Version: 2022.3
言語: 日本語
ドローコールの最適化
GPU インスタンシング対応シェーダーの作成

GPU インスタンシング

GPU インスタンシングは ドローコール最適化 の方法で、同じマテリアルをもつ複数のメッシュコピーを 1 回のドローコールでレンダリングします。メッシュの各コピーはインスタンスと呼ばれます。これは、例えば、木や茂みなど、シーンに何度も現れるものを描画するのに便利です。

GPU インスタンシングは、同じドローコールで同一のメッシュをレンダリングします。バリエーションを追加して繰り返しの表示を低減するために、各インスタンスには スケール のような異なるプロパティを設定できます。複数のインスタンスをレンダリングするドローコールは、フレームデバッガー に、Draw Mesh (instanced) として表示されます。

要件と互換性

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

プラットフォームの互換性

GPU インスタンシングは、WebGL 1.0 を除くすべてのプラットフォームで利用可能です。

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

機能 ビルトインレンダーパイプライン ユニバーサルレンダーパイプライン (URP) HD レンダーパイプライン (HDRP) カスタムのスクリプタブルレンダーパイプライン (SRP)
GPU インスタンシング あり (1) あり (1) あり (1)

ノート:

  1. シェーダーが SRP バッチャー と互換性がない場合のみ

SRP バッチャー

GPU インスタンシングは SRP バッチャー と互換性がありません。SRP バッチャーは GPU インスタンシングより優先されます。ゲームオブジェクトが SRP バッチャーと互換性がある場合、Unity は GPU インスタンシングではなく SRP バッチャーを使用してレンダリングします。最適化手法の優先順位についての詳細は、最適化の優先順位 を参照してください。

プロジェクトが SRP バッチャーを使用していて、ゲームオブジェクトに GPU インスタンスを使用したい場合、以下のいずれかを実行します。

  • Graphics.RenderMeshInstanced を使用します。この API はゲームオブジェクトの使用を回避し、指定されたパラメーターを使用して直接画面上にメッシュを描画します。
  • SRP バッチャーの互換性を手動で削除します。この方法については、互換性を意図的に削除する を参照してください。

GPU インスタンシングの使用法

Unity は、同じメッシュとマテリアルを共有するゲームオブジェクトに対して、GPU インスタンシングを行います。メッシュとマテリアルをインスタンス化するには以下を行います。

  • マテリアルの シェーダー は GPU インスタンシングをサポートする必要があります。Unity の スタンダードシェーダー は、すべての サーフェスシェーダー 同様に GPU インスタンシングをサポートします。他のシェーダーに GPU インスタンシングのサポートを追加するには、GPU インスタンシングをサポートするシェーダーの作成 を参照してください。
  • メッシュは、動作別に分類された以下のソースのいずれかである必要があります。
    • MeshRenderer コンポーネントまたは Graphics.RenderMesh の呼び出し。
      動作: Unity はこれらのメッシュをリストに追加し、どのメッシュをインスタンス化でき るかを確認します。
      Unityは、SRP バッチャーと互換性があるゲームオブジェクトにアタッチされた SkinnedMeshRenderers コンポーネント、または MeshRenderer コンポーネントに対し、GPU インスタンシングをサポートしません。詳しくは、SRP バッチャーの互換性 を参照してください。
    • Graphics.RenderMeshInstanced または Graphics.RenderMeshIndirect の呼び出し。これらのメソッドは、同じシェーダーを使用して同じメッシュを複数回レンダリングします。これらのメソッドを呼び出すたびに、個別のドローコールが送信されます。Unity はこれらのドローコールをマージしません。

マテリアルに GPU インスタンシングを使用するには、Inspector で Enable GPU Instancing オプションを選択します。

マテリアルインスペクターに表示される Enable GPU Instancing オプション
マテリアルインスペクターに表示される Enable GPU Instancing オプション

ライティング

GPU インスタンシングは、Unity の ベイクしたグローバルイルミネーションシステム をサポートします。Unity のスタンダードシェーダーとサーフィスシェーダーは、デフォルトで GPU インスタンシングと Unity のベイクしたグローバルイルミネーションシステムをサポートします。

各 GPU インスタンスは、以下のいずれかのソースからのグローバルイルミネーションをサポートしています。

  • 任意の数の ライトプローブ
  • 1 つの ライトマップ
    ノート: インスタンスはライトマップで複数のアトラスリージョンを使用することができます。
  • 1 つの [Light Probe Proxy Volume (LPPV) コンポーネン ノート: LPPV は、すべてのインスタンスを含むスペースボリュームをベイクする必要があります。

GPU インスタンシングは、自動的に以下と動作します。

  • ライトプローブのの影響を受ける動的 メッシュレンダラー
  • 同じライトマップテクスチャにベイクする静的メッシュレンダラー。Contribute GI が メッシュレンダラーの Static Editor Flags に含まれる場合、メッシュレンダラーは、このコンテキストでは静的です。

Graphics.RenderMeshInstanced でライトプローブレンダリングを有効にするには、プローブデータを含む MaterialPropertyBlock を指定します。詳細およびコード例については、LightProbes.CalculateInterpolatedLightAndOcclusionProbes を参照してください。

または、LPPV コンポーネントの参照と LightProbeUsage.UseProxyVolumeGraphics.RenderMeshInstanced に渡すこともできます。これを行うと、すべてのインスタンスがライトプローブのデータの L0 バンドと L1 バンド のボリュームをサンプリングします。L2 データとオクルージョンデータを補うには、MaterialPropertyBlock を使用します。詳細は、ライトプローブ: 技術的な情報 を参照してください。

パフォーマンスへの影響

頂点数が少ないメッシュは、GPU インスタンシングを使用しても、効率的に処理することができま せん。なぜなら、GPU のリソースを十分に活用した方法で作業を分配できないからです。この処理効率の悪さは、パフォーマンスに有害な影響を与える可能性があります。非効率が始まるしきい値は GPU によって異なりますが、原則として、256 より少ない頂点のメッシュには GPU インスタンシングを使用しないでく ださい。

頂点数の少ないメッシュを何度も描画する場合は、すべてのメッシュの情報を含むバッファを 1 つ作成し、それを使ってメッシュを描画するのが効率的です。


  • 2017–10–24 修正されたページ

  • Enable Instancing チェックボックスの説明、DrawMeshInstancedIndirect、#pragma multi-compile に関しては 5.6 で追加

  • GPU インスタンシングのためのシェーダーウォームアップは 2017.3 で追加 NewIn20173

  • GPU インスタンシングでのグローバルイルミネーション (GI) サポートは 2018.1 で追加 NewIn20181

ドローコールの最適化
GPU インスタンシング対応シェーダーの作成