ComponentBuilderで遊ぼう
Houdini Advent Calendar 2021 は、Houdini19で新しく追加されたComponentBuilderの使い方を調べてみよう、です。
ComponentBuilderとは¶
ComponentBuilderとはなにかというと、
去年のHoudiniアドカレで書いたUSDアセットを作ろうの内容を
もっと簡単にできるようにしたノードです。
つまりは、去年の記事のような複雑なネットワークを作らないでも、
この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とはなんぞ?という人は
https://fereria.github.io/reincarnation_tech/11_Pipeline/01_USD/11_kind_modelhierarchy/
こちらの記事を参照。
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)で出力した場合は、shapeMesh1つにまとまって出力されます。
このあたりは、以前書いたPackedPrimitivesとUSDExportで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で定義した ASSET_geo_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までとは別物)