仮想シャドウ マップ (VSM) は、Unreal Engine 5 の Nanite 仮想化ジオメトリ、Lumen のグローバル イルミネーションおよび反射、および World Partition の機能を使用して、映画品質のアセットおよび大規模で動的ライティングのオープン ワールドで機能する、一貫性のある高解像度シャドウイングを実現するために使用される新しいシャドウ マッピング方法です。
仮想シャドウ マップの目的
仮想シャドウ マップは以下を目的として開発されました。
- 詳細度の高い Nanite ジオメトリと釣り合うように、シャドウの解像度を大幅に上げる
- 合理的で制御可能なパフォーマンス負荷でリアルなソフトシャドウを実現する
- わずかな調整のみで、デフォルトで機能する単純な解決方法を提供する
- 固定ライト シャドウイング手法を統一された単一パスで置き換える
概念上は、仮想シャドウ マップは非常に高解像度のシャドウ マップにすぎません。現時点の実装での仮想解像度は 16K x 16K ピクセルです。クリップマップは、ディレクショナル ライトの解像度をさらに上げるために使用されます。高いパフォーマンスを保ち、メモリ使用量を適度にするために、VSM ではシャドウ マップが 128 x 128 ピクセルの複数のタイルに分割されます。ページは、深度バッファの解析に基づいて画面上のピクセルをシェーディングするために必要な場合のみ割り当てられてレンダリングされます。そのページは、オブジェクトまたはライトの移動によって無効化されない限り、フレーム間でキャッシュされるので、パフォーマンスがさらに向上します。
Nanite では、プレシャドウおよびオブジェクト (またはインセット) ごとのシャドウなど、固定ライト シャドウイングの多くをサポートしていません。カメラ ビューアの近くにあるカスケード シャドウ マップなど、固定ライト シャドウイングのより動的な機能の一部は動作することがあるものの、従来のシャドウ マップを使用した Nanite および固定ライトはサポートされていません。プロジェクトで Nanite を使用する場合は、ムーバブル ライトを使用するか、仮想シャドウ マップを使用する必要があります。
仮想シャドウ マップを有効化する
[Project Settings (プロジェクト設定)] の [Engine (エンジン)] > [Rendering (レンダリング)] を選択すると表示される [Shadows (シャドウ)] セクションで、プロジェクトでサポートされている [Shadow Map Method (シャドウ マップ メソッド)] ([Virtual Shadow Maps (仮想シャドウ マップ)] か、以前の Unreal Engine リリースで使用されていた従来の [Shadow Maps (シャドウ マップ)] のどちらか) を設定することができます。
既存のプロジェクトでは、[Project Settings] またはコンソール変数 r.Shadow.Virtual.Enable
を使用してオプトインする必要があります。新規プロジェクトでは、デフォルトで仮想シャドウ マップが使用されます。

VSM を有効にした場合の既存のシャドウ メソッドの処理
VSM を有効にすると、Unreal Engine では、以下のさまざまな既存のシャドウ メソッドが置き換えられます。
- 固定ライトの事前計算されたシャドウ (2D ディスタンス フィールドおよびシャドウ係数「シャドウ マップ」も含む)
- プレシャドウ
- オブジェクトごと / インセット シャドウ
- カスケード シャドウ マップ (CSM)
- ローカル ライトに対する可動の動的シャドウ
完全にベイクされた静的ライトからのシャドウは、これまでと変わらずに機能します (Lumen を使用していない場合)。それらの影響はベイク済みライトマップで完全に表されているので、ランタイムのライティング評価は一切行われません。固定ライトでは、ベイク済みライトマップからの間接的なディフューズの影響が使用されますが、VSM が有効になっている場合、その直接ライティングとシャドウは動的に評価されます (可動ライトと同様)。
ディスタンス フィールド シャドウ は置き換えられることはなく、ディレクショナル ライトのための仮想シャドウ マップと併用することができます。ディレクショナル ライトでカスケード シャドウ マップのプロパティ Dynamic Shadow Distance Movable Light を使用して設定された可動ライトの動的シャドウイング距離を超える Nanite 以外のジオメトリは、ディスタンス フィールド シャドウに切り替わります。ディスタンス フィールド シャドウを使用すると、Nanite 以外のフォリッジ が多数含まれているなど、複雑なシーンでランタイムの負荷を軽減するのに役立つツールが提供されます。
Nanite ジオメトリは、距離を問わず常に仮想シャドウ マップにレンダリングされます。この方法が最もパフォーマンスが高く、最高の品質を提供するオプションであるためです。コンソール変数 r.Shadow.Virtual.UseFarShadowCulling 0
によって、Nanite 以外のジオメトリを Nanite と同じように動作させることができます。
ローカル ライト (ポイント ライトとスポット ライト) は影響されず、ローカル ライトに対してディスタンス フィールド シャドウを選択すると、アクティブなシャドウ マップ手法が引き続きオーバーライドされます。
VSM の高解像度と精度により、Contact Shadow Length プロパティで制御されるスクリーン空間のコンタクト シャドウ機能は、シャープなコンタクト シャドウを実現するために不要になりました。シャドウ マップにレンダリングしないように設定されたオブジェクトから負荷の低いシャドウを取得するために使用する場合でも価値がある可能性がありますが、VSM が作成するシャドウよりも精度が低いため、それ以外の場合はお勧めしません。
レイトレース シャドウでは通常は最高品質のソリューションが提供されるので、レイトレース シャドウは VSM よりも優先されます。
シャドウ マップ レイ トレーシングによるソフト シャドウ
シャドウ マップ レイ トレーシング (SMRT) は、よりリアルなソフト シャドウやコンタクト シャドウを生成するために、仮想シャドウ マップで使用されるサンプリング アルゴリズムです。影を遠くに投影するオブジェクトは、影を受け取るサーフェスの近くにシャドウを投影するオブジェクトよりもソフトなシャドウになります。 たとえば、下の写真のメッシュは背が高く、長距離にシャドウを落としています。ベースの近くのシャドウは、遠くのシャドウよりもシャープです。

ソフト シャドウをキャストするポイント ライトと、シャドウ マップ レイ トレーシングを使用して強化されたコンタクト シャドウの例。
PCF (Percentage-Closer Filtering) に基づいた以前の方法では、ブラーが過剰になり、高解像度のジオメトリやシャドウのビジュアル面での影響が低減していました。


SMRT アルゴリズムでは、いくつかのレイが光源に向けて発射されますが、従来のレイトレーシングのようにジオメトリとの交差を評価するのではなく、レイに沿ったいくつかのサンプルが投影され、コンタクト シャドウが強調されたソフト シャドウイングを達成するように、仮想シャドウ マップに対して測定されます。 シャドウ レイは、ライトの [Source Radius (光源の半径)] (ローカル ライトの場合) または [Source Angle (光源の角度)] (ディレクショナル ライトライトの場合) に基づいて分散します。
![]() |
![]() |
---|---|
ローカル ライトの光源の半径 | ディレクショナル ライトの光源の角度 |
デフォルトでは、ローカル ライトには [Source Radius] は設定されていませんが、ディレクショナル ライトには [Source Angle] に小さい値が設定されています。いずれかに適切な値に設定されていると、SMRT により、コンタクト シャドウが強化されたソフト シャドウがリアルタイムで生成されます。以下の例では、[Source Radius] が「10」であるポイント ライトを使用しています。
![[Source Radius] が「0」のポイント ライト](vsm-pointlightradius_0.png)
![[Source Radius] が「10」のポイント ライト](vsm-pointlightradius_10.png)
半影シャドウの品質の制御
半影シャドウのソフトネス品質は、ローカル ライトとディレクショナル ライトのどちらもコンソール変数で設定されています。それらの変数には、ほとんどのシーンで一般的に適切な独自のスケーラビリティ設定が含まれています。
半影のノイズは使用される光線数に影響されます。また、[Shadows] のスケーラビリティが [Epic] に設定されている場合、ローカル ライトとディレクショナル ライトの両方がデフォルトで 8 つのレイを使用します。
レイ数を調整するには、コンソール変数 r.Shadow.Virtual.SMRT.RayCountLocal
および r.Shadow.Virtual.SMRT.RayCountDirectional
を使用します。レイ数が少ないほど、半影のノイズが表示されます。関連付けられているコンソール変数を「0」に設定すると、SMRT が無効になり、単一サンプルのハード シャドウに戻ります。


さらに、ローカル ライトおよびディレクショナル ライトに対して、各レイのパスに沿って取得されるサンプル数を設定すると、最大ソフトネスを制御できます。シャドウ マップのサンプル数が少ないほど、レンダリングの負荷が小さくなりますが、そのライトのシャドウで実現できる半影シャドウのソフトネスの量が限定されます。
シャドウ のスケーラビリティ設定よりさらに細かい制御を行うには、コンソール変数 r.Shadow.Virtual.SMRT.SamplesPerRayLocal
および r.Shadow.Virtual.SMRT.SamplesPerRayDirectional
を使用して、使用するサンプル数を調整します。適切に機能させるには、4 ~ 8 サンプルの範囲の値を使用します。



スライダをドラッグすると、[Source Angle] が「5.0」であるディレクショナル ライトで、シャドウ マップのサンプル数が「0」、「2」、「8」(デフォルト) のときにそれぞれどうなるかが示されます。
シャドウ マップ レイ トレーシングの制限事項
SMRT の品質は通常はデフォルト設定で良好ですが、実際のジオメトリに対してテストするのではなく単一のシャドウ マップ投影からのデータを使用することに伴って、以下の制限事項があります。
半影サイズの制限
シャドウの半影は、レイ自体に沿った理想的な測定と比べて次第に「曲がる」ことがあるレイの起点からのサンプルの発散を回避するために、ローカル ライトおよびディレクショナル ライトに対してクランプされています。ローカル ライトの [Source Radius] およびディレクショナル ライトの [Source Angle] に妥当な値を使用すると、結果があまりに極端になることが回避されて、レイがさまざまな方向に放射される範囲が制限されます。これらの値が大きすぎると、パフォーマンスが低下し、カメラが近づいたときにシャドウの半影が視覚的にワープすることになります。

クランプされる範囲を広げたり狭めたりするには、ローカル ライトおよびディレクショナル ライトのコンソール変数 r.Shadow.Virtual.SMRT.MaxRayAngleFromLight
および r.Shadow.Virtual.SMRT.RayLengthScaleDirectional
を使用します。
整合性のない反影
仮想シャドウ マップでは最初の深度レイヤーのみが格納されて、ナイーブなイテレーションでは最初のオクルーダの背後にあるオクルーダとの交差が見逃されるので、オクルーダが重なっている場所ではさまざまな光漏れアーティファクトが発生することがあります。そのような光漏れは、オクルージョンのポイントの前の深度に基づいて最初のオクルーダの背後の深度を外挿する、ギャップ充填ヒューリスティックを使用して解決されます。
これは光漏れの解決には効果がありますが、ライトに平行に傾いているサーフェス上の半影のサイズが縮小されます。現時点では、半影を妥当なサイズにしておくこと以外に、この縮小を防ぐ直接的な方法はありません。

整合性のない半影の例。
半影のアーティファクト
デフォルトでは、仮想シャドウ マップでは、レイの起点 (レシーバー ピクセル) の周りのサンプルが存在することだけが保証されています。このアルゴリズムでレイを横切るときに通過するページがマッピングされていないために、シャドウ データが存在しないことがあります。この影響を軽減するために、ページ マッピングのわずかな拡大や、イテレーション時のさまざまなフォールバックの準備などの、さまざまな手法が使用されています。それでも、欠落したページから生じる偶発的なアーティファクトが発生することがあります。特に、ソフト半影にズームインしたときに画面のエッジ付近で顕著です。このようなアーティファクトは、シャドウ領域でノイズを伴う光漏れとして現れます。 VSM での他の制限事項と同様に、この問題もほとんどの場合は、シャドウ半影を妥当なサイズにしておき、画面の大部分をカバーするポイントにズームインしないようにすることで回避できます。
ディレクショナル ライトのクリップマップ
1 つの仮想シャドウでは、広い範囲をカバーするのに十分な解像度は得られません。ディレクショナル ライトでは、カメラ周りに範囲を拡大する「クリップマップ」構造体が使用され、各クリップマップ レベルで 16K の VSM が使用されます。各クリップマップ レベルの解像度は同じですが、カバーする半径は以前の 2 倍になっています。
![]() |
![]() |
---|---|
ディレクショナル ライトのクリップマップのビジュアライゼーション | 仮想シャドウ マップ ページのビジュアライゼーション |
デフォルトでは、クリップマップ レベル 6 ~ 22 は仮想シャドウ マップのページ テーブルに割り当てられています。つまり、デフォルト設定では、カメラ位置から 64cm (2^6 cm) をカバーする詳細度が最も高いクリップマップになり、約 40 km (2^22 cm) をカバーする最も広いクリップマップになります。仮想クリップマップ レベルの中に何も存在しなければ、その負荷はごくわずかであるため、これらのデフォルトでは、カメラに近いかなりの高解像度で大規模なシーンを適切にカバーできます。
最初と最後のレベルは、コンソール変数 r.Shadow.Virtual.Clipmap.FirstLevel と r.Shadow.Virtual.Clipmap.LastLevel
を使用して調整できます。
対象となるピクセルに割り当てられる解像度は、クリップマップの原点 (カメラ) からの距離に応じて決まります。これは、コンソール変数 r.Shadow.Virtual.ResolutionLodBiasDirectional
を使用して、シャドウのスケーラビリティによって制御できます。値が「0」であれば、カメラのパースペクティブ投影に基づいて、必要な解像度が選択されます。
高解像度であっても投影エイリアス (ライトの方向にほぼ平行なサーフェスにシャドウがキャストされている場合) は可能ですが、解像度へのバイアスの適用によってある程度低くなることがあります。テクスチャでのミップ バイアスと同様に、この値が -1 小さくなるごとにシャドウの解像度が 2 倍になるので、パフォーマンスとのトレードオフを伴います。Epic Shadow スケーラビリティのデフォルト値である「-1.5」では、多くのシーンで合理的なバランスが提供されます。
ローカル ライト
スポット ライトでは、シャドウの詳細度に対処できるように、クリップマップではなくミップ チェーンによる単一の 16K の VSM が使用されます。同様に、ポイント ライトでは、16K の VSM のキューブ マップがフェースごとに 1 つ使用されます。
ローカル ライトでは、従来のシャドウ マップと比べて解像度が大幅に上がります。非常に大きいローカル ライトでは仮想の解像度が不足することがあるため、そのような場合は可能であればディレクショナル ライトを使用するように配慮する必要があります。


スクリーンのピクセル単位のサイズをシャドウ マップの領域に投影することによって、適切なミップ レベルが選択されます。ディレクショナル ライトと同様に、シャドウ スケーラビリティの設定か、コンソール変数 r.Shadow.Virtual.ResolutionLodBiasLocal
を使用して、解像度にバイアスを適用することができます。
ライトごとの解像度の制御は利用できませんが、今後のリリースで追加される可能性があります。
移動ライト
固定ライトは大部分がキャッシュされ、その結果、移動ライトよりもはるかに高い解像度を使用できます。固定ライトと移動ライトのこの違いを考慮するために、可動ライトには固定ライトとは異なる LOD バイアスを設定する必要があります。ライトが移動を停止すると、元のバイアスに徐々に移行します。移動ライトの LOD バイアスは、以下のスケーラビリティ コンソール変数で制御できます。
r.Shadow.Virtual.ResolutionLodBiasLocalMoving
r.Shadow.Virtual.ResolutionLodBiasDirectionalMoving
半透明サーフェス
仮想シャドウ マップは、Substrate と従来のパスを持つ半透明サーフェスの高品質なシャドウ フィルタリングをサポートします。これはグローバル オプトイン機能で、コンソール変数 r.Shadow.Virtual.TranslucentQuality
で有効にできます。このコンソール変数は、ライティングされた半透明サーフェスのシャドウの品質を制御します。これはすべての半透明サーフェスに適用され、パフォーマンスに大きな影響を与えます。r.Shadow.Virtual.TranslucentQuality
の設定:
- 1 より大きい値:ライティングされている半透明サーフェスのシャドウが高品質。
- 0:(デフォルト) ライティングされている半透明サーフェスのシャドウが通常の品質。
粗いページ
深度バッファ解析は、レンダリングが必要なページをマークするための主な方法として使用されています。ボリュメトリック フォグ や前方レンダリング透過処理など、一部のシステムでは、より多くの無作為の場所でシャドウをサンプリングする必要がありますが、大部分のシステムでは、低解像度のシャドウのみが必要とされ、それに対して他のデータ構造体でフィルタやブラーが適用されます。
そのような状況でのシャドウイングに対応するために、[Coarse Pages (粗いページ)] がマークされて、サンプリングの領域全体で少なくとも低解像度のシャドウ データが利用可能であるようになっています。ローカル ライトではルート ミップ ページだけがマークされますが、ディレクショナル ライトでは、さまざまな低い詳細度の一連のページがマークされて、複数の粗いクリップマップが形成されます。 シーンによっては、粗いページが原因でパフォーマンスが低下することがあります。特に、Nanite 以外の動的ジオメトリでは、低解像度のシャドウが広範囲にわたって効果的にレンダリングされるので、ドローコールのボトルネックになることがあります。
コンソール変数 r.Shadow.Virtual.NonNanite.IncludeInCoarsePages 0
を使用して、Nanite 以外のオブジェクトの粗いページへのレンダリングを無効にしてみることをお勧めします。
多くのシーン (特に主に Nanite ジオメトリで構成されているシーン) では、ボリュメトリック フォグなどにシャドウをキャストする Nanite 以外のオブジェクトが必要ありません。これを無効にすると、パフォーマンスが大幅に向上します。
ローカル ライトの粗いページが不要であれば、r.Shadow.Virtual.MarkCoarsePagesLocal
でオフに切り替えることができます。
ディレクショナル ライトの粗いページは、r.Shadow.Virtual.MarkCoarsePagesDirectional
でオフに切り替えることができ、粗いページがマークされるクリップマップ レベルの範囲は r.Shadow.Virtual.FirstCoarseLevel
および r.Shadow.Virtual.LastCoarseLevel
で変更できます。
今後のリリースでは、現在使用されている過度に慎重な粗いページではなく、これらの効果の一部を前もって局所的なページに対して直接マークできるような、もっと優れた解決方法になる予定です。
ビジュアライゼーション
仮想シャドウ マップのビジュアライゼーション オプションは、レベル ビューポートの [View Modes (表示モード)] ドロップダウン メニューで [Virtual Shadow Map (仮想シャドウ マップ)] を選択すると、アクセスできます。

ビジュアライゼーション オプションには、次の項目があります。
ビジュアライゼーション名 | 説明 |
---|---|
Shadow Mask (シャドウ マスク) | シェーディングで使用される最終的なシャドウ マスクです。 |
Clipmap/Mip Level (クリップマップ/ミップ レベル) | クリップマップ (ディレクショナル ライトの場合) またはミップ (ローカル ライトの場合) のレベルを選択します。 |
Virtual Page (バーチャル ページ) | 仮想ページ アドレスのビジュアライゼーション。 |
Cached Page (キャッシュ ページ) | キャッシュされるページは緑色、キャッシュされていないページは赤色で表示されます。静的ページのみがキャッシュされているページ (動的にキャッシュされない) は青色で表示されます。 |
デフォルトでは、仮想シャドウ マップのビジュアライゼーションは、ディレクショナル ライトの結果を表示します。[World Outliner (アウトライナ)] でライトを選択すると、そのライトのビジュアライゼーションを表示することができます。
また、コンソールを使用してビジュアライゼーションを有効にすることもできます (シッピング ビルドは除く)。これは、ライブ ゲームのプロファイリングやデバッグに役立ちます。エディタでこれらのいずれかが設定されている場合、エディタのユーザー インターフェースで選択されたモードがオーバーライドされます。
ビジュアライゼーション名 | 説明 |
---|---|
r.Shadow.Virtual.Visualize [mode] |
レベル ビューポートまたはコンソール コマンドで表示モードのビジュアライゼーションが [Virtual Shadow Map] に設定されている場合は、このコマンドで、表示するチャンネルを指定します。「[mode]」に以下の名前を指定すると、そのビジュアライゼーションが有効になります。cache と vpage の 2 つは、ビジュアライゼーションでよく使用されるモードです。また、none を使用すると、vsm のビジュアライゼーションが無効になります。
|
ShowFlag.VisualizeVirtualShadowMap |
ビジュアライゼーション モードが指定されている場合に、仮想シャドウ マップのビジュアライゼーションを有効にします。 |
r.Shadow.Virtual.Visualize.Layout |
仮想シャドウ マップのビジュアライゼーションのレイアウトを選択します。
|
r.Shadow.Virtual.Visualize.DumpLightNames |
仮想シャドウ マップを含む現在のライトのリストをコンソールに出力します。 |
r.Shadow.Virtual.Visualize.LightName [light name] |
ライトを名前で指定 (部分一致または完全一致のどちらでも使用可能) します。 |
ビジュアライゼーション モードを有効にすると、仮想シャドウ マップのパフォーマンスに軽微ではあるものの、無視できない影響が出ます。パフォーマンス プロファイリングの前には、必ずビジュアライゼーションを無効にしてください。
キャッシュ
前のフレームのシャドウ マップを再利用することは、仮想シャドウ マップで高いパフォーマンスを維持するために重要であり、複雑なシーンでは特に重要です。キャッシュはデフォルトで有効になっていますが、デバッグを行うために、コンソール変数 r.Shadow.Virtual.Cache 0
を使用して無効にすることもできます。仮想シャドウ マップは、キャッシュが有効になっている場合、Nanite のカリング距離を考慮します。
ページは画面上のピクセルに対してのみレンダリングされるので、オクルージョン解除の動作によってカメラの可視性が変化すると、レンダリングする必要がある新しいページが見えるようになることがあります。通常は、カメラの動きが比較的滑らかであれば、それが主な原因で新しいページが見えるようになることはありません。一方、非常に迅速に動く近くのオブジェクト、広範囲のオクルージョン解除、カメラ カットには注意する必要があります。
ほとんどのシーンでは、シーンのジオメトリの変更に起因する再描画が必要なシャドウ マップ ページによって、大きな作業が生じます。キャッシュ ページの無効化の一般的な原因には、次のものがあります。
- ライトの移動や回転は、そのライトのすべてのキャッシュされたページを無効にします。
- シャドウをキャストするジオメトリが移動したり、シーンに追加または削除されたりすると、ライトの視点からそのバウンディング ボックスに重なるすべてのページが無効になります。
- これには、実際に移動していなくてもレンダリング状態の無効化をトリガーするプリミティブ コンポーネントでプロパティを設定するブループリントなどのオブジェクトが含まれることがあります。
- ワールド位置オフセット (WPO) またはピクセル深度オフセット (PDO) など、メッシュの位置を変更する可能性があるマテリアルを使用したジオメトリ。
ライトをゆっくり動かす場合や、時刻に合わせてディレクショナル ライトを変化させる場合は、VSM ページは実質的にはまったくキャッシュされません。時刻の変化のような場合、方向のわずかな違いは目立たないので、キャッシュされたページが数フレームの間存続できるように、少量ごとに変化を量子化することをお勧めします。
今後のリリースでは、キャッシュを向上させる必要があります。このためには、優先システムおよびフレームごとの更新バジェットを追加することによって、シャドウのレンダリングの負荷をより細かく制御できるようにします。これには、更新が必要なページがあまりにも多い場合、シャドウの解像度を一時的に下げることができる機能などが含まれます。
キャッシュの無効化を管理する
キャッシュの無効化を減らす最善の方法は、まず無効化を視覚化し、次に無効化を引き起こしている要素を見つけて、削減することです。まず、キャッシュ ページのビジュアライゼーション から始めることをお勧めします。

キャッシュ ページのビジュアライゼーション
このビジュアライゼーションでは、完全にキャッシュされているページが 緑色 でシェーディングされます。新しいページや無効になったページは、赤色 でシェーディングされます。カメラを動かすと、画面のエッジ、クリップマップの境界、オクルードを解除されたジオメトリの付近に小さなリングや赤色が表示されます。固定カメラでは、新しいページのほとんどはキャッシュの無効化によって生じます。
個別の静的キャッシュが有効な場合 (以下参照)、部分的にキャッシュされたページ (静的な部分のみが有効) は 青色 として表示されます。
問題のある領域が見つかったら、コンソール変数 r.Shadow.Virtual.Cache.DrawInvalidatingBounds 1
を使用して、無効化の原因となっているオブジェクト境界のビジュアライゼーションを有効にすると、多くの場合、さらに役立ちます。これらのオブジェクトと境界を調査し、それらが本当にシャドウを無効化すると想定されるオブジェクトであり、その境界が可能な限り緊密であることを確認します。無効化するオブジェクトがその境界内で重なる可能性のあるすべてのページを無効化する必要があるため、適度に拡張された境界と低い光角の組み合わせでさえ、多くの不要な無効化を引き起こす可能性があります。

キャッシュ ページと無効化する境界のビジュアライゼーション
Nanite オブジェクトのシャドウに完全に含まれている無効化は省略可能であるものの、Nanite 以外のオブジェクトの場合は無効化を省略できません。このため、建物などの大きなシャドウをキャストするオブジェクトでは、Nanite を使用することが特に重要です。
コンソール変数 r.Nanite.VSMInvalidateOnLODDelta
を使用すると、Nanite LOD ストリーミングの変更時に仮想シャドウ マップの無効化をトリガーすることができます。計算された Nanite LOD の推定値に一致する LOD にストリーミングされなかったクラスタは、ストリーミングが完了したときに再レンダリングされるように、VSM の無効化をトリガーします。これは、実験的機能です。プロジェクトを実験的機能を搭載してシッピングしないことをお勧めします。この機能は、変更される可能性があるためです。
複雑なシーンでは、このようなビジュアライゼーションを使用しても、無効化を引き起こす要因の特定が困難な場合があります。また、レベル ビューポートの [Show (表示)] > [Visualize (視覚化)] にある [Draw Only Geometry Causing VSM Invalidation (VSM の無効化を引き起こすジオメトリのみを描画する)] ビジュアライゼーション モードも役立つ可能性があります。

このモードを有効にすると、キャッシュの無効化を引き起こしていないジオメトリはすべて非表示になります。
実装の詳細により、Draw Only Geometry Causing VSM Invalidation モードでは、パーティクルや視覚効果など、シャドウイングに関係しないオブジェクトが表示されることがありますが、これらは別のレンダリング パスで実行され、上に描画されます。
メイン シーンのレンダリングが異なると、マッピングされ無効化されるページが異なるため、このビジュアライゼーションを使用している際の統計情報は信頼性の高い情報ではありません。まず、他の ビジュアライゼーション モード を使用して、念のため、このモードを使用することをお勧めします。
シーン キャプチャ コンポーネント には、キャッシュ全体が無効になる可能性のある既知の問題があります。
プリミティブごとの列挙クラス Shadow Cache Invalidation Behavior を使用して、シャドウを無効化するデフォルトのエンジン動作をオーバーライドできます。これは、静的なワールド位置オフセット (WPO) による無効化を防止するのに役立ちます。オプションには以下のものがあります。
- Auto (自動):(デフォルト) ワールド位置オフセット マテリアルに基づいて無効化を実行し、トランスフォームが変化します。
- Always (常時):常にシャドウを無効化します。これは、システムにとって既知でないアニメートの方法を使用しているプリミティブにフラグを立てるために使用できます。
- Rigid (リジッド):ワールド位置オフセットなど、これ以外の設定であれば生成される無効化を抑制します。
- Static (スタティック):Rigid (リジッド) の動作に加えて、トランスフォームの変更による無効化も抑制します。追加/削除は引き続き無効化をトリガーします。プリミティブが移動またはアニメートされた場合、ビジュアルの結果は未定義になります。
Nanite 以外の変形とフォリッジ
スケルタル アニメーションを使用して変形できるジオメトリ、またはワールド位置オフセットやピクセル深度オフセットを使用するマテリアルは、常にフレームごとにキャッシュ ページを無効化します。定義上、こういった場合も Nanite 以外を使用する必要がありますが、負荷が非常に大きいため、これらの機能を慎重に使用し、境界を制御することがきわめて重要です。
草、場合によってはフォリッジなどのケースでは、コンタクト シャドウ のみを使用することで、十分、高解像度シャドウ マップの代わりになります。前景に詳細度の高いシャドウが必要な場合は、パフォーマンスの負荷を軽減するために、次の点を考慮してください。
- Nanite 以外のオブジェクトは、引き続き、通常のシャドウ CPU カリング設定 (
r.Shadow.RadiusThreshold
など) を順守します。この設定を使用して、これらのオブジェクトを仮想シャドウ マップにレンダリングする際のコストを制御します。 - フォリッジをたくさん含むシーンでは、
r.Shadow.Virtual.NonNanite.IncludeInCoarsePages 0
を使用して、粗いページの Nanite 以外のオブジェクトを無効にすることを強くお勧めします。または、必要ない場合は、粗いページを完全に無効にする ことも検討してください。 - メッシュ LOD を使用して、効果が明らかではなくなる距離で WPO/PDO を使用しないマテリアルに切り替えます。場合によっては、遠方にあるこれらのオブジェクトの動的シャドウ キャストをオフにして、スクリーン空間のコンタクト シャドウを全体的に活用できることもあります。
ディレクショナル ライトでは、その他次のオプションを使用することができます。
- ライトの [Cascaded Shadow Maps (カスケード シャドウ マップ)] セクションで設定された Dynamic Shadow Distance Movable Light 距離を超える範囲にある Nanite 以外のジオメトリには、ディスタンス フィールド シャドウが適用されます。このジオメトリには Nanite が提供する細かい LOD スケーリングがないため、遠方の非 Nanite をディスタンス フィールド シャドウに切り替えると、パフォーマンスを大幅に向上できます。
-
WPO/PDO を除去するマテリアル LOD の作成が実用的ではない場合もありますが、これらの変換の最終的な影響は遠方では小さくなります。
r.Shadow.Virtual.Cache.MaxMaterialPositionInvalidationRange
を使用して、これらのマテリアルからのキャッシュの無効化が無視される距離 (cm 単位) を設定します。これによって、動きが大きい場合に、シャドウが「スミア」になることや、オブジェクトが誤ってセルフシャドウになることがあります。ただし、多くの場合、そのアーティファクトはパフォーマンスと利便性に対する妥当なトレードオフです。
個別のスタティック キャッシュ
この機能は 実験段階 と見なされています。
多くのシーンは、動くことのない大量の静的ジオメトリと、大幅に数の少ない動的 (または可動) ジオメトリで構成されています。つまり、デフォルトでは、比較的負荷の低い動的ジオメトリがページを無効化するため、動的な部分を更新するためだけに、負荷の高い静的ジオメトリを再レンダリングすることになります。
このような場合により適切に最適化するため、r.Shadow.Virtual.Cache.StaticSeparate 1
を使用して、オプションの [Separate Static Caching (個別のスタティック キャッシュ)] モードを有効にすることができます。このモードでは、物理ページ プールのサイズが 2 倍になり、特定のページ内の静的ジオメトリを動的ジオメトリとは個別にキャッシュすることができます。動的ジオメトリが移動しても、静的ジオメトリを再描画する必要がありません。その代わりに、キャッシュ済みの静的ページを低い負荷でその上で合成することができます。「古代の谷」サンプル プロジェクトなどの場合は、静的なテレインは非常に負荷が高い一方で、動的要素は比較的負荷が低いため、この方法を使用することで大幅にパフォーマンスが最適化されることがあります。
このモードを使用する際には、シーンの アクタの可動性 を正確に設定することが重要です。特に、アクタの [Mobility (可動性)] が [Static (スタティック)] に設定されている場合、またはワールド位置オフセットに対応しているマテリアルや、同様に対応していないマテリアルを使用した場合でも、動的および静的の両方のキャッシュ ページが無効になり、結果としてオーバーヘッドが発生してメリットが何もありません。反対に、非常に多くの負荷の高いジオメトリの [Mobility] が [Movable (ムーバブル)] に設定されている場合、ジオメトリを個別にキャッシュするメリットはほとんどない可能性があります。
仮想シャドウ マップ統計情報は、静的キャッシュがどの程度適切に機能しているかの概要を把握することに役立ちます。特に、「無効化」された静的ページの数は 0 に近くなっている必要があります。静的キャッシュを頻繁に無効化しているインスタンスを特定してそれらを [Movable] に切り替えることは、静的キャッシュを有効に保つことができる重要な方法です。
Nanite には、ワールド内のオブジェクトの可動性を判断するうえで役立つ高度なビジュアライゼーション モードがあります。このモードは、仮想シャドウ マップでも役立ちます。

Nanite の高度な仮想シャドウ マップの静的ビジュアライゼーション モード
このビジュアライゼーション モードは、次のどちらかの方法で有効にすることができます。
-
r.Nanite.Visualize.Advanced 1
で Nanite の高度なビジュアライゼーション オプションを有効にしてから、レベル ビューポートで [View Mode] > [Nanite Visualization (Nanite ビジュアライゼーション)] を選択し、ビジュアライゼーション オプションのリストから [Virtual Shadow Map Static (仮想シャドウ マップの静的)] を選択します。画像をクリックすると、拡大表示されます。
-
または、
r.Nanite.Visualize vsmstatic
コマンドを使用して、仮想シャドウ マップの静的ビジュアライゼーションを有効にすることもできます。
GPU のプロファイリングと最適化
Unreal Engine には、プロジェクトでのパフォーマンスをチェックするのに役立つツールが準備されており、GPU プロファイラ (またはプラットフォーム特有のツール) は、パフォーマンスに関する問題のトラブルシューティングおよびデバッグの出発点として適しています。
VSM の負荷が表示される主なパフォーマンス バケットには、Shadow Depths と Shadow Projection (Lights の下) の 2 つがあります。それぞれのカテゴリのトレードオフは、相互にほとんど無関係です。
統計情報の出力に使用されるコマンド (stat gpu など) およびそれに関連付けられているカウンターのタイミングは、プロジェクトのパフォーマンスが CPU にバインドされている場合は特に、信頼できないことに注意してください。
シャドウ深度
ShadowDepths カテゴリは、シャドウ マップへのジオメトリのレンダリングのコストを示しています。

- RenderVirtualShadowMaps(Nanite) には、VSM への Nanite ジオメトリのすべてのレンダリングが含まれています。すべてのディレクショナル ライトは単一の Nanite パスでレンダリングされ、すべてのローカル ライトは 2 番目のパスでレンダリングされています。
- RenderVirtualShadowMaps(Non-Nanite) では、Nanite 以外のジオメトリのレンダリングが処理されています。従来のシャドウ マップのレンダリングと同様に、それぞれの可視ライトには、さまざまなオブジェクトとインスタンスに対して個別のドロー コールを使用する個別のパスがあります。
- Atlas と Cubemap は、VSM のパスの後に続く他の類似したパスと一緒に、従来のシャドウ マップでレンダリングされています。仮想シャドウ マップのパスでまだサポートされていない少数のジオメトリ タイプがあり、それらが旧式のパスの後に続いています。サポートされていないジオメトリ キャスト シャドウがない場合、これらのパスはシャドウマップ ストレージの実行または割り当てを行いません。これらのパスおよび関連付けられているオーバーヘッドは、cvar
r.Shadow.Virtual.ForceOnlyVirtualShadowMaps 1
で完全に無効にすることができます。この場合、サポートされていないジオメトリ タイプは単にシャドウをキャストしません。
VSM による ShadowDepths のパスのコストは、レンダリングする必要があるシャドウ ページの数、およびそこにレンダリングする必要があるジオメトリの量に直接関係しています。Nanite 以外のジオメトリの VSM へのレンダリングは、Nanite ジオメトリよりもはるかに負荷が高くなります。このため、ローポリ メッシュを含む、サポートされているすべてのジオメトリで Nanite を有効にすることをお勧めします。 ただし、Nanite 仮想化ジオメトリ でまだサポートされていない機能では、Nanite を有効にしないでください。
描画されるページ数を把握する
使用される VSM ページに対する画面上の統計情報によって、使用されているページ数、および考えられる問題を解決するためにどこに注目すべきかが示されます。
統計情報を有効にするには、以下のコンソール変数を続けて使用します。
r.ShaderPrintEnable 1
r.Shadow.Virtual.ShowStats 1
(または 2 は統計のみを示します)

統計情報名 | 説明 |
---|---|
Physical Pages | 仮想シャドウ マップで使用できる最大物理ページ数。 |
Allocated | 現在のビューで要求されたシャドウ マップ ページの総数。この値は常に最大ページより少ない必要があります。そうでない場合、破損が生じる恐れがあります(後述の「問題と制限事項」セクションを参照してください。) |
Cleared | 現在のフレームで消去されたページ数。 |
Cached | 仮想シャドウ マップのページ キャッシュにすでに存在しているために、現在のフレームでレンダリングが不要であるページの数。キャッシュ済みのページは非常に低コストであり、パフォーマンスにはほとんど影響しません。個別の静的キャッシュが有効な場合、これはさらにキャッシュされた静的ページとキャッシュされた動的ページで分割されます。 |
Invalidated | 直前のフレームで動的ジオメトリによって無効化されたキャッシュ ページの数。これらのページをカバーしている要素が移動したため、これらのページを再レンダリングする必要があります。個別の静的キャッシュを使用している場合、静的ページの無効化数はゼロか、ゼロに非常に近い状態にするのが理想的です。大量の静的ページが無効化されている場合、無効化を引き起こしているアクタを [Movable] に切り替える必要があります。 |
Merged | 個別の静的キャッシュが有効な場合、これは動的ページと静的ページがマージされたページ数です (どちらかがキャッシュされなかったため)。 |
総ページ数は、画面上の各ピクセルに影響を及ぼすライトの数に応じて決まります。画面の解像度、シャドウの解像度 (解像度の LOD バイアスのコンソール変数を使用)、ライトの範囲、またはライトをキャストするシャドウの数を減らすことによって、総ページ数を減らすことができます。
シャドウ深度でのパフォーマンス低下は通常、使用されているページ数が多いことや動的無効化が多数発生しているために、VSM のキャッシュが十分に機能していないことが原因です。キャッシュの無効化の診断と削減の詳細については、「キャッシュ」セクションを参照してください。
Nanite 以外のパフォーマンスを改善する
キャッシュの改善以外にも、Nanite 以外のシャドウレンダリングのパフォーマンスを向上させる方法がいくつかあります。
Nanite 以外のオブジェクトのパフォーマンスを向上させるために、以下について検討してください。
- プロジェクトでできる限り多くのジオメトリで Nanite を有効にします。
- Nanite ジオメトリは、はるかに効率的に仮想シャドウ マップにレンダリングされるため、ポリゴン数にかかわらず、該当するすべてのケースで優先して使用する必要があります。
- Nanite ジオメトリは Nanite 以外のジオメトリをオクルードし、正しくないキャッシュの無効化を回避することができます。そのため、Nanite 以外のオブジェクトを使用するのは、変形オブジェクト (スキン メッシュ)、ワールド位置オフセット (WPO) およびピクセル深度オフセット (PDO) を使用するマテリアルなど、Nanite 自体がサポートしていない要素の場合のみにする必要があります。
- Nanite 以外のオブジェクトには、完全なメッシュ LOD 階層を設定する必要があります。
- Nanite 以外のメッシュには LOD を設定することが重要です。LOD を設定しない場合、小さなページにレンダリングするだけでもきわめて大きな負荷がかかります。
- 可能な場合、効果が明らかな距離を超える範囲では、非変形メッシュ (WPO/PDO マテリアルなし) に変更することをお勧めします。
- CPU カリング コンソール変数は、仮想シャドウ マップにレンダリングする Nanite 以外のメッシュでは引き続き有効です。
- 仮想シャドウ マップにレンダリングされる Nanite 以外のオブジェクトの CPU カリングの値をコンソール変数
r.Shadow.RadiusThreshold
を使用して調整します。遠くの小さなオブジェクトの負荷を制御するうえで役立ちます。
- 仮想シャドウ マップにレンダリングされる Nanite 以外のオブジェクトの CPU カリングの値をコンソール変数
- Nanite 以外のオブジェクトの遠方のシャドウイングに ディスタンス フィールド シャドウ を使用する
- ディレクショナル ライトでは、多くの場合、カスケード シャドウ マップと同様に、特定の範囲を超えた場所ではディスタンス フィールド シャドウに切り替える必要があります。仮想シャドウ マップでは、Nanite 以外のジオメトリのみがディスタンス フィールド シャドウの使用に切り替わりますが、Nanite ジオメトリでは引き続き完全な詳細度のシャドウが使用されます。
- 粗いページでは Nanite 以外のジオメトリを無効にすると、パフォーマンスが向上します。
- 粗いページで Nanite 以外のジオメトリを無効にすると、パフォーマンスが大幅に向上する可能性があります。これは、Nanite 以外のジオメトリは、通常、大きなページへのレンダリングが非効率的であるためです。
仮想シャドウ マップの統計情報から、Nanite 以外のインスタンス数を把握することができます。

統計情報名 | 説明 |
---|---|
Total | GPU カリングに入力される Nanite 以外のインスタンスの総数。インスタンスは、仮想シャドウ マップのミップ/クリップマップ レベルごとに個別にカリングされます。たとえば、1 つのスタティックメッシュ インスタンスは、交差するポイント ライトごとに 48 インスタンス (8 ミップ レベル * 6 キューブマップ面) となり、各ディレクショナル ライトごとに 17 インスタンス (デフォルト設定では 17 クリップマップ レベルがある) になります。 |
Drawn | カリング後のすべての仮想シャドウ マップに実際に描画されたインスタンスの数。 |
HZB Culled | ライトの視点から見て、(Nanite ジオメトリによって) オクルードされたために削除されたインスタンスの数。 |
Page Mask Culled | 必要なページと重なっていないために削除されたインスタンスの数。これは、たとえば、すでにキャッシュされた領域に描画する際に破棄されるスタティックメッシュを表します。 |
Empty Rect Culled | 必要なページと重なっていないために削除されたインスタンスの数。これは、たとえば、キャッシュ済みの領域に描画する際に破棄されるスタティックメッシュ数を表します。 |
Frustum Culled | ビュー視錐台外にあったインスタンスの数。 |
シャドウの投影
Shadow Projection カテゴリは、シャドウ マップ レイ トレーシングを使用したシャドウ マップのサンプリングの負荷を表しています。これらのパスは、Lights | DirectLighting | UnbatchedLights にあり、通常、関連付けられているライトごとに 1 つの VSM 投影パスになっています。通常最もコストが大きいパスは、VirtualShadowMapProjection にある SMRT のメイン ループです。それ以外は比較的低コストです。
投影パスに RayCount:Adaptive ではなく、RayCount:Static というラベルが付いている場合、低速パスが使用されています。
このセクションで説明している VSM 投影パスは、次のセクションで説明している実験段階のワンパス投影とは異なります。

シャドウ投影は、シーン全体で取得されるシャドウ マップのサンプル総数の純粋な関数であり、パフォーマンスはページ数や行われるキャッシュには依存しません。
SMRT が使用されている場合、次のようになります。
- Average lights per pixel
- 画面の大部分に届いているライトが多いほど、レンダリングのコストが大きくなります。カバーしている画面上のピクセルが少ないライトほどコストは低くなりますが、それでもライトあたりの固定コストがある程度発生します。
- 複数の大きいライトによって画面上の大多数のピクセルが占められないように配慮する必要があります。
- Rays per pixel
- シャドウの可視ソフトネスは、適応レイ数に応じて、パフォーマンスに影響を及ぼします。レイ数やサンプル数を減らす前に、ローカル ライトの [Source Radius] またはディレクショナル ライトの [Source Angle] を小さくしてみます。
- Samples per ray
これらの設定は、Shadow スケーラビリティ設定によって設定されますが、必要に応じてさらに調整できます。詳細については、このページの「シャドウ マップ レイ トレーシング」セクションを参照してください。
通常、シャドウ投影の負荷は、シャドウ深度の負荷よりもはるかに簡単に制御できます (品質やノイズとのトレードオフになる)。
ワンパス投影
この機能は実験段階と見なされています。このセクションのコンソール変数名は、変更される可能性があります。
ライトが小さいほどコストは低くなりますが、それでもある程度の固定パス オーバーヘッドがあります。それには、シーン内の大多数のローカル ライトでシャドウイングをワンパスで効率的に評価できる、単一のパスのシャドウ投影ソリューションを開発することによって対処できます。そのようなライトからのシャドウイングへの寄与を、クラスタ シェーディングを使用して一度ですべて適用することができます。
このパスは、コンソール変数 r.UseClusteredDeferredShading 1
および r.Shadow.Virtual.OnePassProjection 1
を使用して有効化することができます。小さいローカル ライトが多数あるシーンでは、これを使用するとパフォーマンスが大幅に向上することがあります。
次のような特定のライト機能を使用すると、ワンパス投影が有効な場合でも、ライトはバッチ処理されません。
- テクスチャ プロファイル
- ライト ファンクション
- ライティング チャンネル
- 矩形ライト
- ディレクショナル ライト (全画面をカバーするため、これらをバッチ処理するメリットはない)
次の画面キャプチャでは、右側のワンパス投影と対比して、ライトごとに発生するシャドウ投影のパスが左側に示されています。
画像をクリックすると、拡大表示されます。
左のデフォルトのパスでは、各ローカル ライトが、ライトごとの複数のパスを使用して 1 つずつ蓄積されます。これは、小さな画面領域をカバーする小さなライトでは非効率的です。
右の新しいパスでは、シャドウイング ローカル ライトはすべて、単一のクラスタ化シェーディング パスで一括処理されます (BatchedLights)。ディレクショナル ライトは引き続き単一の個別のパスで実行されます。ディレクショナル ライトは画面全体をカバーするため、バッチ処理を行うメリットはありません。
各ローカル ライトは、引き続き別々に半透明ボリュームに挿入されます。ローカル ライトは、投影よりもパフォーマンス上の問題は少ないものの、将来的にはまとめてバッチ処理される可能性があります。
ワンパス投影を有効にすると、デフォルトの 16 から r.Shadow.Virtual.OnePassProjection.MaxLightsPerPixel
を調整することで、ピクセルごとに完全にフィルタリングされるシャドウ付きのライトの数を制限することができます。これは、パフォーマンスを制御するためと、一時的なグラフィック メモリを少し節約するうえで役立ちます。
所定のピクセル (あるいは、実際には、クラスタ化されたディファード シェーディング タイル) で最大ライトよりも多くのシャドウイング ライトがある場合、追加のライトは、負荷の低い単一のハード シャドウルックアップを使用してシャドウイングされます。これが過度な値に設定されると、視覚的に連続性が失われる可能性があるものの、一般的には、この数を上回るライトのシャドウを完全に無効にするよりも許容できます。
このパスは、引き続き開発中であり、デフォルトでは有効になっていません。主な注意点は、ローカル ライトが仮想シャドウ マップと従来のシャドウ マップの両方を含む場合 (シーンでサポートされていないジオメトリ タイプのため)、ワンパス投影パスは従来のシャドウ マップは無視され、表示されません。
すでに r.Shadow.Virtual.ForceOnlyVirtualShadowMaps
を使用している場合は、ワンパス投影も有効にしてください。現在の制限事項が解消されれば、これが使用されるデフォルト パスになります。
対応プラットフォーム
仮想シャドウ マップは現在、PlayStation 5、Xbox Series S|X、そして DirectX 12 の最新ドライバーを使用する、次の仕様を満たすグラフィック カードを搭載した PC でサポートされています。
- NVIDIA:Maxwell 世代以降のカード
- AMD:GCN 世代以降のカード
- Windows 10 のすべての新しいバージョン (バージョン 1909.1350 以降) および DirectX 12 Agility SDK をサポートする Windows 11。
- Windows 10 バージョン 1909 — リビジョン番号は .1350 以降である必要があります。
- Windows 10 バージョン 2004 および 20H2 — リビジョン番号は .789 以降である必要があります。
- DirectX 12 (Shader Model 6.6 atomics) または Vulkan (VK_KHR_shader_atomic_int64)
- 最新のグラフィック ドライバー
問題と制限事項
仮想シャドウ マップは引き続き積極的に開発中です。早期アクセス版の使用に関していくつかの既知の問題および制限事項があり、現時点ではハイエンドのデスクトップおよび次世代コンソールを対象としています。
複数のライトのパフォーマンス
小さなローカル ライトを多く含むシーンでのパフォーマンス向上については、引き続き取り組んでいます。当面、最良の戦略は、ワンパス投影を有効化 し、無効化に特に注意を払い、できるだけ多くのページをキャッシュしておくことです。複数のローカル ライトは、Nanite 以外のジオメトリよりも Nanite ジオメトリではるかに優れたパフォーマンスを発揮するため、遠方の Nanite 以外のジオメトリのシャドウ キャストを積極的にカリングまたは無効にすると、多くのメリットが得られます。場合によっては、遠方のライトの動的シャドウ キャストを完全に無効にして、スクリーン空間の コンタクト シャドウ のみを活用する方が望ましいこともあります。
将来的には、アルゴリズムと品質のトレードオフを実現するため、そしてこのような状況での更新を調整するためのより適切なコントロールを使用できるようになります。
ローポリ ジオメトリ
曲率が高く、法線が滑らかなローポリ ジオメトリでは、アーティファクトが発生することがあります。これは、「シャドウ ターミネーター問題」として知られており、レイ トレーシングや他の精度の高い可視性クエリでも発生します。この問題は、実際のローポリ ジオメトリと「滑らかな」シェーディング法線との間のミスマッチに起因します。ターミネーター付近の領域では、これらの面の一部はシャドウが幾何学的になっていますが、非幾何学的シェーディング法線はわずかにライトの方に向いています。このアーティファクトには、通常、シャドウ ルックアップに対する法線ベースのバイアスによって対処します。この特定のアーティファクトは、仮想シャドウ マップでより顕著になる可能性があります。これは、仮想シャドウ マップは、デフォルトで、Nanite ジオメトリからの高度に詳細なシャドウを提供するように設定されているためです。
この問題に対処する最善の方法は、これらのオブジェクト/領域のポリゴン数を増やすことです。ジオメトリ法線とシェーディング法線の間の発散を制限することで、他の部分のシャドウの品質にマイナスの影響を及ぼすことなく、これらのアーティファクトを低減または除去することができます。Nanite を使用すると、ポリゴン数を簡単に増やすことができ、負荷も抑えることができます。問題のあるオブジェクトが Nanite を使用できない場合は、より高い詳細度 (LOD) を追加すると、多くの場合、うまく機能します。これらのアーティファクトは、オブジェクトがカメラの近くにあるときは、大抵表示されるためです。
ジオメトリを追加できない場合は、r.Shadow.Virtual.NormalBias
を使用して、仮想シャドウ マップ法線バイアスを増やすことができます (デフォルト 0.5)。なお。この方法は、コンテンツの調整ができない場合に限り検討してください。なぜなら、この方法はシーン全体のシャドウの品質にマイナスの影響を及ぼし、特に細かいディテールの領域に影響するためです。
以下の例では、カメラの近くのロー ポリゴンの球体と背景の詳細度の高いジオメトリでアーティファクトが生じています。球体にポリゴンを追加することで、背景の詳細なランドスケープにマイナスの影響を及ぼすことなく、アーティファクトを改善することができます。


バイアスを調整すると、アーティファクトも改善されますが、背景のジオメトリの細かいディテールが明らかに失われます。


VR (バーチャル リアリティ)
仮想シャドウ マップは、まだ VR に完全には対応していません。右目のディレクショナル ライトでアーティファクトが発生する可能性があります。
分割画面
分割画面は最小限のテストしか実施されていないため、パフォーマンスが十分でない可能性があります。
物理ページ プールのオーバーフロー
仮想シャドウ マップでは、すべてのライトのシーン内のすべてのシャドウ データは、単一の大きなテクスチャ プールに格納されます。デフォルトのプール サイズは、Shadow スケーラビリティ設定によって制御されるものの、高解像度のシャドウを使用する多くのライトを含むシーンでは調整が必要な場合があります。
また、ビデオ メモリを節約するために、ローエンドのハードウェアでは調整が必要になる場合もあります。
ページ プール サイズは、r.Shadow.Virtual.MaxPhysicalPages
を使用して調整することができます。r.ShaderPrintEnable 1
と r.Shadow.Virtual.ShowStats 2
を連続して使用して仮想シャドウ マップの統計情報を有効にすると、現在のページ プールの使用に関する統計情報が表示されます。

仮想シャドウ マップの画面上の統計情報の現在のページ プールの使用状況の例。
Pages が Max Pages を超えると、破損が発生し、場合によっては、チェッカーボード パターンや破損したシャドウ、欠落したシャドウとして表示されることがあります。シャドウ ページ プールがオーバーフローした場合、画面とログに警告が表示されます。

ページ プールのページ数超過による仮想シャドウ マップの破損の例。
この問題が発生した場合は、ページ プールのサイズを大きくするか、シャドウの解像度または仮想シャドウ マップがキャストするライトの数を減らしてください。
シーン キャプチャ
場合によっては、シーン キャプチャ コンポーネントにより、仮想シャドウ マップ キャッシュ全体が無効になることがあります。この症状は通常、仮想シャドウ マップの統計で Invalidations が低いこととして現れますが、キャッシュされたページも低く (場合によってはゼロ)、キャッシュされたページのビジュアライゼーションは均一に赤くなります。
これが発生した場合は、シーン内のシーン キャプチャ アクタを非表示/削除して、問題の原因であるかどうかを確認してください。
現在、これが発生したときにシーン キャプチャを無効にする以外の回避策はありません。
マテリアル
シンプルなサブサーフェス マテリアルのみがサポートされています。サブサーフェス プロファイルとトランスミッションはまだ実装されていません。マテリアルでそれらが使用されていると、そのマテリアルは不透明であるかのようにシャドウイングされます。
シャドウの解像度
仮想シャドウ マップでは従来のシャドウ マップと比べて解像度が大幅に向上しますが、ライト角度が緩やか (または投影エイリアス) で非常に大きなローカル ライトによって、利用可能な仮想解像度が使い尽くされることがあります。その場合は、ジオメトリのサーフェスに応じて、箱状のシャドウやバイアスの問題が生じることがあります。
ディレクショナル ライトのクリップマップは、解像度の不足の影響をそれほど受けませんが、カメラの視野角が非常に狭い場合は、最終的に仮想解像度が使い尽くされることもあります。
シャドウ マップによる投影エイリアスを解消するための単純な解決方法はありません。仮想シャドウ マップを使用していても、最悪の状況を回避するために何らかの対処を行い、解像度とパフォーマンスのバランスを取る必要があります。
[Map Check (マップをチェック)] の警告
仮想シャドウ マップを使用している場合に、[Map Check (マップをチェック)] で次のような不正確な警告が表示されることがあります。
- Lumen の動的グローバル イルミネーションおよび反射 の機能を使用していない場合に実際は再ビルドが必要であっても、仮想シャドウ マップが有効である場合は、[Lighting needs to be rebuilt (ライティングの再ビルドが必要です)] というメッセージが表示されません。固定のディレクショナル ライトが仮想シャドウ マップを有効にして動的であっても、固定の間接ライティングはベイク処理のままです。
- プレシャドウ に関する警告は、仮想シャドウ マップの使用時には無関係であるため無視しても構いません。