Unreal Engine向けFBX出力の話
Houdini Apprentice Advent Calendar 2022、16日目の記事です。
Houdiniでゲーム向けのデータを作る場合、HDAを作成してゲームエンジンで直接編集してデータ制作を完了する方法のほかに、一般的なDCCツールと同じようにFBXで書き出してゲームエンジンにインポートする方法があります。
今回は後者のゲーム向けモデル(スタティックメッシュ)をFBXで出力する場合にモデリング以外で気を付けるべきポイントを解説します。
スケールと向き
Houdiniは1ユニットを1メートルとみなすことが一般的ですが Unreal EngineはFBXの1ユニットを1センチメートルと解釈します。出力前にTransform SOPで100倍にスケールを変更しておきましょう。
向きについてはUnreal EngineはZ-upの左手座標系で、モデルはY-Frountでインポートすることが推奨されており、Houdiniとは全く異なっていますが、FBXで書き出すとデフォルト設定で自動的に変換されます。
頂点カラー
頂点カラーを活用していないプロジェクトも多いのですが、頂点カラーはUV以外にメッシュに持つことのできる貴重な情報です。頂点カラーをうまく使うことでマテリアル数(≒ドローコール)も抑えることができ、表現力がアップするのでぜひ使っていきましょう。
Houdiniでは頂点カラーは@Cdであらわすことができます。
PointにもVertexにも持つことができますが、Vertexに入れたほうができることが増えるため、基本的にはVertexに入れましょう。
また、Unreal Engineでは頂点カラーはRGBAで持つことができますが、AのコンポーネントはHoudiniでは@Alphaに該当します。こちらも使う場合は、Vertexにデータを持ちましょう。
PointとVertexで@Cdと@Alphaが分かれて設定されている場合は、うまくインポートできません。
マテリアル
FBX用のマテリアルは様々な方法で設定できますが、単純なプロップであればGeometoryネットワークの中にMaterial Networkを作り、Material SOPで参照する方法がネットワークの移動が少なくて使いやすいと思います。
コリジョン
Houdiniでモデリングすることで、コリジョンも様々なアプローチで並行して作ることができ、メッシュの変更に合わせてコリジョンも自動的に変更することができます。
その中でもいくつかの代表的なアプローチをご紹介します。
Bound
Oriented Bounding Box にチェックを入れることで、最適な軸に回転してバウンディングボックスを生成するので、より形状に沿ったボックスを生成できます。
Shrinkwrap
メッシュを包み込んだ形状(Convex Collision)を生成するノードです。比較的小さなモデルであれば精密なコリジョンは必要ないのでこれで済みます。
convex hull という名前でも検索できますが、本来のノード名のShrinkWrapよりゲーム開発者には見慣れた単語なので便利ですね。
Convex Decomposition
複数のConvex Collisionを一度に生成してくれるノードです。プロシージャルな処理に組み込むのは難しいですが、決め打ちであれば気の利いたコリジョンを一発で作れるので大変便利。
VDB to Spheres
VDBボリュームを複数のSphereに変換します。コリジョン作成で役に立つケースは少ないですが、覚えておくと意外な場面で役に立つかもしれません。
コリジョンの出力
コリジョン付きのFBXを書き出すのは少々面倒です。通常はOBJレベルの階層にモデルを分けて出力する必要があります。
プロップはSOPレベルで管理したいので、これは非常にめんどくさい仕様です。このような場合、大翔士さんのHDAを使うと非常に便利です。個人的にゲームエンジン向けのFBXを作る人には必須のHDAだと思います。
使い方は非常にシンプルで、Name SOPを使用して、Primitiveに以下のNameアトリビュートを設定します。
UCX_[RenderMeshName]
コリジョンだけでなくLODも同時に書き出す場合は、LOD0番のUCXのような名前に設定する必要があります。
UCX_[RenderMeshName]_LOD0
複数のConvexで構成されたコリジョンを作るには以下のようなネットワークを作ります。
string n = itoa(detail(1,"iteration",0));
@name = concat("UCX_rubbertoy_LOD0_",n);
LOD
LODも通常はOBJレベルの階層でモデルを分けて出力する必要があります。コリジョンと同様、上記のHDAを使うと便利です。
Name SOPを使用して、Primitiveに以下のNameアトリビュートを設定します。
LODGroup/[RenderMeshName]_LOD#(LOD番号)
それ以外のデータ
HoudiniはPointやvertexに自由にアトリビュートを持つことができます。
UVなどのアトリビュートはゲームエンジンにも反映されるので当然追加した場合データサイズが増えますが、それ以外のデータはどうなっているのでしょうか?
不要なグループを整理したデータと整理しなかったデータをそれぞれインポートして比較してみました。
SizeMapでMemory Sizeを比較してみると全く同じデータサイズであることがわかります。Houdiniにしか関係ないアトリビュートは、実際のゲームのデータを増やすわけではないことがわかります。アトリビュートの整理にはそこまで気を使わなくても大丈夫でしょう。
インポート設定
これまで設定してきたデータをインポートするために重要なUnreal Engine 側の設定は以下の項目です。
Vertex Color Import Option : Replace
頂点カラーのインポート設定です。ReplaceにすることでFBXの持つ頂点カラー(とアルファ)を使用します。
Import Mesh LODs : ON
FBXの持つLODを読み込みます。
Normal Import Option : Import Normal and Tanget
FBXの持つ頂点法線およびタンジェントをインポートします。
頂点モデリングが終わってもゲームアセットの完成ではないのが、ゲーム向けモデリングの大変なところですね。ここにもプロシージャルが活きることがあるのでぜひ、Houdiniを活用してみてください。