メインコンテンツまでスキップ

ComponentBuilderで遊ぼう

Houdini Advent Calendar 2021 は、Houdini19 で新しく追加された ComponentBuilder の使い方を調べてみよう、です。

ComponentBuilder とは

ComponentBuilder とはなにかというと、

の内容を もっと簡単にできるようにしたノードです。 つまりは、去年の記事のような複雑なネットワークを作らないでも、 この ComponentBuilder を使用すれば汎用アセットをセットアップできるようになります。

まさかの翌年で前年に書いた内容が公式のノードとして用意してるとは Houdini 恐ろしい子...

まずはざっくり

まずは、SOLARIS の Stage で Component Builder を選びます。

すると、このようなノードができます。 この ComponentOutput の結果できあがるシーングラフは、

このようになります。

多少違いますが、 ComponentBuilder を使わなかったときの結果と同じような構成になっていて Payload の構造、Geometry と Material の別レイヤー化などした状態で USD アセットのセットアップを行ってくれます。

試しに USD ファイルに Export します。 今までだと USDROP ノードで Export していましたが、ComponentBuilder の場合は ComponentOutput ノードが Export を担当します。

Load from Disk のチェックを入れると TOPs っぽいものがノードの左側に表示されます。 そしたら、Save to Disk します。

デフォルトだと Hip と同じフォルダ以下に出力されるようになっているので、 出力先に指定されたフォルダを覗いてみると、 出力されていました。

出力した usdc を usdview で開いてみると

AssetInfo、Kind といったメタデータ、 Payloads、Material の Variant、Material・Geometry の分離等含めてすべてされた状態の USD アセットを出力することができました。

すごい。

Kind とはなんぞ?という人は

こちらの記事を参照。 AssetInfo は近いうちに USD アドカレに書きます。

ComponentBuilder の構成

ComponentBuilder は、

  • Component Geometry
  • Component GeometryVariants
  • Component Material
  • Component Output

この4つのノードで構成されていますので、それぞれの役割を確認しながら詳しく使っていこうと思います。

Component Geometry

ComponentGeometry は、その名の通り USD アセットのうち、Geometry 部分のレイヤーを作成するためのノードです。 そして、その Geometry に対して VariantSet(ヴァリエーション、モデルのパターン)を作成するために使用するのが Component Geometry Variants です。

ComponentGeometry を使用することで、USD の GeometryPrim 以下の構造を作ってくれます。

Geometry は、ComponentGeometry ノードをダブルクリックすると、中に Output ノードが3つ用意されています。

この ComponentGeometry ノード内は SOPNetwork になっていて、SOP でプロシージャルに作成したモデルを そのまま出力することができます。 使い方は、 output#0 ~ #2 に指定の Purpose(目的)のノードを接続します。

Purpose(目的)とは その Geometry に対して、レンダリング時にどのような目的を持たせるかを指定するための Attribute デフォルトでは default(役割を持たない) proxy(OpenGL 用の軽量 Geometry) guide(ガイド表示用) が指定できて、それぞれの枠割でどのモデルを表示するかを指定できます。 詳しくはまた別の記事で。

試しに、default に pig proxy に box を接続します。

このようになります。

Stage に戻りビューポートを見ると、Proxy モデルが表示されています。 これは ComponentGeometry ノードで proxy (OpenGL 用の軽量 Geometry)の Purpose が指定されている Geometry が表示されているからです。

これを Karma に変更します。

変更すると、Pig に変わりました。 Karma の場合(OpenGL ではない場合)は defaultGeometry 表示になります。

現在のシーングラフはこの通り。 geo 以下に proxy/render の3つの Scope ができていて、それが ASSET の Xform でまとめられているのがわかります。

ComponentGeometry ノード(SOP)で出力した場合は、shapeMesh 1つにまとまって出力されます。 このあたりは、以前書いた で Mesh を切り分けたり出力先の SdfPath を制御できますので 気になる方はぜひこちらの記事もよろしくお願いします。

Face への MaterialAssign

ComponentGeometry で Mesh を出力した場合、Pack 等しない場合は1つの Mesh になりますが その場合どうやって複数のマテリアルをアサインすればいいのか?というと、 SOP 側で Primitives に Group を指定します。

SOP で指定した Group の名前を、 Subnet Groups に、スペースを空けてグループ名を追加します。

Subset Groups を作ると、UsdGeomSubset が作成されます。

UsdGeomSubset は、その名の通り UsdGeom のサブセットで メッシュのインデックスを保持します。

とあるとおり、SOP で指定した Primitives の Group の Index を UsdGeomSubset に出力してくれます。 この UsdGeomSubset に対してマテリアルをアサインすることで、複数マテリアルのアサインができます。

UsdSubset については、UsdPreviewSurface を使うに説明がありますのでそちらを参照ください。

ComponentMaterial

次は ComponentMaterial。 その名の通りマテリアルをアサインするためのノードです。

使い方は簡単で、Input0 に ComponentGeometry をつなぎ、Input1 に MaterialLibrary をつなぎ ComponentMaterial で指定の Mesh に対して MaterialLibrary で作成したマテリアルをアサインします。

MaterialAssign の方法

ComponentMaterial は、マテリアルをアサインする Primitive と、アサインしたい Material の Path を 指定することでアサインが可能です。

ComponentGeometry で SubsetGeom を指定していた場合、ComponentMaterial で SubsetGeom を Primitives で指定、アサインしたい Material の Path を指定することで

Face 単位でのアサインができました。

Assign の結果、出来上がったシーングラフはこのようになります。 shape とその Subset、そしてマテリアルという構造になります。

MaterialLibrary

Material Library の設定で、指定の VOP からマテリアルを LOP にインポートすることもできますが それ以外に MaterialLibrary ノードをダブルクリックすれば そこが VOP になっているので

そこでマテリアルを作れば、特に指定をしないでも Material Path Prefix 以下に Material を出力してくれますので、 お好みで使い分けるとよさそうです。

ComponentMaterial を使用した場合の特徴

この ComponentMaterial を使用しないでも

MaterialLinker を使用して

このようにすれば、視覚的にも楽にマテリアルアサインが可能ですが、 ComponentMaterial を使用した場合、大きく以下2つが変わります。

Material の別レイヤー化

のちに説明する ComponentOutput で、マテリアルを別レイヤーとして Export します。

この時のレイヤーとコンポジションの構造はこんな感じになります。

MaterialAssign は mtl.usdc 側 リファレンスの順序的でマテリアルレイヤーのほうが強い

MaterialAssign ON/OFF の VariantSet の追加

マテリアルのアサインを VariantSet を使用して ON/OFF する構造を自動で追加してくれます。

自分用メモ ComponentMaterial のノードをダブルクリックすると、その中は LOP Input で Stage を受け取り、その中でノードベースでも MaterialAssign ができる。 ここで指定した値は over で mtl.usdc に入る

※ただし、この方法でマテリアルを作ると、ComponentGeometryVariants で  マテリアルが消失するらしい?

ComponentGeometryVariants

次に ComponentGeometryVariants。 これは、その名の通り Geometry の VariantSet を作成するためのノードです。 ComponentGeometry を Input に接続すると、いい感じに Component の Variant を作成してくれます。

ComponentMaterial を追加した後に、ComponentGeometryVariant ノードを作成し2つを接続します。 この例だと、Cube と Torus の2つの Mesh が作られて、

ASSET ノードに対して geo Variants が追加されます。 ここには、ComponentGeometry で指定した名前(デフォルトは ComponentGeometry のノード名)でバリアントが作られます。

これで、MaterialAssign と合わせて ASSET Prim には、geo と mtl(アサインオンオフ)の VariantSet がある状態になります。

自分用メモ ComponentGeometryVariant のノードの段階だと、マテリアルの Variant がちょっとおかしい気がする mtl.usdc 的には ASSET に VariantSet が入っているけど、このノードタイミングだと Variant はあっても Variant にならない。 (ComponentOutput が入ると正しいので、そういうものなのかもしれない)

Component Output

最後は ComponentOutput です。 これはその名の通り、ここまで作った USDAsset を指定のレイヤー構成で Export してくれます。 Export する以外に、USD アセット用のメタデータの追加、継承の追加、RootPrim の指定などの構造を 指定します。

Export する

まずは Output。 Caching の Load From Disk を ON にして、SaveToDisk を押します。 押すと、デフォルトの場合は Hip と同じフォルダ以下の usd/assets/以下にモデルを出力します。

出力すると、

このようなレイヤーが出力されます。 このレイヤーの関係性は以下のようになります。

備考 geo / mtl 内の variant は over で定義した ASSETgeo_variant#/ASSET を AssetName Prim に Reference この over それぞれに Variant が指定されていて、Reference でそれが合成されている

LayoutAssetGallery に登録する

Caching の Add to AssetGallery ボタンを押すと、

簡単に登録できました。

作成したアセットは、Layout ノードを使用すると、簡単にレイアウトすることができます。

サムネイルを作る

Thumbnail の Generator Thumbnail ボタンを押すと、Asset フォルダ以下に Thumbnail.png が作成されます。

Variant ごとの別レイヤー作成

Component Output の VariantLayers を ON にすると、バリアントを別アセットとして登録することができます。 (別レイヤーですが、本体の AssetName.usdc をリファレンスして、SetVariant している)

AssetInfo や Kind

Component Output では、USD の各種メタデータも指定が可能です。 Kind については最初にも書いた通り で、どう使うのかを書いたのですが、AssetInfo についてはそこまでふれてないはず 個別に USD アドカレにて記事を投稿予定です。 (去年のあどかれのこのあたりで言及してた)

以上でモデルとマテリアルを作り、アサインして、出力するまでの構造ができました。

Layer 名の指定

Component Output を使用すると、ExportOptions で各レイヤーの名前を変更して出力することができます。 デフォルトだと AssetName.usd payload.usdc geo.usdc mtl.usdc extra.usdc となっています。 ですが、 usd は、中身がアスキーでもバイナリでも大丈夫で、リファレンスが絡んできた場合であってもアスキー・バイナリを簡単にスイッチできるように しておいたほいがよいため、 usdc ではなく usd としておいたほが個人的には良いと思います。 (この辺りはアドカレ2日目の記事で技師長師匠が言及しています)

さらに、複雑なコンポジションになってきたときに、どのアセットのどのレイヤーを明示しておいたほうが良いとおもうので、 各レイヤーの頭にアセット名を入れておきます。 (Kitchen_set なども、このようにアセット名が入っていますのでそれ準拠)

最終的にはこのようなレイヤーになりました。

サンプル

https://1drv.ms/u/s!AlUBmJYsMwMhhOcoB7mqcctbgbO2GA?e=J2djhB

ComponentBuilder がなかった Houdini18.5 で作ったアセットセットアップサンプルと比較すると、

これが、

こうなって、以前の USD をがっつり理解していないとかなり難解なネットワークだったのが、 かなり直感的でシンプルなネットワークになっているのがわかると思います。 (以前のサンプルは VariantSet を入れていなくてもこれだけ複雑)

https://1drv.ms/u/s!AlUBmJYsMwMhhPUHvj3CO9k1O7qsTw?e=mzekNF

一応今回のシンプルな Primitive で作ったサンプルファイルをアップロードしておきましたので 構築の参考になれば。

まとめ

アドカレ公開日までで調べられるところまでやろうとおもったら、 想像以上に機能が多彩で随分と長い記事になってしまいました(多機能すぎる)

ComponentBuilder は、USD アセットを作るのに必用な機能が非常に扱いやすい形でまとめられていると思いました。 今回触り切れなかった機能もまだまだありますので、 余力があればもう少し深堀した記事も書きたいなと思います。

また、Houdini19 からは Layout 関連がかなり進化していて Layout と ComponentBuilder を使うことで、以前までとは比較にならないぐらいサクサクレイアウトできるようになりました。 以前までは「ちょっとこれは、すごいけど USD の構造知らないとちょっと手がだせないかな...」という印象があった SOLARIS ですが 今回は、そういう印象がなくなり非常に直感的になっています。 これを機会に、ぜひとも USD を使用したアセット作成やレイアウトを試してもらいたいなと思います。 (18.5 までとは別物)