Version: 2022.2
言語: 日本語
手動によるメッシュの結合
BatchRendererGroup

スクリプタブルレンダーパイプラインバッチャー

スクリプタブルレンダーパイプライン (SRP) バッチャーは、ドローコールの最適化 で、SRP を使用するアプリケーションのパフォーマンスを大幅に向上させます。SRP バッチャーは、同じシェーダーバリアントを使用するマテリアルのドローコールの 準備とディスパッチに必要な CPU 時間を短縮します。

スクリプタブルレンダーパイプライン (SRP) バッチャーは、同じシェーダーバリアントを使用する多くのマテリアルを持つシーンのレンダリングに要する CPU 時間を短縮します。
スクリプタブルレンダーパイプライン (SRP) バッチャーは、同じシェーダーバリアントを使用する多くのマテリアルを持つシーンのレンダリングに要する CPU 時間を短縮します。

要件と互換性

このセクションでは、SRP バッチャーとレンダーパイプラインの互換性についての情報を紹介します。

レンダーパイプラインの互換性

機能 ビルトインレンダーパイプライン ユニバーサルレンダーパイプライン (URP) HD レンダーパイプライン (HDRP) カスタムのスクリプタブルレンダーパイプライン (SRP)
SRP バッチャー なし

ゲームオブジェクトの互換性

どのシーンでも、SRP バッチャーと互換性のあるオブジェクトと互換性のないオブジェクトがあります。互換性のあるゲームオブジェクトは SRP バッチャーコードパスを使い、互換性のないオブジェクトは標準の SRP コードパスを使います。詳しくは、SRP バッチャーのしくみ を参照してください。

SRP バッチャーのコードパスに対応するには、ゲームオブジェクトは以下の要件を満たす必要がある。

  • ゲームオブジェクトはメッシュかスキンされたメッシュを含む必要があります。パーティクルは不可です。
  • ゲームオブジェクトは MaterialPropertyBlocks を使ってはいけません。
  • ゲームオブジェクトが使用するシェーダーは、SRP バッチャーに対応している必要があります。詳しくは、シェーダーの互換性 を参照してください。

シェーダーの互換性

HD レンダーパイプライン (HDRP) とユニバーサルレンダーパイプライン (URP) のすべての Lit および Unlit シェーダーはこの要件を満たします (これらのシェーダーのパーティクルバージョンを除く)。

カスタムシェーダーが SRP バッチャーと互換性を持つためには、以下の要件を満たす必要があります。

  • UnityPerDraw という名前の 1 つの定数バッファでですべてのビルトインのエンジンプロパティを宣言する必要があります。例えば、unity_ObjectToWorldunity_SHAr などです。
  • シェーダーはすべてのマテリアルプロパティを UnityPerMaterial という名前の 1 つの定数バッファで宣言する必要があります。

シェーダーの互換性の状況は Inspector パネルで確認できます。

特定のシェーダーの Inspector でシェーダーの互換性を確認できます。
特定のシェーダーの Inspector でシェーダーの互換性を確認できます。

SRP バッチャーの使用

このセクションでは、Unity の事前にビルドされたスクリプタブルレンダーパイプラインで SRP バッチャーを使用する方法について説明します。

URP で SRP バッチャーを使用する

URP の SRP バッチャーを起動するには以下を行います。

  1. Project ウィンドウで、URP アセット を選択します。
  2. In the Inspector for the URP asset, enable SRP Batcher. If this option is not visible, follow the instructions below.

URP アセットに追加プロパティを表示する方法

Unity は、デフォルトでは URP アセットの一部の詳細プロパティが表示されません。利用可能なすべてのプロパティを表示するには以下を行います。

  • URP アセットの任意のセクションで、垂直の省略記号アイコン (⋮) をクリックし、Show Additional Properties を選択します。

追加プロパティを表示する

Unity は、現在使用中のセクションで利用可能なすべてのプロパティを表示します。

すべてのセクションの追加プロパティを表示する場合は以下を行います。

  1. 垂直方向の省略記号アイコンをクリックし、Show All Additional Properties を選択します。Unity は、Preferences ウィンドウの Core Render Pipeline セクションを開きま す。
  2. Additional Properties > Visibility の順に選択し、All Visible を選択します。
Additional Properties > Visibility > All Visible
Additional Properties > Visibility > All Visible

HDRP で SRP バッチャーを使用する

HDRP を使用する場合、Unity はデフォルトで SRP バッチャーを有効にします。SRP バッチャーを無効にすることは推奨されません。ただし、デバッグのために SRP バッチャーを一時的に無効にすることは可能です。

エディターを使用して、ビルド時に SRP バッチャーを有効/無効にする方法は以下の通りです。

  1. Project ウィンドウで、HDRP アセット を選択します。
  2. アセットの Inspector で、デバッグモード にします。デバッグモードでは、HDRP アセットのプロパティが表示され、SRP バッチャー のプロパティが表示されるようになります。
  3. Enable SRP バッチャー を選択して、SRP バッチャーの有効/無効を選択します。 ****

ランタイムに SRP バッチャー を有効または無効にするには、C# コードでこのグローバル変数を切り替えます。

GraphicsSettings.useScriptableRenderPipelineBatching = true;`

SRP バッチャーの仕組み

ドローコールを最適化する従来の方法は、その数を減らすことです。その代わりに、SRP バッチャーは、ドローコール間のレンダー状態の変化を低減します。これを行うために、SRP バッチャーは、一連の binddraw GPU コマンドを結合します。それぞれのコマンド群が、SRP バッチと呼ばれます。

bind と draw コマンドのバッチ処理により、ドローコール間の GPU 設定が削減されます。
bind と draw コマンドのバッチ処理により、ドローコール間の GPU 設定が削減されます。

レンダリングの最適なパフォーマンスを得るには、各 SRP バッチができるだけ多く binddraw コマンドを含む必要があります。これを実現するには、できるだけ少ないシェーダーバリアントを使用します。同じシェーダーを使って、必要な数の異なるマテリアルを制限なく使用できます。

レンダーループ中に、Unity が新しいマテリアルを検出すると、CPU はすべてのプロパティを収集し、定数バッファで GPU にバインドします。GPU バッファの数は、シェーダーが定数バッファを宣言する方法によって異なります。

SRP バッチャーは、マテリアルデータを GPU メモリに維持する低レベルのレンダリングループです。マテリアルコンテンツが変わらない場合、SRP バッチャーはレンダー状態の変更をしません。代わりに、SRP バッチャーは専用のコードパスを使用して、以下のように大きな GPU バッファの Unity エンジンのプロパティを更新します。

SRP バッチャーのレンダリングワークフロー。SRP バッチャーは専用のコードパスを使用して、大きな GPU バッファの Unity エンジンのプロパティを更新します。
SRP バッチャーのレンダリングワークフロー。SRP バッチャーは専用のコードパスを使用して、大きな GPU バッファの Unity エンジンのプロパティを更新します。

CPU は、上の図で Per Object large buffer とラベル付けされている Unity エンジンのプロパティのみを処理します。すべてのマテリアルには、GPU メモリに配置された永続的な定数バッファがあり、すぐに使用できます。これにより、以下の理由でレンダリングが高速化されます。

  • すべての素材コンテンツが GPU メモリに永続化されるようになりました。
  • 専用のコードは、オブジェクトごとのすべてのプロパティのための大きな GPU 定数バッファを管理します。

ゲームオブジェクトの SRP バッチャー互換性を意図的に排除する

まれに、意図的に、特定のゲームオブジェクトの SRP バッチャーとの互換性を排除したい場合があります。例えば、SRP バッチャーと互換性がない GPU インスタンスシング を使いたい場合です。全く同じマテリアルで多数の同じメッシュをレンダリングする場合、GPU インスタ ンシングの方が SRP バッチャーよりも効率的な場合があります。GPU インスタンスを使用するには、以下のいずれかが必要です。

  • Use Graphics.RenderMeshInstanced.
  • SRP バッチャーの互換性を手動で排除し、マテリアルの GPU インスタンシングを有効にする

ゲームオブジェクトから SRP バッチャーとの互換性を除くには、2 つの方法があります。

  • シェーダーを非対応にする。
  • レンダラーを非対応にする。

Tip: If you use GPU instancing instead of the SRP Batcher, use the Profiler to make sure that GPU instancing is more efficient for your application than the SRP Batcher.

シェーダー互換性の排除

手書きシェーダーと Shader Graph シェーダーの両方を SRP バッチャー に非対応にすることができます。ただし、Shader Graph シェーダーの場合、Shader Graph を頻繁に変更し、再コンパイルする場合は、代わりに レンダラーを非互換にする 方がシンプルです。

Unity シェーダーを SRP バッチャーに非対応にするには、シェーダーソースファイルを変更する必要があります。

  1. 手書きシェーダーの場合は、シェーダーソースファイルを開きます。Shader Graph シェーダーの場合、Shader Graph のコンパイル済みシェーダーソースコードを新しいシェーダーソースファイルにコピーします。シェーダーグラフの代わりに、新しいシェーダーソースファイルをアプリケーションで使用します。
  2. シェーダーの Properties ブロックに新しい マテリアルプロパティ の宣言を追加します。UnityPerMaterial 定数バッファで新しいマテリアルプロパティを宣言しないでください。

マテリアルプロパティには何もする必要がありません。UnityPerMaterial 定数バッファに存在しないマテリアルプロパティを用意するだけで、そのシェーダーは SRP バッチャー と互換性がなくなります。

注意: Shader Graph を使用する場合、Shader Graph を編集して再コンパイルするたびに、このプロセスを繰り返さなければならないことに注意してください。

レンダラー互換性の排除

個々のレンダラーを SRP バッチャーと互換性のないものにすることができます。これを行うには、レンダラーに MaterialPropertyBlock を加えます。

Unity フレームデバッガーで SRP バッチャをプロファイルする

SRP バッチの状態は、Frame Debugger ウィンドウで確認することができます。各 SRP バッチには、Unity が使用したドローコールの数、Unity がシェーダーにアタッチしたキーワード、Unity がそのドローコールを前のものと一緒にバッチ処理しなかった理由が表示されます。

SRP バッチャーのバッチ状況を確認するには、以下の手順を行います。

  1. エディターで、Frame Debugger を開きます (メニュー: Window > Analysis > Frame Debugger)。
  2. Frame Debugger で、Render Camera > Render Opaques を選択します。
  3. RenderLoopNewBatcher. Draw リストを展開します。
  4. 検査したい SRP Batch をクリックします。

下の例では、理由は Nodes have different shaders (ノードが異なるシェーダーをもっている)。つまり、その SRP バッチのシェーダーが、前の SRP バッチのシェーダーと異なることを意味します。SRP バッチャーは異なるシェーダーを使用したため、SRP バッチャーは新しいバッチを作成しました。複数の SRP バッチでドローコールの数が少ない場合、プロジェクトがあまりにも多くのシェーダーバリアントを使用していることを意味することが多い。

Frame Debuger ウィンドウでは、なぜ SRP バッチャーは既存のバッチを使わずに新しい SRP バッチを作成したかなど、個々の SRP バッチの詳細を確認できます。 

自分でスクリプタブルレンダーパイプラインを書く場合、ユニバーサルレンダーパイプラインや HD レンダーパイプラインを使う代わりに、最小限の キーワードで汎用多目的シェーダーを書くようにします。これは、好きなだけ多くのマテリアルプロパティを使用できるので最適です。

手動によるメッシュの結合
BatchRendererGroup