スクリーンにオブジェクトを描画するために,描画エンジンはOpenGLやDirect3DのグラフィックAPIにドローコール(draw call)を発行しなければいけません。どんな一回のドローコールでも多くのグラフィックAPIの集まりが必要になります。つまりこれはCPUパフォーマンスのオーバーヘッドに重大な影響をもたらします。
Unityはランタイムで複数のオブジェクトを合成し,一回のドローコールで同時に描画します。この処理は「バッチング(batching)」と呼ばれます。Unityがより多くのオブジェクトを一緒にバッチングできれば,レンダリングのパフォーマンスはより良くなるということになります。
Unity内に組み込まれているバッチングは,単なるモデリングツールでのジオメトリ合成(またはStandard Assets packageのCombineChildren スクリプトの利用)以上に,絶大な効果があります。Unity内のバッチングは見える範囲に入った 後 に処理が走ります。描画エンジンはどのオブジェクトも個別にカリング(間引き)しますので,レンダリングされたジオメトリの集合はバッチングしないのと同じになります。一方で,モデリングツールのジオメトリ合成は効果的なカリングを阻害し,結果的に多くのジオメトリをレンダリングすることになります。
同じマテリアルを共有しているオブジェクトがバッチング可能になります。そのため,より効果的なバッチングをするには,できる限り違うオブジェクト間で多くのマテリアルを共有する必要があります。
もし二つのテクスチャが違うだけの独立したマテリアルがあるのであれば,二つのテクスチャを組み合わせて一つのテクスチャに合成しましょう( テクスチャアトラス と呼ばれるプロセスです)。いったんテクスチャを同じアトラスにしてしまえば,単一のマテリアルとして使うことができるようになります。
もしスクリプトから共有しているマテリアルプロパティをアクセスするならば,以下の情報が重要です:Renderer.material の変更はマテリアルのコピーが生じます。共有しているマテリアルをキープしたいのであれば,代わりに Renderer.sharedMaterial を使いましょう。
同じマテリアルを共有していて他の条件を満たせば,Unityは自動的に動いているオブジェクトをバッチングします。ダイナミックバッチングは自動的に処理されるので,何かの手間が必要というわけではありません。
ヒント:
一方でスタティックバッチングはどんなサイズのジオメトリでもドローコールを減らすことが出来ます(動かなくて同じマテリアルを共有することが条件です)。スタティックバッチングはダイナミックバッチングよりも顕著に効果が出ます。CPUパワーを減らす必要があるなら是非スタティックバッチングを選択して下さい。
スタティックバッチングの利用するには,そのオブジェクトがゲーム中,動いたり,回転したり,スケールしたりするということが__ない__ ということを明示的に設定する必要があります。InspectorのStaticチェックボックスをオンにすると,その設定になります。:
スタティックバッチングを使うと,合成したジオメトリ情報を保存しておくためのメモリが余計に必要になります。もしスタティックバッチングの前に,複数のオブジェクトで同じジオメトリを共有しているのであれば,オブジェクトごとにジオメトリのコピーがおこります(エディター上でもランタイムでも)。このことから,いつでもお勧めする方法ではありません。つまり場合によっては,小さいメモリ使用量を維持するために,スタティックバッチングを避けて,レンダリングのパフォーマンスを犠牲になければならないこともあるでしょう。例えば,密集した森林において,木をスタティックにすると,メモリにはかなりの負担になるかもしれません。
スタティックバッチングはUnity Pro専用で,どのプラットフォームでも利用可能です。
現在は, メッシュレンダラ および [パーティクルシステム](Particle Systems) のみがバッチングされます。すなわち,スキンメッシュ,クロス,トレイル レンダラおよびその他の種類のレンダリング コンポーネントはバッチング されません 。
準透明なシェーダはしばしば後方から前方のオブジェクトの順番でレンダリングしないと正しく透明さが機能しないことがあります。Unity は最初にオブジェクトをこの順番でのレンダリングを指令し,バッチングしようとします - しかし順番は厳密に適用する必要がある場合,不透明のオブジェクトと比べてバッチングはより少なくなることを意味します。
Unityのレンダリングの一部はまだバッチングが実装されていません。例えば,シャドウ 投影,カメラのデプステクスチャ,または GUI の場合でのレンダリングはバッチングされません。