読者です 読者をやめる 読者になる 読者になる

夏までにiPhone アプリつくってみっか!

趣味でiPhone/Androidアプリを開発し、日々勉強した事を書いています。オープンワールド系レースゲームをUnityで開発中です。

【Unity】マテリアルの共有化でドローコール(Batches, SetPass Calls)が減ったかどうか検証

Unity オープンワールドレーシングゲーム

最初にモデリングしたAE86は車体各部を色毎にマテリアルを分けることで着色していました。
この方法は色艶の調整が楽なのですが、「ドローコールが増えて処理が重くなる」という情報を得ました。
そこで、2台目のCR-Xではできるだけマテリアルを共有し、着色、反射、鏡面、凹凸などはテクスチャで表現する方法に変えてみました。
今回は、実際にその効果があったのかどうかを検証したいと思います。

UnityのStatisticsウィンドウ(Gameビュー上部の枠のStatsをクリックして表示)には様々な情報が表示されますが、ゲームの処理の重さを測る指標としてBatches数、SetPass Calls数などがあります。
Unityの中の人によると、ドローコール数(=Batches数)は今やさほど問題ではなく、SetPass Calls数に気を配るべきだとのことらしいです。

参考:
GREE Tech Talk #07 ご来場ありがとうございました | GREE Engineers' Blog

比較のため、まずはAE86の各指標の数値がどうなっているか調べてみます。

f:id:takujidev:20151025115237p:plain

画面が真っ暗なのは純粋にモデルの部分だけの数値がみたかったからで、ライトやスカイボックスなどあらゆるものをOFFにしています。
ただし、地面がないと車が奈落の底へ落ちてしまうのでQuadを1枚敷いています。
Quad 1枚分の数値がこちらです。これを引いた値が純粋な車だけの数値となります。

f:id:takujidev:20151025115526p:plain

さて、最初のAE86と地面が表示されたスクリーンショットではBatches数が15、SetPass Calls数が9となっています。

AE86は車体と4本のタイヤ・ホイールの計5つのオブジェクトから構成されています。
車体は白、黒、窓の色、窓枠などのつや消し黒、テールランプの赤、オレンジの6つのマテリアル、タイヤ・ホイールは艶の違う2種類の黒の2種類のマテリアルを使用しています。
地面のマテリアルと合わせると計9種類のマテリアルが存在することになり、これはSetPass Callsの9と一致しています。

Batches数は各オブジェクトが持つマテリアル数の合計となるようです。
つまり、車体(6) + タイヤ(2) * 4 + 地面(1) = 15です。

次に、これがCR-Xではどのような結果になったのか、見てみたいと思います。

f:id:takujidev:20151025120315p:plain

Batches数が8、SetPass Calls数が3です。

減りました!

CR-Xは車体、4本のタイヤ・ホイール、ナンバープレート、パワーバルジ(ボンネット上の出っ張り)の7個のオブジェクとからなっています。
車体の大部分と他の全てのオブジェクトは1つのマテリアルを共有しています。唯一マテリアル分けたのは透明な材質にする必要があったヘッドライトカバーだけで、計2種類のマテリアルで構成されています。これに地面の1マテリアルを足すとSetPass Callsの3と一致します。

Batches数は本来は車体(2) + タイヤ(1) * 4 + バルジ(1) + ナンバー(1) + 地面(1) = 9なのですが、ナンバーとバルジのドローコールがバッチングにより1つにまとめられたためSaved by Batchingに1が計上され、Batches数は8となっています。

構成するオブジェクト数が違うのでBatches数の直接比較はできませんが、SetPass Calls数がAE86の1/3に減ったのでマテリアルを共有し、テクスチャで色分け、材質分けをした効果は大いにあったという結論となりました。

ただ、ひとつ気になったことがあります。
3角形ポリゴンの数を示すTris数なのですが、実際のモデルのポリゴン数と一致しています。
AE86のモデルのポリゴン数(Tris数)は4832で、Unity上のTris数は4.8k、CR-Xのモデルのポリゴン数は7198でUnity上の表示は7.2kとなっています。

私は今までUnity上のTris数は描画処理されているポリゴンの数だと思っていました。つまり、車の前面は底面など、反対側を向いていてBackface Cullingで描画されていないポリゴンの数が差し引かれ、モデルのポリゴン数の半分くらいの数が計上されているものだと勝手に考えていました。
しかし、この結果から考えるとBackface Cullingされているかどうかに関わらず、表示領域内のオブジェクトの全てのポリゴン数がカウントされているようです。
試しにナンバープレートのみを表示してみましたが、Backface Cullingは正常にされていて、向こうを向いている前のプレートは表示されず、カメラの方を向いている後ろのプレートだけが見えています。

f:id:takujidev:20151025123214p:plain

なお、表示領域外にありFrustum Cullingされたオブジェクトのポリゴン数は計上されません。

最後に、CR-Xがアキバの街を走る動画です。