URP のディファードレンダリングパス
URP ユニバーサルレンダラーは、フォワードレンダリングパスとディファードレンダリングパスの 2 つのレンダリングパスをサポートしています。
レンダリングパスの違いの詳細については、レンダリングパスの比較 のセクションを参照してください。
このセクションでは、ディファードレンダリングパスについて説明します。
ディファードレンダリングパスを使用してレンダリングしたシーンの例。
このセクションには、以下のトピックが含まれています。
ディファードレンダリングパスの選択方法
レンダリングパスを選択するには、URP ユニバーサルレンダラーアセットのプロパティ Lighting > Rendering Path を使用します。
ディファードレンダリングパスを選択すると、Accurate G-buffer normals プロパティが表示されます。
Accurate G-buffer normals プロパティでは、法線をジオメトリバッファ (G-buffer) に格納する際のエンコード方法を設定できます。
Accurate G-buffer normals オフ: 特にモバイル GPU でパフォーマンスが向上しますが、滑らかなサーフェスでカラーバンディングアーティファクトが発生する可能性があります。
Accurate G-buffer normals オン: 八面体エンコーディングを使用して、法線テクスチャの RGB チャンネルに法線ベクトルの値を格納します。このエンコーディングでは、法線ベクトルの値がより正確なものになりますが、エンコーディングおよびデコーディング処理により、GPU の負荷が増加します。
この設定の詳細については、G-buffer での法線のエンコーディング セクションを参照してください。
Unity Player のシステム要件
ディファードレンダリングパスには、Unity Player の一般的なシステム要件に加え、以下の要件と制限事項があります。
シェーダーモデル: 4.5 以上。
ディファードレンダリングパスは、OpenGL ベースのグラフィックス API の Desktop OpenGL、OpenGL ES 2.0、OpenGL ES 3.0、WebGL 1.0、WebGL 2.0 をサポートしていません。
実装の詳細
このセクションでは、この機能の実装の詳細と、この機能の仕組みに関する技術的な詳細について説明します。
G-buffer のレイアウト
このセクションでは、Unity がディファードレンダリングパスの G-buffer にマテリアル属性を格納する方法について説明します。
以下の図は、Unity がディファードレンダリングパスで使用するレンダーターゲットの各ピクセルのデータ構造を示しています。
データ構造は以下の構成になっています。
Albedo (sRGB)
このフィールドには、sRGB 形式、24 ビットのアルベドカラーが含まれます。
MaterialFlags
このフィールドは、マテリアルのフラグを含むビットフィールドです。
ビット 1、ReceiveShadowsOff: 設定されている場合、そのピクセルは動的シャドウを受けません。
ビット 2、SpecularHighlightsOff: 設定されている場合、そのピクセルはスペキュラーハイライトを受けません。
ビット 4、SubtractiveMixedLighting: 設定されている場合、そのピクセルは減法ミックスドライティングを使用します。
ビット 8、SpecularSetup: 設定されている場合、そのマテリアルはスペキュラーワークフローを使用します。
技術的な詳細については、/ShaderLibrary/UnityGBuffer.hlsl
ファイルを参照してください。
Specular
このフィールドには、以下の値が含まれます。
SimpleLit マテリアル: 24 ビットで格納された RGB スペキュラーカラー。
メタリックワークフローを使用する Lit マテリアル: 8 ビットで格納された反射率。16 ビットは使用されません。
スペキュラーワークフローを使用する Lit マテリアル: 24 ビットで格納された RGB スペキュラーカラー。
Occlusion
このフィールドには、ベイクしたライティングのベイクしたオクルージョンの値が含まれます。リアルタイムライティングの場合、ベイクしたオクルージョンの値と SSAO の値を組み合わせてアンビエントオクルージョンの値が計算されます。
Normal
このフィールドには、24 ビットでエンコードされたワールド空間の法線が含まれます。法線のエンコーディングについては、G-buffer での法線のエンコーディング のセクションを参照してください。
Smoothness
このフィールドには、SimpleLit マテリアルおよび Lit マテリアルの Smoothness の値が格納されます。
Emissive/GI/Lighting
このレンダーターゲットには、マテリアルのエミッシブ出力とベイクしたライティングが含まれます。このフィールドは、G-buffer パスの間に入力されます。ディファードシェーディングパスの間に、このレンダーターゲットにライティングの結果が格納されます。
レンダーターゲットの形式:
B10G11R11_UFloatPack32。ただし、以下の条件のいずれかが真である場合を除きます。
URP アセットの Quality > HDR の設定がオンになっていて、ターゲットのプレイヤープラットフォームが HDR をサポートしていない。
Player Settings の PreserveFramebufferAlpha の設定が true である。
R16G6B16A16_SFloat。プロジェクトの設定により、Unity が B10G11R11_UFloatPack32 を使用できない場合。
上記の形式のどちらも使用できない場合、
SystemInfo.GetGraphicsFormat(DefaultFormat.HDR)
メソッドの戻り値が使用されます。
Shadowmask
Lighting Mode が Subtractive または Shadowmask に設定されている場合、このレンダーターゲットが G-buffer レイアウトに追加されます。
Subtractive モードと Shadowmask モードはフォワードレンダリングパスに最適化されており、ディファードレンダリングパスでは効率が低下します。ディファードレンダリングパスでは、GPU パフォーマンスを高めるために、これらのモードの使用を避け、代わりに Baked Indirect モードを使用してください。
Rendering Layer Mask
ライトレイヤー機能が有効な場合 (URP アセット、Advanced > Light Layers)、このレンダーターゲットが G-buffer レイアウトに追加されます。ライトレイヤー機能を使用すると、GPU パフォーマンスに大きな影響が及ぶ可能性があります。詳細については、ライトレイヤー セクションを参照してください。
Depth as Color
サポートされるプラットフォームでネイティブレンダーパスが有効になっている場合、このレンダーターゲットが G-buffer レイアウトに追加されます。このレンダーターゲットには、深度が色としてレンダリングされます。このレンダーターゲットには、以下の目的があります。
Vulkan デバイスでのパフォーマンスを向上させること。
Metal API の深度バッファを Unity が取得できるようにすること。Metal API では、同じレンダーパス内で DepthStencil バッファから深度を取得することができません。
Depth as Color レンダーターゲットの形式は、GraphicsFormat.R32_SFloat
です。
DepthStencil
このレンダーターゲットの最上位 4 ビットは、マテリアルタイプをマークするために予約されています。URP のパスタグ: UniversalMaterialType も参照してください。
このレンダーターゲットについては、Unity はプラットフォームに応じて D32F_S8
形式か D24S8
形式のどちらかを選択します。
G-buffer での法線のエンコーディング
ディファードレンダリングパスでは、法線は G-buffer に格納されます。各法線は 24 ビット値としてエンコードされます。
URP ユニバーサルレンダラーアセットの Rendering Path プロパティで Deferred オプションを選択すると、Accurate G-buffer normals プロパティが表示されます。
Accurate G-buffer normals プロパティでは、法線のエンコード方法を設定できます。
Accurate G-buffer normals オフ: 法線ベクトルの値を、G-buffer の法線テクスチャの RGB チャンネルに、値 (x、y、z) あたり 8 ビットで格納します。値は、精度を損なうことなく量子化されます。特にモバイル GPU でパフォーマンスが向上しますが、滑らかなサーフェスでカラーバンディングアーティファクトが発生する可能性があります。
Accurate G-buffer normals オン: 八面体エンコーディングを使用して、法線テクスチャの RGB チャンネルに法線ベクトルの値を格納します。このエンコーディングでは、法線ベクトルの値がより正確なものになりますが、エンコーディングおよびデコーディング処理により、GPU の負荷が増加します。
エンコードされた法線ベクトルの精度は、フォワードレンダリングパスでサンプリングされた値の精度とほぼ同じです。
以下の図は、カメラがゲームオブジェクトの間近にあるときの 2 つのオプションの視覚的な違いを示しています。
パフォーマンス上の考慮事項
Accurate G-buffer normals オプションをオンにすると、エンコーディング処理およびデコーディング処理により、GPU の負荷が増加します。この負荷は、デスクトッププラットフォームやコンソールでは軽微なものですが、モバイル GPU ではかなりの負荷になる可能性があります。
このオプションをオンにしても、メモリフットプリントは増加しません。Unity は法線を格納するために、エンコーディングに関係なく、法線テクスチャの同じ RGB チャンネルを使用します。
ディファードレンダリングパスのレンダーパス
以下の表に、ディファードレンダリングパスにおけるレンダーパスイベントの順序を示します。
レンダーパスイベント | ディファードレンダリングパスのパス | SSAO Renderer Feature のパス |
---|---|---|
BeforeRendering | ||
BeforeRenderingShadows | ||
AfterRenderingShadows | ||
BeforeRenderingPrePasses | デプスプレパスまたはデプスおよび法線プレパス (フォワードオンリーマテリアル) | |
AfterRenderingPrePasses | ||
BeforeRenderingGbuffer | G-buffer パス (GBufferPass) | |
G-buffer 深度テクスチャのコピー | ||
AfterRenderingGbuffer | SSAO (任意) | |
BeforeRenderingDeferredLights | ||
ディファードレンダリング (ステンシル) | ||
AfterRenderingDeferredLights | ||
BeforeRenderingOpaques | 不透明なフォワードオンリーマテリアル | |
AfterRenderingOpaques | SSAO およびブレンディング (任意) | |
BeforeRenderingSkybox | ||
AfterRenderingSkybox | ||
BeforeRenderingTransparents | ||
AfterRenderingTransparents | ||
BeforeRenderingPostProcessing | ||
AfterRenderingPostProcessing | ||
AfterRendering |
以下のセクションでは、ディファードレンダリングパスのレンダーパスについて説明します。
デプスプレパスまたはデプスおよび法線プレパス
ディファードレンダリングパスのデプスプレパスまたはデプスおよび法線プレパスでは、ディファードレンダリングモデルをサポートしていないマテリアルのみがレンダリングされます。例えば、そうしたマテリアルには、Complex Lit シェーダーを使用するマテリアルがあります。
ディファードレンダリングパスでは、デプスプレパスを使用して深度バッファのコピーが生成されることはありません (この動作はフォワードレンダリングパスでは異なります)。
ユニバーサルレンダラーで SSAO Renderer Feature を使用する場合、デプスおよび法線プレパスが実行されます。SSAO は、スクリーンスペースの深度バッファと法線バッファを使用して、アンビエントオクルージョンを計算します。
任意のパス: SSAO、ブレンディングを使用した SSAO
ユニバーサルレンダラーで SSAO Renderer Feature を使用し、After Opaque オプションが無効な場合 (デフォルトでは無効)、AfterRenderingGbuffer イベントで SSAO パスが実行されます。SSAO Renderer Feature は、SSAO テクスチャを計算します。Unity は、ディファードレンダリングパスとフォワードオンリーパスでレンダリングされたマテリアルを、このテクスチャにサンプリングします。
このパス順序を使用すると、Unity はベイクしたオクルージョンと SSAO Renderer Feature のリアルタイムオクルージョンを組み合わせることができ、ベイクしたアンビエントオクルージョンとリアルタイムアンビエントオクルージョンによる二重の減光を回避できます。
After Opaque オプションが有効な場合、Unity はフォワードオンリーマテリアルをレンダリングした後、AfterRenderingOpaques イベントで SSAO とブレンディングパスを実行します。その後、SSAO テクスチャを Emissive/GI/Lighting バッファにオーバーレイするために、追加のフルスクリーンパスを実行します。これが原因で、ベイクしたオクルージョンとリアルタイムオクルージョンが反映される領域が暗くなりすぎることがあります。
パフォーマンス上の考慮事項
TBDR アーキテクチャを備えたモバイルプラットフォームで After Opaque オプションが無効な場合、ロード処理と格納処理のために追加のレンダーターゲットが必要になります。これは、パフォーマンスに大きな影響を与えます。
モバイルプラットフォームで After Opaque オプションを有効にすると、GPU パフォーマンスが向上します。TBDR アーキテクチャを備えたモバイルプラットフォームでこのオプションを有効にすると、追加のレンダーターゲットのロード処理と格納処理を回避できます。
フォワードオンリーパス
Unity のシェーダーの中には、ディファードレンダリングパスでレンダリングできないライティングモデルを使用するものがあります。
そのようなシェーダーの例を以下に示します。
Complex Lit: このシェーダーのライティングモデル (クリアコートエフェクトなど) は非常に複雑であり、追加のマテリアルプロパティを G-buffer に収めることができません。
Baked Lit および Unlit: これらのシェーダーはリアルタイムライティングを計算しないため、Unity はフォワードオンリーパスの間にこれらのシェーダーを Emissive/GI/Lighting バッファに直接レンダリングします。これは、ディファードレンダリング (ステンシル) パスでシェーダーを評価するよりも高速です。
カスタムシェーダー: Unity は、ディファードレンダリングパスが必要とするパスタグを宣言していないシェーダーをフォワードオンリーとしてレンダリングします。必要なパスタグは、
LightMode
とUniversalMaterialType
です。詳細については、URP のパスタグ を参照してください。
Unity は、このようなシェーダーを使用するマテリアルをフォワードレンダリングパスでレンダリングします。SSAO Renderer Feature で Complex Lit シェーダーを使用するマテリアルのアンビエントオクルージョンを計算できるようにするには、まずデプスおよび法線プレパスでそのようなマテリアルをレンダリングする必要があります。これは、そのようなマテリアルは G-buffer パス (GBufferPass) でレンダリングされないためです。詳細については、URP のパスタグ を参照してください。
実装に関する一般的な注記
プラットフォームの互換性を最大限に確保するために、URP のディファードレンダリングパスでは、ライトステンシルボリューム手法を使用してライトボリュームをレンダリングし、ディファードシェーディングを適用します。
関連するコードファイル
このセクションでは、ディファードレンダリングパスに関連するコードを含むファイルを紹介します。
ディファードレンダリングパスを処理するメインクラス:
com.unity.render-pipelines.universal\Runtime\DeferredLights.cs
G-Buffer パス用の ScriptableRenderPass:
com.unity.render-pipelines.universal\Runtime\Passes\GBufferPass.cs
ディファードシェーディングパス用の ScriptableRenderPass:
com.unity.render-pipelines.universal\Runtime\Passes\DeferredPass.cs
ディファードシェーディング用のシェーダーアセット:
com.unity.render-pipelines.universal\Shaders\Utils\StencilDeferred.shader
ディファードシェーディング用のユーティリティ関数:
com.unity.render-pipelines.universal\Shaders\Utils\Deferred.hlsl
G-buffer からマテリアルのプロパティを格納およびロードするためのユーティリティ関数:
com.unity.render-pipelines.universal\Shaders\Utils\UnityGBuffer.hlsl
ShaderLab のパスタグ
ディファードレンダリングパスでシェーダーをレンダリングできるようにするには、以下のタグ定義を持つパスをシェーダーに設定する必要があります。
"LightMode" = "UniversalGBuffer"
Unity は、G-buffer パスの間にこのような LightMode
タグを持つシェーダーを実行します。
ディファードレンダリングパスのフォワードオンリーパスで特定のマテリアルをレンダリングする必要があることを示すには、シェーダーパスに以下のタグを追加します。
"LightMode" = "UniversalForwardOnly"
"LightMode" = "DepthNormalsOnly"
シェーダーライティングモデル (Lit、SimpleLit) を指定するには、UniversalMaterialType
タグを使用します。
詳細については、URP のパスタグ: LightMode セクションを参照してください。
制約とパフォーマンス
このセクションでは、ディファードレンダリングパスの制約について説明します。
地形のブレンディング
5 つ以上のテレインレイヤーをブレンドする場合、ディファードレンダリングパスはフォワードレンダリングパスと若干異なる結果を生成します。このようなことが起こるのは、フォワードレンダリングパスでは、マルチパスレンダリングを使用して、最初の 4 つのレイヤーと次の 4 つのレイヤーを別々に処理するためです。
フォワードレンダリングパスでは、マテリアルのプロパティをマージし、4 つのレイヤーの結合されたプロパティに対してライティングを計算します。その後、次の 4 つのレイヤーを同じように処理し、ライティング結果をアルファブレンドにより生成します。
ディファードレンダリングパスでは、G-buffer パスでテレインレイヤーを一度に 4 つ結合し、ディファードレンダリングパスの間に一度だけライティングを計算します。このようなフォワードレンダリングパスとの違いは、視覚的に異なる結果 をもたらします。
Unity は、ハードウェアブレンディング (一度に 4 つのレイヤー) を使用して G-buffer 内のマテリアルのプロパティを結合します。これにより、プロパティ値の組み合わせの正確さが制限されます。例えば、ピクセル法線はアルファブレンド式だけでは正しく結合できません。テレインレイヤーには粗い地形のディテールが含まれるものもあれば、細かいディテールが含まれるものもあるからです。法線を平均化または合計すると、精度が失われます。
ノート: Accurate G-buffer normals 設定をオンにすると、地形のブレンディングが解除されます。この設定をオンにすると、Unity は法線を八面体エンコーディングでエンコードします。このエンコーディングはビット単位 (2 x 12 ビット) であるため、この方法でエンコードされた異なるレイヤーの法線は、一緒にブレンドすることができません。アプリケーションで 5 つ以上のテレインレイヤーが必要な場合は、Accurate G-buffer normals 設定をオフにしてください。
以下の画像は、テレインレイヤーを異なるレンダリングパスでレンダリングした場合の視覚的な違いを示しています。
フォワードレンダリングパスでレンダリングしたテレインレイヤー
ディファードレンダリングパスでレンダリングしたテレインレイヤー
ベイクしたグローバルイルミネーションとライティングモード
ベイクしたグローバルイルミネーションが有効な場合、Subtractive および Shadowmask ライティングモードを使用すると、ディファードレンダリングパスで GPU の負荷が増加します。
ディファードレンダリングパスは、互換性の理由から、Subtractive および Shadowmask ライティングモードをサポートしていますが、フォワードレンダリングパスの場合とは異なり、これらのモードによるパフォーマンスの向上はありません。ディファードレンダリングパスでは、Unity はすべてのメッシュを同じライティングアルゴリズムを使用して処理し、Subtractive モードと Shadowmask モードで必要な追加のライティングプロパティを ShadowMask レンダーターゲット に格納します。
ディファードレンダリングパスでは、Baked Indirect ライティングモードは ShadowMask レンダーターゲットを必要としないため、パフォーマンスが向上します。
ライトレイヤー
URP には、シーン内のどのライトを特定のメッシュに反映するかを設定できるライトレイヤー機能が実装されています。特定のライトレイヤーに割り当てられたライトは、同じライトレイヤーに割り当てられたメッシュにのみ反映されます。
ライトレイヤー機能を有効にするには、URP アセットで Advanced > Light Layers の順に選択します。
パフォーマンスへの影響
ライトレイヤー機能では、レンダリングレイヤーマスク (32 ビット) を格納するために、追加の G-buffer レンダーターゲットが必要です。追加のレンダーターゲットは、GPU パフォーマンスに悪影響を与える可能性があります。
実装に関する注記
フォワードレンダリングパスでは、レイヤー 機能により、特定のライトのセットを使用して特定のメッシュをレンダリングするよう Unity に指示することができます。レイヤー 機能はカリングマスクシステムを使用します。
ディファードレンダリングパスでは、シェーディングはレンダリングループの後の段階に延期されるため、レイヤーシステムをライトカリングマスクとともに使用することはできません (ディファードレンダリングパスのレンダーパス の表の ディファードレンダリング (ステンシル) ステップを参照してください)。