バーチャル テクスチャのメモリ プール

バーチャル テクスチャの物理メモリ プールを使用した GPU メモリ割り当ての概要。

バーチャル テクスチャ システムには GPU メモリ割り当ての主なタイプとして、ページ テーブル メモリと物理メモリ プールの 2 つがあります。

  • ページ テーブル メモリ は、テクスチャ座標からテクスチャ データへの間接参照を提供し、オンデマンドで割り当てられます。時間の経過とともに増大することがあり、その内容がすべて解放されない限り、通常はメモリから解放されません。このメモリ タイプをユーザーが制御することはできません。

  • 物理メモリ プール には、現在常駐しているテクスチャ データが入っていて、いくつかの個別のプールで構成されています。バーチャル テクスチャ システムで使用される各テクスチャ形式には、固有のメモリ プールが関連付けられています。各プールは、バーチャル テクスチャの最初のインスタンス化時に、一致する形式で割り当てられています。各プールのサイズは固定であり、増やすことはできません。各プールのサイズはユーザーが制御できます。

このドキュメントでは、バーチャル テクスチャの物理メモリ プールをどのようにして定義およびデバッグするかについて説明します。

物理メモリ プールの動作について

物理メモリ プールはそれぞれ複数のページで構成されています。各ページにはバーチャル テクスチャの 1 つのタイルのデータが入っています。このプールは、最も長い時間使用されていないキャッシュとして機能します。バーチャル テクスチャ システムがタイルをリクエストすると、プール内の利用可能なページにストリーミングまたはレンダリングされます。利用可能なページがなければ、最も長い時間使用されていないタイルが入っているページが追い出されて、新しいページの領域が空けられます。

バーチャル テクスチャのメモリ プールに収まらない数のバーチャル テクスチャ タイルがビューに表示される場合、システムはそのビューを正しくレンダリングできません。その場合は、バーチャル テクスチャのメモリ プールのサイズを、データ使用量に合うように調整する必要があります。

物理メモリ プールを構成する

バーチャル テクスチャリング用の メモリ プール サイズ は「BaseEngine.ini」コンフィギュレーション ファイルで設定されています。

プールは テクスチャ形式グループ ごとおよび タイル サイズ ごとに設定されています。それらの設定は、プロジェクト固有の [コンフィギュレーション ファイル]() を設定することで、プロジェクトごとにオーバーライドできます。

バーチャル テクスチャのメモリ プール用のすべてのコンフィギュレーション設定は、/Script/Engine.VirtualTexturePoolConfig 見出しの下にあります。

次の例では、BC7 テクスチャが入っているバーチャル テクスチャのすべてのメモリ プールのサイズが 100 メガバイト (MB) に設定されています。このサイズは近似値であり、システムが実際に割り当てるのは、整数のページ数に収まる平方数であり、100 MB 未満で最も大きいプール サイズです。

    [/Script/Engine.VirtualTexturePoolConfig]
    +Pools=(Formats=(PF_BC7), SizeInMegabyte=100)

コンフィギュレーション ファイルで該当するエントリがない形式では、デフォルトのプール サイズが使用されます。デフォルト値は、テクスチャ形式グループを指定せずにプールを定義することで表現できます。

    [/Script/Engine.VirtualTexturePoolConfig]
    +Pools=(SizeInMegabyte=64)

一部のプールには複数のレイヤーがあり、それぞれのレイヤーに固有の形式があります。これは、ほとんどの ランタイムバーチャル テクスチャ の設定が当てはまります。その場合、一致するレイヤー形式のエントリがコンフィギュレーション ファイルに存在する必要があります。

たとえば、マテリアルで Base Color、Normal、Roughness、Specular のタイプを使用するランタイムバーチャル テクスチャは次のように設定します。

    [/Script/Engine.VirtualTexturePoolConfig]
    +Pools=(Formats=(PF_DXT5, PF_DXT5), SizeInMegabyte=128)

メモリ プールのコンフィギュレーション エントリでは以下の追加設定を指定できます。

メモリ プールのコンフィギュレーション設定

説明

bAllowSizeScale

スケーラビリティのコンソール変数 r.VT.PoolSizeScale.Group <X> を通じてメモリ プールのサイズに適用される追加のスケール係数を指定できるようになります。

ScalabilityGroup

bAllowSizeScale が適用されるグループ インデックス (0-2) を設定します。複数のグループを指定すると、プールごとに異なるスケーラビリティを設定できます。

bEnableResidencyMipMapBias

このプールがサブスクリプション超過である場合にバーチャル テクスチャにミップマップ バイアスが適用されるという動作を有効にします。

物理メモリ プールの常駐

バーチャル テクスチャのメモリ プールの現在の使用量は 常駐 と呼ばれます。現在表示されているタイルによって 1 つのプールのすべてのページが割り当てられている場合、常駐は 100% です。

常駐が 100% であれば、プールはサブスクリプション超過であり、表示されているタイルのデータがドロップされます。そうなると、メモリでテクスチャ データのロードと追い出しが繰り返されるので、不要な IO および画面のちらつきが発生します。

メモリ プールがサブスクリプション超過である場合に画面上に通知が表示されるように設定できます。この通知はコンソール コマンド r.VT.Residency.Notify 1 を使用して有効にします。

virtual texture pool oversubscribed notification

この警告は、コンフィギュレーション ファイルでメモリ プールのサイズを増やすか、あるいはバーチャル テクスチャまたはマテリアルを変更する必要があることを表しています。このような問題の解決に関するヒントについては、下記のセクションを参照してください。

常駐ミップマップ バイアス

bEnableResidencyMipMapBias 設定を有効にしてプールが構成されていれば、プールがサブスクリプション超過である場合に常駐を減らすようにミップマップ バイアスが設定されています。そうすると、解像度を下げてバーチャル テクスチャをレンダリングすることで、不要な IO および画面のちらつきが回避されます。

常駐のサブスクリプション超過の発生がごくまれであり、そのめったに発生しないことのためにメモリを割り当てたくない場合に、この設定は有用です。サブスクリプション超過に対する画面上のメッセージには、適用されているミップマップ バイアスが示されます。

常駐に由来するミップマップ バイアスはグローバルです。すべての物理メモリ プールからの現在の最大バイアスは、すべてのバーチャル テクスチャ サンプリングに適用されています。

物理メモリ プールのヘッドアップ表示

常駐を監視し、サブスクリプション超過の発生を減らすには、適切なメモリ プール サイズを設定することが重要です。画面上のヘッドアップ ディスプレイ (HUD) を使用して、各バーチャル テクスチャの物理メモリ プールの現在の常駐を表示することができます。

それを有効にするには、コンソール コマンド r.VT.Residency.Show 1 を実行します。

virtual texture pool residency level editor view

バーチャル テクスチャの物理メモリ プールの HUD には、各テクスチャ形式の現在の常駐とその割り当て済みメモリが表示されます。

virtual texture pool residency graph

画面上の各グラフは、バーチャル テクスチャの物理メモリ プールのいずれかを表しています。次の 3 つの折れ線グラフがあります。

  • 赤色 は現在のプール占有率であり、0 ~ 100% の範囲です。

  • 黄色 は固定プール占有率であり、0 ~ 100% の範囲です。

  • これは、ロック済みとマークされているページによる占有率です。通常は、バーチャル テクスチャごとに 1 ページがロックされています。ロード済みのバーチャル テクスチャ アセットの数が非常に大きいと、そのバーチャル テクスチャが表示されていなくても、利用可能なプール領域が減少することがあります。

  • 緑色 は、常駐を 100% 未満に維持するために適用されているミップマップ バイアスです。

物理メモリ プールの常駐をデバッグする

バーチャル テクスチャのメモリ プールがサブスクリプション超過である場合にデバッグおよびコンテンツのチェックを開始すべきいくつかの領域を以下に示しています。

メモリ プールのサイズ

バーチャル テクスチャのメモリ プール サイズに関して以下の点をチェックします。

  • プール サイズが、想定されるバーチャル テクスチャ データのフル作業用セットを保持するのに十分な大きさであることを確認します。

  • ページ サイズが大きいプールほど、プール サイズが大きくなっている必要があります。たとえば、テクスチャ形式が PF_A32B32G32R32F であるプールは、テキスト形式が PF_DXT1 であるプールよりもメモリ要件がはるかに大きくなります。同様に、複数のレイヤーがあるプールはメモリ要件が大きくなります。

  • 出力解像度が高いレンダリングほど、プール サイズを大きくする必要があります。

  • 通常は、出力解像度が高いほど、高い解像度のミップ タイルが必要とされます。

  • タイル サイズが大きいほど、必要とされるプール サイズが大きくなります。

  • ストリーミングバーチャル テクスチャリング のデフォルトのタイル サイズは 128 テクセルです。ただし、このデフォルト値はオーバーライドできます。

  • ランタイムバーチャル テクスチャ のタイル サイズは最大で 1024 テクセルにすることができます。タイル サイズが大きいほど、プール内に無駄な領域が発生しやすくなります。

サブスクリプション超過

サブスクリプション超過の注目すべき原因の 1 つは、バーチャル テクスチャのサンプリング時にミップ バイアスが負の値であるアプリケーションです。体系的にサンプルするミップの解像度が高いほど、必要とされるメモリ プールの量が多くなります。ミップ バイアスが負の値であるのは、マテリアル グラフにある Texture Sample ノードでミップ レベルまたはバイアスを明示的に設定しているためです。

サブスクリプション超過は、予期しないソースが原因である場合もあります。UV が三角ポリゴンまたはメッシュのインバリアンであるために、ゼロ勾配のテクスチャをサンプリングした場合などです。次のマテリアル グラフのスニペットはその例です。この具体的な事例は、Runtime Virtual Texture Sample ノードの Mip Value 設定で [Ignore Input WorldPosition (入力のワールド位置を無視する)] を使用することによって解決できます。

virtual texture pool oversubscription material example

コンソール コマンド r.VT.DumpPoolUsage を使用すると、ミップ バイアスや他の問題が原因で想定よりも多くのプール内の領域を占有しているテクスチャを見つけるのに役立ちます。このコマンドは、各バーチャル テクスチャ アセットが各メモリ プールで現在割り当てているページの数をダンプします。そのダンプ出力はページ数が多い順に並べられているので、最初のエントリが妥当であるかどうかを確認します。

次のダンプでは、最初のエントリがその他のエントリよりも著しく大きくなっています。したがって、T_Ground_Sand_F_basecolor_CANYON を参照しているマテリアルでミップ バイアスの問題を確認します。

    PhysicaPool: [0]DXT1 (136x136):
        T_Ground_Sand_F_basecolor_CANYON 1912
        T_Rock_Quarry_Y_RAOD 418
        ubulehofw_8K_Albedo 324
        pcciQ_4K_Albedo 248
        T_Rock_Cliff_D_RAOD 187
        noise_directional_3 115
        T_column_260_B_W 97
        T_column_260_B_goldA_RMAOO 97
        T_column_260_B_goldA_C 96
このページは Unreal Engine の前のバージョン用です。現在リリースされている Unreal Engine 5.3 に対して更新は行われていません。
Unreal Engine のドキュメントを改善するために協力をお願いします!どのような改善を望んでいるかご意見をお聞かせください。
調査に参加する
キャンセル