Version: 2022.1
言語: 日本語
グラフィックスのパフォーマンスとプロファイリング
GPU インスタンシング

ドローコールの最適化

画面にジオメトリを描画するために、Unity はグラフィックス API に対してドローコール (draw call、描画呼び出し) を送信します。ドローコールはグラフィックス API に対して、何をどのように描画するかを指示します。各ドローコールには、テクスチャ、シェーダー、バッファに関する情報など、グラフィックス API が画面に描画するために必要なすべての情報が含まれています。ドローコールはリソースを消費しますが、多くの場合、ドローコール自体よりも、ドローコールの準備の方に多くリソースが消費されます。

ドローコールに備えるため、CPU はリソースを準備し、GPU の内部設定を変更します。これらの設定はまとめてレンダー状態と呼ばれます。レンダー状態の変更 (例えば、別のマテリアルに切り替えるなど) は、グラフィックス API が実行する中で最もリソースを消費する操作です。

レンダー状態の変更はリソースを消費するためそれらを最適化することが重要です。レンダー状態の変更を最適化する主な方法は、レンダー状態の変更の回数を減らすことです。これには 2 つの方法があります。

  • ドローコールの総数を減らします。ドローコールの数を減らすと、それらの間のレンダー状態の変化の数も減ります。
  • レンダー状態の変更回数を減らす方法でドローコールを整理します。グラフィックス API が同じレンダー状態を使用して複数のドローコールを実行する場合、ドローコールをグループ化し、レンダー状態の変更をそれほど多く実行する必要がなくなります。

ドローコールとレンダー状態の変更を最適化することは、アプリケーションにとって多くの利点があります。主にフレーム時間が改善されますが、それ以外にも以下のような利点があります。

  • アプリケーションが必要とする電力量を削減します。電池駆動のデバイスでは、電池の消耗を抑えることができます。また、アプリケーションの実行時にデバイスが発する熱も減らすことができます。
  • アプリケーションの今後の開発における保守性を向上させることができます。ドローコールやレンダー状態の変更を早期に最適化し、最適化されたレベルで維持することで、パフォーマンスの大きなオーバーヘッドを発生させることなく、シーンにゲームオブジェクトを追加できるようになります。

Unity では、ドローコールとレンダー状態の変更を最適化して減らすために、いくつかのメソッドを使用できます。いくつかのメソッドは、他のメソッドよりも特定のシーンに適しています。Unity では以下のメソッドが利用可能です。

  • GPU インスタンシング: 同じメッシュの複数のコピーを同時にレンダリングします。GPU インスタンシングは、樹木や茂みなど、シーンに何度も現れるジオメトリを描画するのに便利です。
  • ドローコールのバッチ処理: メッシュを結合してドローコールを削減します。Unity には、以下のようなビルトインのドローコールバッチ処理があります。
    • 静的バッチ処理: 静的 ゲームオブジェクトのメッシュをあらかじめ結合しておきます。Unity は結合したデータを GPU に送りますが、結合された各メッシュは個別にレンダリングされます。Unity はメッシュを個別にカリングすることができますが、データの状態が変化しないので、各ドローコールのリソース消費は少なくなります。
    • 動的バッチ処理: CPU 上でメッシュの頂点を変換し、同じ構成を共有する頂点をグループ化し、1 回のドローコールでそれらをレンダリングします。頂点が同じ構成を共有するのは、例えば、position (位置) と normal(法線) のような同じ数と種類の属性をもつ場合です。
  • 手動でメッシュを結合: Mesh.CombineMeshes 関数を使用して、複数のメッシュを手動で 1 つのメッシュに結合します。Unity は、メッシュごとに 1 回のドローコールではなく、結合されたメッシュを 1 回のドローコールでレンダリングします。
  • SRP バッチャー: プロジェクトでスクリプタブルレンダーパイプライン (SRP) を使用する場合、同じシェーダーバリアントを使用するマテリアルのドローコールの準備とディスパッチに必要な CPU 時間を短縮するために、SRP バッチャーを使用できます。

最適化の優先度

同じシーンで複数のドローコール最適化メソッドを使用することができますが、Unity のドローコール最適化メソッドには、特定の優先順位があることに注意してください。ゲームオブジェクトに複数のドローコール最適化メソッドを使用するように設定すると、Unity は最も優先度の高いメソッドを使用します。唯一の例外は、SRP バッチャー です。SRP バッチャーを使用する場合、Unity は SRP バッチャーと互換性があるゲームオブジェクト に対し静的バッチ処理もサポートしています。Unity は、ドローコールの最適化に次の順序で優先順位を付けます。

  1. SRP バッチャーと静的バッチ処理
  2. GPU インスタンシング
  3. 動的バッチ

ゲームオブジェクトを静的バッチ処理に設定すると、Unity がバッチ処理に成功した場合、レンダラーがインスタンシングシェーダーを使用する場合も、ゲームオブジェクトの GPU インスタンシングを無効にします。この場合、Inspector ウィンドウに警告メッセージが表示され、静的バッチ処理を無効にするよう促されます。同様に、Unity がメッシュの GPU インスタンシングを使用できる場合、Unity はそのメッシュの動的バッチ処理を無効にします。

グラフィックスのパフォーマンスとプロファイリング
GPU インスタンシング