On this page |
ジオメトリを単一プリミティブにパック化
このSOPは、入力ジオメトリを受け取り、それを組み込みパックプリミティブにパック化します。
組み込みパックプリミティブは、入力ジオメトリのコピーをプリミティブのデータの一部として記録します。組み込みプリミティブのコピーは、組み込まれたジオメトリを共有し、できるだけメモリを節約します。
このSOPには、ディスクに保存せずにジオメトリをインスタンス化する方法があります。
パックプリミティブ概要
Packed Primitives(パックプリミティブ)は、 レンダリング時 にジオメトリを生成するプロシージャです。 この目的は、複製を減らして必要な時にだけ情報を読み込むことで、Houdiniでのインタラクティブ操作時のメモリ使用量を減らすことです。
パックプリミティブの内部には、ジオメトリに関する情報が埋め込まれています。 この情報とは、メモリ内に格納されている実際のジオメトリ、他のジオメトリの一部の参照、ディスク上に保存されたジオメトリのファイルパスのことです。
Mantra, Houdiniビューポート, ソルバなどは、そのパックされた情報を解析する方法を知っており、効率的にジオメトリをレンダリング/表示/処理することができます。
パックプリミティブは編集不可です。つまり、軽量な参照です。パックジオメトリを編集したいのであれば、Unpackノードを使用して、 編集したいジオメトリの一部を抽出して、それを修正し、必要に応じてPackノードを使用してジオメトリを再度パックする必要があります。
パックプリミティブは、重いジオメトリや膨大な数のコピー/インスタンスのレンダリングやシミュレーションで役に立ちます。 ジオメトリが変わらない(例えば、変形しないRBDオブジェクト)限りは、ジオメトリのパック化の恩恵を受けることができます。
パックプリミティブのタイプ
メモリ内のパックプリミティブ
Packジオメトリノードを使用してジオメトリをパックプリミティブに変換することで、 メモリ内 のパックプリミティブが得られます。 これは、メモリ内に、あなたの現在のバージョンのジオメトリの埋め込み参照を持ったPacked Geometry Primitiveを作成します。 "埋め込まれた"ジオメトリは、1個のトランスフォームを持った1個の編集不可な"プリミティブ"になります。
-
"埋め込まれたジオメトリ"は、単にメモリ内の内容の参照です。パックプリミティブをコピーすると、ジオメトリ自身がコピーされるのではなく、 参照 がコピーされます。そのため、参照されたジオメトリがパックプリミティブのすべてのコピー間で共有されます。これは、パックされていないHoudiniジオメトリをコピーするよりも非常にメモリ効率が良いです。パックされていないHoudiniジオメトリでは、すべてのポイント、プリミティブ、アトリビュートなど独立して複製されます。
-
パックプリミティブのコピーはメモリをあまり使用せず、トランスフォームが簡単で、より効率的にビューポートでの描画やMantraによるレンダリングをすることができます。
-
参照されたジオメトリは通常のネットワーク内で存在するので、簡単にシーンに順応したプロシージャルなジオメトリを生成することができ、スタンプを使うことでバリエーションのあるパックジオメトリを生成することができ、結果をリアルタイムで確認しながらインタラクティブにジオメトリを編集をすることができます。基本的には、メモリ内のパックプリミティブを扱うほどインタラクティブ性が高くなり、従来のインスタンスワークフローよりもユーザーが使いやすくなります。
-
ジオメトリネットワークのメモリ内のパックプリミティブそれぞれのコピーを"アンパック"することで、参照されているジオメトリの実際のコピーを作成することができます。これにより、従来のHoudiniジオメトリとパックプリミティブのハイブリッドなプロシージャルワークフローを生成することができます。
-
ここでいう"パック"とは"圧縮"や"軽量化"を意味していません。RAM内で元のジオメトリを保持し、さらに各参照に対して少ないメモリを使用しています。単一のパックプリミティブは、元のジオメトリを使用するよりも必ずしも効率的であるとは限りません。このメリットは、参照されているジオメトリを共有して膨大な数のコピーを効率的に表現できることです。
これは、パックプリミティブをコピースタンプ時に重要です。パックジオメトリのインスタンスがすべて固有であれば、メモリやパフォーマンスのメリットはありません。実際に、これは"実際の"ジオメトリよりもメモリを消費します。その理由は、各パックプリミティブにオーバーヘッドがあるからです。
(スタンプのバリエーションの数に限りがある時は、スタンプジオメトリをパック化する負荷を多少は相殺することができます。Copy SOPの Cache Stamping パラメータを参照してください。)
Packed Diskプリミティブ
Packed Disk プリミティブは、ディスク上のファイルに参照を埋め込みます。
表示またはレンダリング時に、Mantra/Houdiniは、常にメモリ内にデータを保持するのではなく、ディスクからデータを読み込みます。
.bgeo
やAlembicなどのファイル形式は、高速なランダムアクセスでデータの内容にアクセスすることによって、そのデータを非常に効率的にします。
File SOPの Load パラメータを"Packed Disk Primitive"にすることで、ディスクのジオメトリをパックプリミティブとして読み込むことができます。
Packed Diskプリミティブは、メモリ内のパックプリミティブと同様です: “埋め込まれた”ジオメトリは、単一のトランスフォームを持った単一の編集不可なプリミティブとして表示されます。
-
メモリ内のパックプリミティブとほぼ同様に、Packed Diskプリミティブは、ビューポートやMantraでジオメトリのコピーを効率的に作成するのに非常に良い選択肢です。Packed Diskプリミティブのコピーは、単に参照をディスクファイルにコピーするだけです。
-
Packed Diskプリミティブは、単にファイルから既に生成されたデータを読み込むだけなので、メモリ内のパックプリミティブほど動的ではありません。Packed Diskプリミティブを編集する唯一の方法は、それを"アンパック"して、そのファイルデータをメモリにコピーすることです。
-
ビューポートはインスタンス毎にジオメトリをコピーせず、単に異なったトランスフォームで複数回同じデータを描画しているだけです。ビューポートは参照されたジオメトリを、ポイントクラウドや境界ボックスのようにより単純化した表現で描画することもできます。
-
Houdiniと同様に、Mantraはデータをコピーせずに、必要な時にディスクファイルからデータを"ストリーム"することができるので、Mantraのメモリ使用量を減らすことができます。
-
Houdiniは、メモリ内のジオメトリに関しては、全体のジオメトリをIFD(Mantraに送信されるシーン記述ファイル)に書き出さなければならないのに対し、Packed Diskプリミティブに関しては、単に参照をディスク上のファイルに書き出すだけです。Packed Diskプリミティブは、IFDの生成を高速にし、非常に大きくて複雑なシーンに対してそのIFDのディスクサイズを小さくすることができます。
-
Packed Diskプリミティブは、シーンの組み立て、特に静的な背景オブジェクトに適しています。レンダリング時の少ないメモリ使用量は、シミュレーション出力などの大きなディスク容量を持つオブジェクトにも非常に役に立ちます。
Packed Disk Sequenceプリミティブ
Packed Disk Sequenceプリミティブは、Packed Diskプリミティブ(上記参照)と同様ですが、ジオメトリファイル名のシーケンスとそのファイルシーケンスのインデックスを参照します。 Mantraは、Packed Disk Sequenceプリミティブをシーンの一部として読み込んだ時に(現行フレームのジオメトリだけでなく)そのフルシーケンスを知ることになるので、モーションブラーでフレーム間を補間することができます。 つまり、Packed Disk Sequenceプリミティブは、モーションブラーを使ったレンダリングにおいて効率的にアニメーションジオメトリを(フレーム毎のジオメトリファイルの形式で)インスタンス化することができます。
アニメーションシーケンスをPacked Disk Sequenceとしてインポートするには、File SOPを使用します。 その Load パラメータを"Packed Disk Sequence"に設定します。 Geometry File パラメータの隣にあるファイル選択アイコンをクリックして、読み込むジオメトリシーケンスを選択します。
Note
技術的には、Packed Disk Sequenceを読み込む時に Geometry File の$F
パターンが Frame Range パラメータ値の間を補間します(このパラメータは通常では現行フレームを参照しません)。
他のモードと整合性を保つために$F
をここで使用しているので、ファイル選択が期待通りに動作します。
Loadモードの Sequence Index パラメータは、使用するアニメーションシーケンスの(浮動小数点)フレームを設定します。
デフォルトは$FF - 1
です。Packed Disk Edit SOPを使用することで、既存のPacked Disk Sequenceプリミティブのインデックスを編集することができます。
Packed Diskプリミティブは、レンダリングするフレームがアニメーションのフレーム範囲外の時に自動的に循環します。
パックディスクシーケンス上の"wrap"文字列Primitiveアトリビュートを"clamp"
、"cycle"
、"mirror"
、"strict"
のどれかに設定することで、これを変更することができます。
-
"cycle"
は、サンプルインデックスを有効な範囲に自動的にラップします(デフォルトの挙動)。 -
"clamp"
は、範囲外のインデックスサンプルを有効な範囲にクランプします(そのため、例えば、有効なフレーム範囲が1-5であれば、5より大きいフレーム番号はフレーム5に固定されます)。 -
"mirror"
は、ジグザグまたはピンポン形式で逆にしてラップします。 -
"strict"
は、空っぽのジオメトリを有効なフレーム範囲外にします。
パックフラグメント
name
アトリビュートを含んだジオメトリをパックする時、それと同じname
値を共有する各ジオメトリが パックフラグメント プリミティブになります。このプリミティブは元のジオメトリの参照を含みます。
そのため、各フラグメントが同じジオメトリを共有しますが、そのサブセットを参照します。
-
パックフラグメントプリミティブは、完全なモデルのほとんどの部分を表現するのに適しています。特に、各フラグメントが例えばリジッドボディシミュレーションで何か固有のトランスフォームを受け取る部分です。
-
フラグメントを"アンパック"すると、元のモデルのその部分のみがメモリにコピーされます。
-
各フラグメントは単に元のジオメトリの参照にすぎないので、膨大な数のフラグメントがある時に非常に効率的です。とはいえ、ほとんどのフラグメントが削除されていると、実際のジオメトリを使用するよりも効率が悪くなることがあります。少しの破片しか残っていなくても、Houdiniはまだメモリ内に全体の元のモデルを保持し続けます。それに対し、実際のジオメトリを使用した場合、最初はメモリ使用量が多いですが、パーツを削除するとメモリ使用量が減ります。
少しの破片しか残っていない箇所で残りのフラグメントを"アンパック"することで、両方の良いメリットを得ることができます。
How to
To... | Do this |
---|---|
SOPジオメトリをパックプリミティブに変換する |
Pack SOPを使います。
Packノードは、すべての入力ジオメトリから新しいプリミティブを作成することができます。または、アトリビュート(例えば、Shatterで作成される |
パックプリミティブ内から"サブプリミティブ"を抽出する |
Unpack SOPを使います。 |
ダイナミクスネットワークからジオメトリをパックプリミティブとしてインポートする |
DOP Import SOPには、ダイナミクスネットワークから |
VEXシェーダでパックジオメトリ上のアトリビュートにアクセスする |
renderstateVEX関数を使用することで、パックジオメトリ上のアトリビュートの値を取得することができます。例えば、パックジオメトリに |
Note
ジオメトリには、material
アトリビュート(Houdiniが特別な場合として扱います)以外のPrimitiveアトリビュートを設定/使用することができません。
プリミティブレベルのアトリビュートは、通常では動作しません。その理由は、パックジオメトリは、Houdiniからは単一ポイントを持つ単一プリミティブのように見えるからです。
レンダリング
パックプリミティブはMantraのレンダリングで非常に役に立ちます。パックプリミティブはIFDを生成して高速にレンダリングすることができ、メモリ使用量とディスク容量が少なく済みます。 とはいえ、そのメリットを完全に得るには、Mantraのパックプリミティブとの動作方法を理解するべきです。
マテリアルの割り当て
標準のジオメトリの場合は、2つのレベルでマテリアルを割り当てることができます:
-
オブジェクトレベルでは、Geometryノードのパラメータで割り当てます。
-
ジオメトリ(SOP)レベルでは、Materialノードを使用して、特定のプリミティブ上に
material
アトリビュートを設定します。これは、そのアトリビュートを持ったプリミティブに対してオブジェクトマテリアルを上書きします。
Houdiniはレンダリング用のシーン記述ファイル(IFD)を生成する時、マテリアルを割り当てるためにオブジェクトとジオメトリのアトリビュートをチェックするので、どちらのシェーダをIFDに含めるべきか知っています。
パックプリミティブを使用する時は、Houdiniは3つ目のレベルのマテリアルの割り当てができます:
-
パックプリミティブ内に埋め込まれたジオメトリ上のマテリアルアトリビュート。このアトリビュートは、"もっと高い"レベル(Primitiveアトリビュートとオブジェクトマテリアル)を上書きします。
しかし、Houdiniは、IFDを生成する時に、その埋め込まれたジオメトリ(走査するのに遅い非常に巨大なファイルであることがあります)の中を見ません。そのため、その埋め込まれたジオメトリが何のマテリアルアトリビュートを持っているのか知ることができないので、IFD内にそのシェーダが含まれているかどうか知りません。Mantraがレンダリング時にそのプリミティブをアンパックする時にだけ、そのプリミティブにMantraで必要なシェーダが含まれていないことに気づきます。
この問題を回避するには、IFDにシーン内のシェーダが すべて 含まれていることを、それらのシェーダがオブジェクトやジオメトリのレベルで割り当てられているかに関わらず、Houdiniに伝えることができます。 Mantraレンダーノードの Save All SHOPs を有効にしてください。(これは、少しだけIFDのディスクファイルが大きくなります)。 パックプリミティブで必要なシェーダをシーンに読み込んでいる限りは、それらのシェーダはレンダリング時に利用可能です。
Tip
パックジオメトリ"内部"にシェーダを割り当てて、シェーディングパラメータを上書きする方法は、Material Style Sheetsのヘルプを参照してください。
ディスプレイスメントとサブディビジョンサーフェス
Houdiniは、標準ジオメトリと同じようにパックジオメトリに対してディスプレイスメントシェーディングとサブディビジョンサーフェスのレンダリングを行ないます。 しかし、主にインスタンスに対してパックジオメトリを使用し、ディスプレイスメントシェーダを適用したり、サブディビジョンレンダリングを使用するのであれば、 Dicing(細分化) について考える必要があります。
-
ディスプレイスメントやサブディビジョンサーフェスをレンダリングする前に、Mantraはジオメトリを、(シェーディング品質が
1
に設定した時)1ピクセル1プリミティブになるまで小さなプリミティブに"Dicing(細分化)"します。つまり、カメラに近いオブジェクトほど遠くにある(ピクセルの大きさ未満の)オブジェクトよりも細分化されます。 -
パックジオメトリを使ってインスタンス化する時、これは問題を起こす可能性があります。インスタンス化のメリットは、ジオメトリをすべてのインスタンスで共有できることです。しかし、ディスプレイスメントやサブディビジョンのレンダリングを追加すると、Mantraは各オブジェクトをそれぞれ読み込んでDicingしなければなりません。つまり、ジオメトリはもはや共有されなくなります。
-
この問題を回避するには、インスタンスを含んだオブジェクトにShare Displacements Between Instancesレンダープロパティを追加することができます。このパラメータを有効にして、Mantraに以下のことを伝えます:
-
あるインスタンスに対してシーンに必要な最高レベルのDicingを使用し、そして
-
そのDicingされたジオメトリをすべてのインスタンスで共有する
-
-
これは、遠くにあるオブジェクトも"非常に細かい"ディテールを持つことを意味します。このため、処理が遅くなる可能性がありますが、インスタンスを維持できるメリットは、他のデメリットよりもおそらく勝ります。
最悪の場合では、"正しくない"Dicingレベルが問題を起こせば、カメラからの距離に基づいて、2つのオブジェクト間のインスタンスを分割することができるので、"最高のDicingレベル"が"近いオブジェクト"と"遠いオブジェクト"に対して別々に計算されます。
他の方法では、カメラに近いインスタンスをアンパックして、"必要な最高のDicingレベル"計算からそれらのインスタンスを除去することができます。
アトリビュート
ディスク上またはメモリ内の パックプリミティブインスタンスは、単に同じファイルやメモリのポインタなので、各インスタンスには、個々のアトリビュート値を持たせることができません(ただし、material
とvel
(velocity)のアトリビュートは、特別に動作します。以下参照)。
パックフラグメント インスタンスには、個々のアトリビュート値を持たせることが できます 。なぜなら、それらのインスタンスは 融合された ものだからです。とはいえ、ディスク上の、またはメモリ内のパックプリミティブよりも効率が悪いことを意味します。
Alembicプリミティブ インスタンスには、個々のアトリビュート値を持たせることができません。とはいえ、Mantraでは、Alembicプリミティブを"unshare(共有しない)"するオプションがあります。これは、メモリをたくさん消費しますが、レンダリング時にAlembicプリミティブインスタンスに個々のアトリビュート値を持たせることができます。
Mantraは、パックプリミティブに対して仮想のMantraオブジェクトのツリーを作成し、ツリーのトップから各仮想オブジェクトまで(それらの仮想オブジェクト自体にmaterial
アトリビュートがない場合)material
アトリビュートをコピーしていくので、Geometryオブジェクト上のマテリアルは、パックプリミティブ内部に適切に適用されます。
同様に、vel
(velocity)アトリビュートは、仮想オブジェクトツリーを通じて 追加 されるので、モーションブラーは適切に動作します。
パックプリミティブ上のPrimitiveアトリビュートは、仮想Mantraオブジェクトのオブジェクトプロパティにコピーされます。Render State VOPやrenderstate VEX関数を使用すれば、シェーダコード内でそれらのアトリビュートにアクセスすることができます。
パックプリミティブの 内部に material
Primitiveアトリビュートがあれば、Houdiniは、そのプリミティブの内部を見ないので、Mantraへ送信するファイル内にそのマテリアルを含む必要があることを知りません。
Declare all SHOPs オプションをオンにすることで、(レンダリングファイルが大きくなりますが)これを修復することができます。これによって、Houdiniはレンダリングファイル内に単にすべてのマテリアルを含んでいることを知ります。
Mantraは、パックプリミティブ フラグメント をレンダリングする時、パックプリミティブからアトリビュートをジオメトリにコピーするので、フラグメントに対してVelocityブラーが動作します。他のパックプリミティブタイプは、インスタンスとしてレンダリングされるので、このようには動作しません。
パラメータ
Display As
パックプリミティブをビューポートに表示させる方法。
Path Attribute
新しく作成されるパックプリミティブに割り当てるpath
アトリビュート値。このフィールドを無効または空っぽのままにすると、path
アトリビュートは作成されません。
Pack By Name
SOPのジオメトリを1つ以上のパックフラグメントに分割します。name
アトリビュートのすべて固有の値に対して、そのアトリビュート値を持つプリミティブまたはポイントだけでパックプリミティブが作成されます。
Name Attribute
各フラグメントに属するプリミティブを識別するために使用する文字列または整数のPrimitive/Pointアトリビュートを指定します。 Pointアトリビュートを指定すると、ポイントのみがパックされます。
Create Packed Fragments
パックジオメトリプリミティブではなく、パックフラグメントプリミティブを作成するように指定します。 これは、文字列Primitiveアトリビュートにのみ動作します。
Tip
パックフラグメントプリミティブは、最終レンダリングジオメトリに多くの固有の破片を持っている場合に非常に効率が良いです。 パックジオメトリプリミティブは、最終レンダリングジオメトリに多くの同じ破片のコピーを持っている場合に非常に効率が良いです。
Pivot Location
パックプリミティブが参照するポイントのオフセットを初期化する方法を指定します。
Transfer Attributes
パックジオメトリへ転送するアトリビュートのリストを指定します。
Transfer Groups
パックジオメトリへ転送するグループのリストを指定します。
Examples
The following examples include this node.
LookatTarget Example for POP Lookat dynamics node
このインタラクティブなサンプルでは、POP Lookatノードの使い方を説明しています。 再生ボタンを押して、ビューポートにある緑のターゲットハンドルを動かしてみてください。 円錐のパーティクルが、あなたが動かしたターゲットの方向に向きます。
UnpackWithStyle Example for Unpack geometry node
このサンプルでは、アンパックと同時にスタイルシート情報を評価することができるUnpack SOPの機能について説明しています。 Nested Packed Primitiveでは、スタイル情報を維持しつつも部分的にアンパックできることを説明しています。 このサンプルでは、Python SOPを使って、プリミティブ単位でスタイルシートから情報を抽出する方法も説明しています。
See also |