UE4 ランタイムバーチャルテクスチャーとランドスケープによるメッシュ境界のブレンド
UE4.23から使えるようになったバーチャルテクスチャー(Virtual Texture)という、非常に大きなテクスチャーでもメモリー消費量を抑えて、更にパフォーマンス効率も上げて使用できる機能があります。
バーチャルテクスチャーには2種類あり、ランタイムバーチャルテクスチャー(Runtime Virtual Texture)と、ストリーミングバーチャルテクスチャー(Streaming Virtual Texture)と呼びます。両者の違いは名前の通り、ランタイム(実行中)で使うか、ストリーミング(逐次)で使うかの違いです。
RVTは主にランドスケープで複雑なマテリアルのブレンドに最適です。SVTはUDIMと呼ばれる複数のUVを持たせたいオブジェクトなど、更に巨大なテクスチャーを効率よく扱う時に最適です。
今回はランタイムバーチャルテクスチャー、通称RVTを使ってランドスケープによるメッシュ境界のブレンドというものをやってみます。メッシュ境界のブレンドというのは背景物が地面などに刺さったりしてしまい、違和感のあるような状態を少しでも緩和させる際に最適な手法です。UE4には他にも背景物を地面を馴染ませる方法がいくつかありますが、RVTはより効率よくブレンドが可能な仕組みとなっているのでお勧めです。
必要な設定
まずはRVTとメッシュディスタンスフィールド(Mesh Distance Field)を先にオンにしておく必要があります。MDFは事前に計算を行い、メッシュ境界を判断するために利用します。これは事前に設定が必要ですが、マテリアル内で非常に有用な情報を取得できるようになります。
プロジェクト設定のRenderingから"Enable virtual texture support"と"Generate Mesh Distance Fields"を有効化して、エディターを再起動しましょう。この後一度全てのマテリアルのシェーダーコンパイルが走りますので、終わるまでゆっくりと待ちます。
終わったら次はRVTとランドスケープマテリアルの作成です。
RVTとランドスケープマテリアル作成
まずは新規レベルを作成し、ほぼ空の状態にしておきます。そしてランドスケープマテリアルとRVTをコンテンツブラウザから作成します。
ランドスケープマテリアルを開き、画像のようにマテリアルを作成します。
"Layer Blend"ノードで自由にランドスケープのレイヤーを作成しておきます。ここではGround、Grass、Snowの3つを作成。Texture Sampleで利用するテクスチャーは標準スターターコンテンツの"T_Ground_Gravel_D"、"T_Ground_Gravel_N"、"T_Ground_Moss_D"、"T_Ground_Moss_N"の4枚を利用しています。
Snowレイヤーのノーマル用Layer Blendには"T_Ground_Moss_N"を複製し、"TextureCoordinate"ノードのUとVのTilingをそれぞれ0.5にすることで、少し雪の粗さがでやすいようにしています。
次にマテリアルの詳細から、"Use Material Attributes"というチェックをオンにして、マテリアルアトリビュートを使えるようにしておきます。マテリアルアトリビュート化することで、マテリアルをレイヤー化して利用することができるようになります。
そして最終的に以下のようなマテリアルのノード構成となりました。
ラフネスやスペキュラーなどの設定は大雑把なものなので、必要に応じて調整が必要です。ここで重要なのが、"Runtime Virtual Texture Output"というノードです。ここへ繋がった要素がそのままRVTへ書き込まれることになります。
ランドスケープの作成とRVTの設定
次にランドスケープを作成します。ランドスケープ自体は適当な設定のものでも構いません。今回は小さめのランドスケープを作成しています。作成する際には今回作ったランドスケープマテリアルを適用しておきましょう。
ランドスケープのペイントモードに切り替えておき、3つのレイヤーを適用しておきます。ランドスケープレイヤーの適用は少しややこしいので、ドキュメントを参考にしながらやってみてください。ただし、最新の4.25はモードパネルUIも少し違うため、違いに注意してください。
作ったランドスケープにペイントモードで適当にそれぞれのレイヤーを塗っておきます。もちろんランドスケープはスカルプトで地形を変えてしまっても問題ありません。
次に"Runtime Virtual Texture Volume"というアクターをレベル内に配置し、ランドスケープを全て覆うようにサイズを調整します。
Runtime Virtual Texture Volumeアクターを選択し、"Source Actor"に適用したいランドスケープを指定、"Virtual Texture"に今回作成したRVTアセットを指定しておきます。
これでランドスケープマテリアルとRVTの設定は完了しました。最後は配置メッシュ側のマテリアルの設定です。
配置メッシュ側のマテリアル
最後に配置されるマテリアル側の設定も必要です。必要な部分は少ないので、該当部分をマテリアル関数化しておき、マスターマテリアルに入れておくことで流用化もしやすいと思います。
まずはメッシュディスタンスフィールドの情報を使ってメッシュ境界を取得できるようにノードを作成しておきます。
そしてRVTのテクスチャーをサンプリングできる、"Runtime Virtual Texture Sample"ノードと通常のTexture SampleをLerpなどでブレンドするようにします。ここで、"Runtime Virtual Texture Sample"ノードを選択し、"Virtual Texture"が今回作成したRVTアセットを指定するようにすることを忘れないでください。
最後に"Pixel Depth Offset"へ"DitherTemporalAA"ノードを使って、境界部分のブレンドの強さを指定できるようにします。
これで全て完成しました!完成したノードの全体構成を貼ると以下のような感じになります。
それでは最後にメッシュに適用していきましょう。
配置されたメッシュへマテリアルを適用
まずはメッシュを適当に配置しておきます。ここではマテリアルはデフォルトのままです。
次にそれぞれのメッシュに今回作成したRVT適用の入ったマテリアルを設定します。
これだけでもかなり変化がわかります。次にマテリアルインスタンス上でパラメーターを調整してみます。
このマテリアルでは元々岩用のテクスチャーを使っていたので、表面の岩部分とランドスケープの雪部分と上手くブレンドされました。
欠点
全体的にいい感じではあるのですが、RVTはあくまでも2次元のテクスチャー情報しか持っていないので、非常に高さのあるものには有効に働きません。
ちょっと伸び方が酷い感じになってしまいます。ただ、これも調整次第でよく見えるようにすることは可能だと思います。試行錯誤して見栄えをよくしていきましょう!
欠点はありますが、RVTを使った大規模な背景の馴染ませは非常に大きなクオリティアップに繋がります。実は負荷もそこまで高くありません。ぜひ使えそうな時にはどんどん使っていきましょう!