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

GPU インスタンシング

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

GPU インスタンシングは、、各ドローコールで同じメッシュをレンダリングします。バリエーションを追加して繰り返しの印象を減らすために、各インスタンスは ColorScale のような異なるプロパティをもつことができます。複数のインスタンスをレンダリングするドローコールは、Frame Debugger に、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.DrawMeshInstanced を使用する。この 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 の ベイクした Global Illumination システム をサポートします。Unity のスタンダードシェーダーとサーフィスシェーダーは、デフォルトで GPU インスタンシングと Unity のベイクした Global Illumination システムをサポートします。

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

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

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

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

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

また、LPPV コンポーネントの参照と LightProbeUsage.UseProxyVolumeGraphics.DrawMeshInstanced に渡すこともできます。これを行うと、すべてのインスタンスがライトプローブのデータの 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 インスタンシング対応シェーダーの作成