スクリプタブルレンダーパイプライン (SRP) バッチャーは、ドローコールの最適化 で、SRP を使用するアプリケーションのパフォーマンスを大幅に向上させます。SRP バッチャーは、同じシェーダーバリアントを使用するマテリアルのドローコールの 準備とディスパッチに必要な CPU 時間を短縮します。
このセクションでは、SRP バッチャーとレンダーパイプラインの互換性についての情報を紹介します。
機能 | ビルトインレンダーパイプライン | ユニバーサルレンダーパイプライン (URP) | HD レンダーパイプライン (HDRP) | カスタムのスクリプタブルレンダーパイプライン (SRP) |
---|---|---|---|---|
SRP バッチャー | なし | あり | あり | あり |
どのシーンでも、SRP バッチャーと互換性のあるオブジェクトと互換性のないオブジェクトがあります。互換性のあるゲームオブジェクトは SRP バッチャーコードパスを使い、互換性のないオブジェクトは標準の SRP コードパスを使います。詳しくは、SRP バッチャーのしくみ を参照してください。
SRP バッチャーのコードパスに対応するには、ゲームオブジェクトは以下の要件を満たす必要がある。
HD レンダーパイプライン (HDRP) とユニバーサルレンダーパイプライン (URP) のすべての Lit および Unlit シェーダーはこの要件を満たします (これらのシェーダーのパーティクルバージョンを除く)。
カスタムシェーダーが SRP バッチャーと互換性を持つためには、以下の要件を満たす必要があります。
UnityPerDraw
という名前の 1 つの定数バッファでですべてのビルトインのエンジンプロパティを宣言する必要があります。例えば、unity_ObjectToWorld
や unity_SHAr
などです。UnityPerMaterial
という名前の 1 つの定数バッファで宣言する必要があります。シェーダーの互換性の状況は Inspector パネルで確認できます。
このセクションでは、Unity の事前にビルドされたスクリプタブルレンダーパイプラインで SRP バッチャーを使用する方法について説明します。
URP の SRP バッチャーを起動するには以下を行います。
Unity は、デフォルトでは URP アセットの一部の詳細プロパティが表示されません。利用可能なすべてのプロパティを表示するには以下を行います。
Unity は、現在使用中のセクションで利用可能なすべてのプロパティを表示します。
すべてのセクションの追加プロパティを表示する場合は以下を行います。
HDRP を使用する場合、Unity はデフォルトで SRP バッチャーを有効にします。SRP バッチャーを無効にすることは推奨されません。ただし、デバッグのために SRP バッチャーを一時的に無効にすることは可能です。
エディターを使用して、ビルド時に SRP バッチャーを有効/無効にする方法は以下の通りです。
ランタイムに SRP バッチャー を有効または無効にするには、C# コードでこのグローバル変数を切り替えます。
GraphicsSettings.useScriptableRenderPipelineBatching = true;`
ドローコールを最適化する従来の方法は、その数を減らすことです。その代わりに、SRP バッチャーは、ドローコール間のレンダー状態の変化を低減します。これを行うために、SRP バッチャーは、一連の bind
と draw
GPU コマンドを結合します。それぞれのコマンド群が、SRP バッチと呼ばれます。
レンダリングの最適なパフォーマンスを得るには、各 SRP バッチができるだけ多く bind
と draw
コマンドを含む必要があります。これを実現するには、できるだけ少ないシェーダーバリアントを使用します。同じシェーダーを使って、必要な数の異なるマテリアルを制限なく使用できます。
レンダーループ中に、Unity が新しいマテリアルを検出すると、CPU はすべてのプロパティを収集し、定数バッファで GPU にバインドします。GPU バッファの数は、シェーダーが定数バッファを宣言する方法によって異なります。
SRP バッチャーは、マテリアルデータを GPU メモリに維持する低レベルのレンダリングループです。マテリアルコンテンツが変わらない場合、SRP バッチャーはレンダー状態の変更をしません。代わりに、SRP バッチャーは専用のコードパスを使用して、以下のように大きな GPU バッファの Unity エンジンのプロパティを更新します。
CPU は、上の図で Per Object large buffer とラベル付けされている Unity エンジンのプロパティのみを処理します。すべてのマテリアルには、GPU メモリに配置された永続的な定数バッファがあり、すぐに使用できます。これにより、以下の理由でレンダリングが高速化されます。
まれに、意図的に、特定のゲームオブジェクトの SRP バッチャーとの互換性を排除したい場合があります。例えば、SRP バッチャーと互換性がない GPU インスタンスシング を使いたい場合です。全く同じマテリアルで多数の同じメッシュをレンダリングする場合、GPU インスタ ンシングの方が SRP バッチャーよりも効率的な場合があります。GPU インスタンスを使用するには、以下のいずれかが必要です。
ゲームオブジェクトから SRP バッチャーとの互換性を除くには、2 つの方法があります。
ヒント: SRP バッチャー の代わりに GPU インスタンスを使用する場合、Profiler を使用して、GPU インスタンスが SRP バッチャーよりもアプリケーションにとって効率的であることを確認します。
手書きシェーダーと Shader Graph シェーダーの両方を SRP バッチャー に非対応にすることができます。ただし、Shader Graph シェーダーの場合、Shader Graph を頻繁に変更し、再コンパイルする場合は、代わりに レンダラーを非互換にする 方がシンプルです。
Unity シェーダーを SRP バッチャーに非対応にするには、シェーダーソースファイルを変更する必要があります。
Properties
ブロックに新しい マテリアルプロパティ の宣言を追加します。UnityPerMaterial
定数バッファで新しいマテリアルプロパティを宣言しないでください。マテリアルプロパティには何もする必要がありません。UnityPerMaterial
定数バッファに存在しないマテリアルプロパティを用意するだけで、そのシェーダーは SRP バッチャー と互換性がなくなります。
注意: Shader Graph を使用する場合、Shader Graph を編集して再コンパイルするたびに、このプロセスを繰り返さなければならないことに注意してください。
個々のレンダラーを SRP バッチャーと互換性のないものにすることができます。これを行うには、レンダラーに MaterialPropertyBlock
を加えます。
SRP バッチの状態は、Frame Debugger ウィンドウで確認することができます。各 SRP バッチには、Unity が使用したドローコールの数、Unity がシェーダーにアタッチしたキーワード、Unity がそのドローコールを前のものと一緒にバッチ処理しなかった理由が表示されます。
SRP バッチャーのバッチ状況を確認するには、以下の手順を行います。
下の例では、理由は Nodes have different shaders (ノードが異なるシェーダーをもっている)。つまり、その SRP バッチのシェーダーが、前の SRP バッチのシェーダーと異なることを意味します。SRP バッチャーは異なるシェーダーを使用したため、SRP バッチャーは新しいバッチを作成しました。複数の SRP バッチでドローコールの数が少ない場合、プロジェクトがあまりにも多くのシェーダーバリアントを使用していることを意味することが多い。
自分でスクリプタブルレンダーパイプラインを書く場合、ユニバーサルレンダーパイプラインや HD レンダーパイプラインを使う代わりに、最小限の キーワードで汎用多目的シェーダーを書くようにします。これは、好きなだけ多くのマテリアルプロパティを使用できるので最適です。