Open2

Unityのbatching

kanonjikanonji

グラフィックス API はドローコールごとに非常に多くの処理をするため、ドローコールは高負荷で、CPU 側のパフォーマンスオーバーヘッドの原因になります。これは大抵、ドローコール間に状況の変更 (例えばマテリアルの切り替えなど) が発生することに起因し、グラフィックスドライバーで高負荷な検証と 変換処理の原因となります。

  • 動的バッチ処理: かなり小さいメッシュ用に、その頂点を CPU 上に変換して多数の類似したものを群にし、ひとまとめにして描画します。
  • 静的バッチ処理: 静的 (つまり、動かない) ゲームオブジェクトを大きなメッシュと結合して、それを高速でレンダリングします。

手動でゲームオブジェクトをマージするのに比べ、ビルトインのバッチ処理にはいくつか利点があります。特に、ゲームオブジェクトはビルトインのバッチ処理をしても個々にカリングすることが可能です。ただし、欠点もあります。静的バッチ処理では、メモリとストレージのオーバーヘッドを招きます。そして、動的バッチ処理では、いくらかの CPU オーバーヘッドが発生します。

動的バッチ処理は、CPU 上でゲームオブジェクトのすべての頂点をワールド空間に変換することによって機能します。そのため、動的バッチ処理の処理負荷がドローコールよりも小さい場合にのみ利点があります。ドローコールが実際どの程度の負荷になるかは、多くの要素によりますが、主に、使われているグラフィックス API によるところが大きいと言えます。例えば、コンソールや Apple の Metal のような最新の API では通常、ドローコールの処理負荷がかなり低く、動的バッチ処理を使用する利点が全くないことがしばしばあります。
ドローコールバッチング - Unity マニュアル https://docs.unity3d.com/ja/2019.4/Manual/DrawCallBatching.html

  • バッチングはドローコール削減。
  • ドローコールは(前回のドローコールとの間の前処理が)CPU負荷。
  • 動的バッチングはCPU負荷。
    • ドローコール(の前処理)より動的バッチングの方がCPU負荷が大きい場合は逆効果。
    • "Apple の Metal のような最新の API"が例えば、ドローコールの負荷がかなり低い。
  • 静的バッチングはメモリとストレージ負荷。
kanonjikanonji

レンダリングする際には、まずCPUが全てのレンダリング対象オブジェクトの情報を集めます。

次にこれらのうち、マテリアルが同じだったりといったバッチング条件に合うものを一つのメッシュにまとめます。
こうしてまとめたメッシュごとに、Batchという処理単位を作ります。

その後このBatchごとに、SetPass Call -> Draw Callの順に処理をしていきます。

SetPass Callとは、マテリアルの設定値をCPUがGPUに教える処理です。
もし一回前にSetPassした時とマテリアルが同じであれば、SetPass Callは不要なのでスキップされます。

その後Draw Callが呼ばれます。
Draw Callとは、CPUがGPUに、SetPass Callで設定された値を用いてメッシュを描画することを命令することです。
https://light11.hatenadiary.com/entry/2018/06/06/001843

BatchとSetPass call, Draw callの関係の図
BatchとSetPass call, Draw callの関係の図
http://www.plantuml.com/plantuml/uml/XP51IyCm5CVl-HIFUPwuHYyRo3Rz08B7iSEpUMdBqdGaAHF4G-yUl0WUl8hWmIzLP5_3jCOY5DfJazzxVR_mVqlhqBWoLypkChr7WpdSORnBJ55gSLMemi29F9CawLy79gGTF320TQzNobXYKocC81FeEUSUhOmf3e5SUFB83CKETQB83t9n2cYztHzcpV2WiUJsQEqCDXu1t9AxyLU8KQavvEZ8PAXWvOlRxf_9jS53sp9fPWf_cmteehuk6jQjntJHW8xtTRnDRg4oJNCXH7iu5MXJ4Wj7zswEY8ln9m5yFp_LrMjTVTRLLrrz7D-guylxs6ERLR0G_7IJPaAGtav3DkptqojmrcrcUXaYxi8B9FeZF12lMf8MPQv-0000

恐らくはこういう事。
Batch1個につきDraw callは必ず1回あるが、SetPass callはマテリアルが同じなら省略される。
なのでBatches ≒ Draw callsと考えて良さそう。