[UE5] PCGのDynamicMesh機能を用いて、手続き型のジオメトリスクリプトを作成する
当校の生徒さんが、Unreal Engineにおけるマテリアル表示上のテクニックについて、ブログを書いてくれました。ぜひご覧ください。
オリジナル文書は、こちらです。
https://docs.google.com/document/d/1tkKh99w3WkiazeuaFtfdwA9XVjWt-mwlgZoJrXBG9UI/edit?tab=t.0
ーーー
[UE5] PCGのDynamicMesh機能を用いて、手続き型のジオメトリスクリプトを作成する
はじめに
この記事では、UnrealEngine5.7(以後UE5.7と呼称)以降ビルトインとして組み込まれたProcedural Content Generation(以後PCGと呼称)とGeometry Script Interopプラグインの機能を併用し、壁や柱などのジオメトリの破壊表現を、手続き型かつ非破壊で生成する方法を紹介いたします。
完成品のデモ
左がデフォルト、右が破壊表現を適応させた状態
シード値によるランダムな生成
実行環境
windows11
UE5.7(Launcher版)
PCGを使用する理由
建造物のレベルデザインをする際に、法線マップではなく実際にジオメトリを変形させるという表現手法を取る必要があり、バリエーションも大量に欲しいというシチュエーションがあるとします。
ここで主な実装方法として
・エディター内で直接編集する
・外部の3Dツール(主にBlenderなど)にてアセットを自作する
この二つがよく挙げられるので、簡単にメリットとデメリットを比較します。(個人の見解なので、参考程度に)
[外部3Dツール]
メリット
細かいディテーリングなどの作業を効率よく行える
Blenderでは、プラグインを使用した破壊表現も作成可能
規模の小さいレベルデザインや、小物の製作との相性が良い
デメリット
場合によってはエクスポート作業などがボトルネックとなり、実際の動作環境での確認作業で苦労する
[エディター内での直接編集]
メリット
リアルタイムで結果が確認できるため、オープンワールドなどの比較的規模の大きいレベルデザインと相性が良い
非破壊のため、大量のアセットが容量を圧迫する可能性が低い
デメリット
大まかな調整までしか行えないため、思ったような結果が得られない場合がある
UnrealEngineでは、規模の大きいレベルデザインを得意としていることや、初学者でも効率よく作業を進められる環境が整っていることから、PCGをワークフローに導入するメリットが大きいという結論に至りました。
実装手順
1-1 Geometry Script Interopプラグインを導入
Pluginsメニューの検索バーにて”PCG”と検索、下記の画像と同じプラグインを有効にして再起動
1-2 使用するメッシュを用意
必要となるメッシュは最低2種類以上で、”形状を変化させたいメッシュ”と”変化させたい形状をしたメッシュ”を用意する必要があります。
ここではFabにて無料で配布されている、コンクリートの壁と石のアセットを使用します
https://www.fab.com/listings/b785af40-d4f7-415d-ac0d-b60a50d6f301
ここで注意点があり、”形状を変化させたいメッシュ”のポリゴン数が、ジオメトリに対して十分に存在しているかを確認する必要があります。
理由としては、変形する手法にBooleanを用いるため(モデリング作業をする方ならご存じかもしれませんが)ポリゴン数が極端に少ないと、思うような出力結果が得られないのです。
1-3 PCG Graphの作成
コンテンツブラウザを右クリック
PCG ➡ PCG Graph ➡Create empty graph
名称をPCG_GeoDmgとします
作成したグラフを開き、以下のノードを作成していきます
[完成図]
MeshSamplerのStaticMeshスロットに”形状を変化させたいメッシュ”を参照させます。
MeshSamplerのサンプリングメソッドは、メッシュの形状により相性がまちまちなため、出力結果を参考にしながら逐一変更しましょう(今回はOne Point Per Vertexを選択)。
Create PointのCoordinate SpaceをLocal Componentに変更
Globalではレベル内の0,0,0から生成されるため、正確に配置・制御することが難しくなります。
MeshSamplerとCreatePointにExtentsModifireを接続
CopyPointを使用し、MeshSamplerをCreatePointの位置にコピー
これにより、レベル内に配置したPCG Graphの位置に実際に生成することが可能になります。
Normal To Densityで、特定の法線方向だけに形状を変化させることが可能です。
Transform Pointで、”変化させたい形状のメッシュ”を配置する箇所からオフセットを設定します。
特にこだわりが無ければ、RotationのMin~Maxの値は基本的に0~360°に設定するだけでok
RandomChoiceノードで、配置可能な全てのCopyPointsの中からランダムに”変化させたい形状のメッシュ”を配置する箇所を選択します。
FixedNumberの項目から、選択する箇所の個数を指定可能
DifferenceのSourceインプットにRandomChoiceのShosenアウトプットを接続、DifferencesインプットにCreatePointと繋がっている方のExtentsModifireアウトプットを接続
DensityFunctionをBinaryに設定
このノードを使用し、変形させたくない部分の範囲を指定します。
今回は、壁の下部の形状をキープさせたいため、CreatePointのCubeをExtentsModifierで変形、差分として設定しています。
Transform pointで差分の位置は自由に変更可能
2-1 Dynamic Meshの生成
※Boolean Operationノードは負荷が高いため、結果を確認する必要がない場面では左上の”Pause Regen(ショトカはAlt + R)”を有効にしておく事を推奨します。
GetActorDataのModeをGet SinglePointに設定
CopyAttributesのInputとOutputをそれぞれ”$Transform”と”Transform”に設定
SetのInputを”Transform.Scale”に設定
SubtractのIn Aに先ほどまでのノードを、InBにGetActorDataを接続
AppendMeshesFromPointsのModeをDynamic Meshに変更
Create Empty Dynamic MeshをIn Dyn Meshに接続
Scale MethodをExtents、DeterminismのドロップダウンからNative Testsの項目にチェックを入れる
Static Mesh To Dynamic Mesh Element(以後SM2DMと呼称)をAppend Dyn Meshに接続、Static Meshスロットに”変化させたい形状をしたメッシュ”を参照させ、Extract Materialsの項目にチェックが入っていることを確認
Point to attribute setで、DynamicMeshTransformにTransformの値のみを渡す
これにより、PCGグラフの配置方法に関わらず、動的に変形することが可能になります。
Boolean OperationをSubtract、ModeをEach A With Each Bに変更
Spawn Dynamic Meshを接続
出力結果
ダイナミックメッシュとしての変形は成功しているようですが、どうやら変形した部分にも壁のマテリアルが適応されており、変形させたい形状をしているメッシュのUVを参照しているようです。
これを修正していきましょう
2-2 メッシュのUVを修正
壁を複製し、エディターを開く
Materialスロットを追加
Element1に壁のマテリアル、Element0に変化させたい形状のメッシュのマテリアルを適応
コンテンツブラウザにて”PCG_DynamicMeshSimplify”と検索
コピーし、現在編集しているPCG Graphと同じ場所に貼り付けし、名称を”PCG_MaterialUVFix”に変更
PCG_MaterialUVFixを開き、Process Dynamic Mesh関数を編集
接続されているノードを全て消し、画像のように組んだ後にコンパイル
これにより、変形した部分のマテリアルが正しく入れ替えられ、UVの問題も解決します
Dynamic Mesh Transformと接続されている方のSM2DMに、先ほどのマテリアルスロットを追加したメッシュを参照させる
ExecuteBlueprintを接続、Blueprint Element Typeに先ほど作成したBluePrintを適応
出力結果
これにて、基本的な動作は全て完成となります。
ここでBooleanの出力がうまくいかない場合は、変形させたいメッシュをModeling Mode ➡ Mesh ➡ Remesh でポリゴンを増やし、XFrom ➡ Bake Transformで編集を適応させると、結果が良くなる場合があります。
テクスチャの割り当てが逆になっていた際は、マテリアルスロットの順番を逆にしましょう。
まとめ
変形させたメッシュをStaticMeshにして保存したい場合は、Actorタブ > MargeActorからMargeすることで保存可能です。
PCGやGeometry Script Interopプラグインの情報などが、現状(日本語では特に)あまり出回っていない状況ですので、本記事が少しでも参考になれば幸いです。