BLOGブログ

2020.01.29UE4/Material

[UE4]VirtualTexturingについて

執筆バージョン: Unreal Engine 4.24

今回はVirtualTexturingについて紹介したいと思います。

※※注意※※VirtualTexturingはバージョン4.23から入ってきた機能で、現在ベータ版です。
また、VirtualTexturingを使うことそのものが処理負荷軽減にはならない可能性があります。

・VirtualTexturingの種類について
VirtualTexturingには2種類あります。それぞれの利点や使い方について触れていきたいと思います。
・StreamingVirtualTexturing(以下SVT)
・RuntimeVirtualTexturing(以下RVT)

StreamingVirtualTexturingについて
この手法が効果的なものは、ライトマップなど、どうしてもテクスチャサイズが大きくなってしまうものや、巨大なオブジェクトに対して高解像度なテクスチャを適用しているときなどに効果的です。
現状のmipmapの方法だと、オブジェクトに対して近い状態だと、そのオブジェクトが画面の1部分にしか描画されていなくても、高解像度のテクスチャ全体が読み込まれてしまいます。
それに対し、SVTでは表示されている部分にあった解像度のテクスチャがストリーミングされます。下の画像はSVTが適用されている状態です。

適用されているテクスチャの解像度が1つのオブジェクトの中で変化しています。どのくらいのミップレベルで読み込まれているかは
r.VT.Borders 1
で可視化できます。メッシュがカメラに近い部分ほどグリッドが細かく分割されている(高い解像度が使われている)のが確認できます。
このボックスに貼られているSVTすべてのmipmapがタイル状に分割されていて、必要な部分だけロードしています。(画像はRenderDocからの確認したものになります)

SVTを使用したい場合はProject Settings>Rendering>Enable Virtual Texture Supportにチェックを入れます。(プロジェクトの再起動が必要になります)

次にSVTしたいテクスチャ設定を開いてVirtual Texturing Streamingのチェックを有効にします。

設定が適用できるとテクスチャのサムネイルに『VT』の文字が付きます。
※プロジェクト設定のVirtualTexturingをONにすると大きなテクスチャを読み込んだときに自動的にVirtual Texturing Streamingが有効になります。およそ4Kサイズ以上になると自動的にVTになるようです。

またSVTによってUDIMにも対応することができます。
※ベータ版のためか、かなり挙動が怪しいです。テクスチャリインポートではほぼ確実にエディタが落ちてしまいました。
UDIMテクスチャはテクスチャが同じ階層内に下記のように連番で名前がつけられていると自動的にUDIM・VirtualTexturing化されます。
BaseName.####.[サポート画像形式]
テクスチャを上記の命名規則に従ってサイズ違いで4枚、以下の用に用意しました。

UDIM用テクスチャのうちどれか1枚を選択すると同階層にあるテクスチャも自動的に読み込んでくれます。
UE4に読みこんだテクスチャは以下の様に複数のテクスチャが1枚にまとめられています。

Mayaで以下のようなUV配置をしたオブジェクトを用意しました。そのオブジェクトにインポートしたテクスチャを適用すると2つ目の画像になります。0~1のUV領域を超えてちゃんとマッピングされています。

ただし、読み込み時にテクスチャサイズが異なるものが入っていると、以下の画像のように勝手にタイリングされてしまう場合があります。タイリングはプロジェクトを開き直すと正しくなるようです。
(それでも治らない場合はNoMipmapに変更してプロジェクトを開き直したりすると正しくなるかもしれません…)
他にもStreamingのボーダーが正しく可視化されない場合があったりと、使用にはかなり注意しなければいけないかもしれません。

RuntimeVirtualTexturingについて
RVTは前述したSVTと異なり、テクスチャ単体の仕組みではなく、シェーディングキャッシュのようなものになっています。
マテリアルで使用しているテクスチャをそのままを使うのではなく、そのマテリアルを使用してブレンドした結果をテクスチャとしてキャッシュしている状態になっています。さらにそのテクスチャをSVTと同様、すべてのmipmapがタイル化され、サンプリングする際に解像度などを加味してくれています。(mipmapをどこまで含めるかは設定で変更できます。
以下のランドスケープマテリアルをRVT化してみます。

マテリアルの状態

ビューポートの状態

RVTしたものをRendererDocでどのようなテクスチャを読んでいるのか確認したのが以下の画像になります。
マテリアルで使用している複数のテクスチャが使用状況に応じた1枚のテクスチャに合成されています。またそのテクスチャがSVTのようにタイルに分割され、必要な解像度にあわせたmipmapが呼び出されています。


RVTは、ランドスケープなどの様にテクスチャを複数使ったりする複数なマテリアルなどのレンダリングに向いています。
ただしこのRVTは実質的にシェーディングキャッシュのため、フレームごとの更新では無いそうです。そのため、動くメッシュには向いていません。MovableMeshではなくても、頂点シェーダで動いているようなStaticMeshも不向きなものに該当します。またRVTはキャッシュ結果をZ 軸の負方向への垂直投影するような形でテクスチャをメッシュに反映しています。

RVTを適用する手順を見ていきます。
RVTを使用する際もSVTと同様にProject Settings>Rendering>Enable Virtual Texture Supportが有効になっている必要があります
また、本記事ではRVT化するアセットはLandscapeアクタをベースにしています。

SVTを有効にするにはテクスチャのオプションを有効にするだけでしたが、RVTでは設定をもたせるアセットの作成、マテリアルの作成、適用範囲を決めるボリュームアクタの配置など、いくつか手順が必要になってきます。
順に説明していきたいと思います。

まずRuntime Virtual Texture というアセットを作成します。(以下RVT アセットとします

このアセット内でRVTの設定を変更することができます。設定の内容についてはこちらをご参照ください。
https://dq8iqaixvew1d.cloudfront.net/ja/Engine/Rendering/VirtualTexturing/Reference/index.html
この記事では作成時のデフォルトの設定で作業を進めます。
RVT アセットはマテリアル、ボリューム、RVTを適応したいアクタの合計3箇所に設定します。

次に、RVT用のマテリアルを作成します。使用するランドスケープマテリアルにRVT アセットに書き込むノード・Runtime Virtual Texture Outputと、RVT アセットに書き込むノード・Runtime Virtual Texture Sampleを追加します。
https://dq8iqaixvew1d.cloudfront.net/ja/Engine/Rendering/VirtualTexturing/Runtime/QuickStart/index.html
上記UE4ヘルプのクイックスタートではマテリアルをアトリビュート化しVirtualTextureFeatureSwitchノードに接続していますが、VirtualTextureFeatureSwitchノードはRVTがサポートされていないときに従来どおりのマテリアルを使用するように切り替えるスイッチャーです。この記事では省略させていただいてます。VirtualTextureFeatureSwitchノードや、他のRVTに関するマテリアルノードに関してはこちらをご参照ください。https://docs.unrealengine.com/ja/Engine/Rendering/VirtualTexturing/Runtime/index.html

Runtime Virtual Texture SampleノードにはどのRVTアセットを使用するかを割り当てておきます。

マテリアルが作成できたら、RVTを割り当てるアクターを覆うようにRuntimeVirtualTextureVolumeを配置していきます。

RuntimeVirtualTextureVolumeTransform from Bounds欄でボリュームで囲いたいアクターを選択し、Copy Rotation,Copy Boundsを押すと自動でアクタの形に合うようにボリュームを配置してくれます。ただしこの記事の作例の様に平らなもので行うとボリュームのZスケールが0になるので手動で調整します。

さらにLandscapeアクタ自体にもRVT アセットを設定する必要があります。Landscapeアクタを選択し、Virtual Texture>Render to Virtual Texturesの+ボタンを押してエレメントを作成して、そこにRVTアセットを設定します。


以上の設定でLandscapeマテリアルをRuntimeVirtualTexturingにすることができていると思います。

さらにRuntimeVirtualTexturing化したものは他のものにテクスチャとして適応したり、逆にRuntimeVirtualTexturingに要素を追加することもできます。

キャッシュしたRuntimeVirtualTexturingをテクスチャとするには、Runtime Virtual Texture Sampleをマテリアルで使用すれば可能です。メッシュ形状のディテール追加に役立ちそうです。
以下の画像はスフィアのマテリアルにRVTのカラーテクスチャに適用した場合です。

対してRVTに要素として追加するには、追加したいアセットを選択>Virtual Texture>Render to Virtual Textureに書き込む先のRVTアセットを設定すると要素が書き込まれます。また書き込むマテリアルはドメインがVirtual Textureになっている必要があります。メッシュをデカールのように扱うことができます。元のメッシュのマテリアルのノーマルやラフネスなども反映されています。(RVTアセットや書き込み先マテリアルがRuntime Virtual Texture Sampleからラフネスやノーマルの値を受け取っている必要があります。)

長くなってしまいましたが、以上VirtualTexturingについての紹介でした。参考になれば幸いです。