【Unity】バッチングについて(第2回・Static Batchingとカリング)

投稿者: | 2017年3月23日

はじめに

こんばんは、代表の堂前です!

前回はStatic Batchingの処理の流れと中身について書いてみました。
今回はDynamic Batchingについて書こうかな〜と思っていたのですが、facebookにて一部不明点が挙がっていたので、カリングとStatic Batchingの兼ね合いの話を書こうと思います。

※検証したのはMacのUnity5.5.2f1になります。


まずはUnity上で検証

今回も前回と同じシチュエーションで、8つのオブジェクトを同一マテリアルにし、それを全てStaticとしてバッチングを確認する状況にしています。

この状態でカメラを横方向にシフトし、一部オブジェクトを見えない状態にしてみます。
通常だとオブジェクト単位でカリング(見えないオブジェクトを早期に処理から外す)が掛かるのですが、Static Batchingで事前にまとめられたと思われるメッシュ(Combined Mesh)ではどうなるでしょうか?

以下、比較してみました。

全部映る 一部見えない
Scene状況
Game状況
FrameDebugger

最後のFrameDebuggerが重要で、「Vertices」と「Indices」の値が変わっています!
これは「Combined Mesh」があってもカリングが行われているということを示しています。

ですので動的にバッチングを行なっているのかなとも考えてProfilerで調べましたが、それっぽい処理は見当たらず・・・。
不思議な状況に陥りました。


詳細解析

そこでひとまずアプローチを変え、Windows向けにビルドしたものを「Intel® Graphics Performance Analyzers」で解析することにします。

それでオブジェクト描画部分を見てみると、Drawcall(DrawIndexedPrimitive関数)が2つに分かれています!

それぞれについてどう描画されているかを調べたのが下になります。
最初に一部(2オブジェクト)を描いて、次に残り(4オブジェクト)を描画しています。
形状もいびつです。





ここまでは状況確認です。

以下は処理の推測です。

・「Combined Mesh」を作る際、オブジェクト単位ごとに頂点のインデックス(Mesh.triangles)を固めておく。
・全部見えている時はそのインデックスを頭から末尾まで範囲指定して描画するが、一部見えない時は描画のインデックス指定でその部分をスキップする様にDraw関数を呼ぶ。

上記検証のためにはインデックスを把握しないといけないのですが、「Intel® Graphics Performance Analyzers」でインデックスを確認しました。
(※GUI上では確認手段がなかったので、Geometryを.objファイルにExportして確認。)

このメッシュの頂点インデックスの並び順は以下になってました。

この様な並びになる法則性は不明ですが、バッチング後も各オブジェクトは「Combined Mesh」におけるインデックスの範囲は保持しておいて、カリングされた時は描画時にその部分だけDrawをスキップさせるという仕組みと思われます。
こうすることによりシーン初期化時のみでMeshを合成し、尚且つカリングにも対応できていると考えます。


 

 

【免責事項】
本サイトでの情報を利用することによる損害等に対し、株式会社ロジカルビートは一切の責任を負いません。

【Unity】バッチングについて(第2回・Static Batchingとカリング)」への1件のフィードバック

  1. ピンバック: 【Unity】5.6.0からのScriptableRenderLoopについて – 株式会社ロジカルビート

コメントは停止中です。