UE5: PCGで配置したメッシュの下の草(Landscape Grass)を消す際の罠と解決策
PCG(Procedural Content Generation)で床や岩などのスタティックメッシュを自動配置した際、その下からLandscape Grassが突き抜けて生えてしまうのを防ぎたい場面は多いと思います。
RVT(Runtime Virtual Texture)をマスクとして使用する定番の手法を試した際、開発中に高確率で遭遇する「エンジンの仕様による罠」とその解決策をまとめました。
罠:見えている範囲の草しか消えない現象
RVTを使って「メッシュの形に白くマスクを書き込み、Landscapeマテリアル側でその部分の草ウェイトをSubtractする」というロジックを組むと、単体テストでは成功したように見えます。しかし、広大なマップに適用すると以下の現象が発生します。
- カメラを動かして離れた場所に移動すると、メッシュを突き抜けて草が生えたままになっている。
- Landscapeマテリアルを再コンパイル(または更新)した瞬間だけ、現在見えている範囲の草が正しく消滅する。
原因は「Landscape Grassのキャッシュ仕様」
これは設定ミスではなく、Unreal Engineのパフォーマンス最適化による仕様です。
- Landscape Grassは、カメラから見えている範囲(タイル)ごとに計算され、キャッシュ(一時保存)されます。
- PCGがマップのあちこちに動的にメッシュを配置しても、画面外のタイルに対しては「草の再計算」が自動で走らないため、RVTの最新のマスク結果が反映されません。
💡確認用のコンソールコマンド
プレイ中やエディタ上でgrass.FlushCacheコマンドを実行すると、強制的に全タイルの草が再計算され、一時的に画面外の草も綺麗に消えることを確認できます。
解決策となる2つのアプローチ
この問題に対しては、プロジェクトの開発フェーズに合わせて以下のいずれかのアプローチを取る必要があります。
1. RVTをビルド(ベイク)して固定する
最もパフォーマンスが良く、確実な正攻法です。配置が完全に確定した最後の仕上げの段階におすすめです。
-
Virtual Texture Builderアセットを新規作成する。 - レベル上の RVT Volume の
Virtual Texture Setupにセットする。 - 「Build」を実行してマスク結果をテクスチャとして完全に焼き付ける。
- デメリット: PCGの配置パラメータをいじってメッシュを動かすたびに、手動で再ビルドする必要があるため、レベルデザイン中の試行錯誤(イテレーション)には不向きです。
2. 草の配置自体をPCGに移行する(動的な代替案)
開発中で頻繁にメッシュを動かしたい場合は、Landscape Grass Typeの利用を完全にやめ、草の配置もPCGの役割にしてしまうのが強力な解決策です。
- PCG内で草用のポイントデータを生成する(Surface Sampler等)。
- 床や建物のポイントデータを使って、
Differenceノードで草のポイントをくり抜く。 - くり抜いた後のポイントを
Static Mesh Spawnerに渡す。
キャッシュ仕様やマテリアルコンパイラに依存せず、純粋な座標空間の計算で確実に草を消すことができます。レベルデザインの初期〜中盤は非常に取り回しが良いアプローチです。