【Unity】DrawCallについて

1.UnitのDrawCallについて マニュアルより抜粋 スクリーンにオブジェクトを描画するために、描画エン…

1.UnitのDrawCallについて

マニュアルより抜粋

スクリーンにオブジェクトを描画するために、描画エンジンはOpenGLやDirect3DのグラフィックAPIにドローコール(draw call)を発行しなければいけません。どんな一回のドローコールでも多くのグラフィックAPIの集まりが必要になります。つまりこれはCPUパフォーマンスのオーバーヘッドに重大な影響をもたらします。

要約するとUnityは画面に何かを描く時にDrawCall発行する
DrawCallは処理が重いので少ない方がいいとのこと。

2.DrawCallの回数を確認する

UnityのGameビューウィンドウの上に[Stats]というボタンがある。
これを押すと[Statistics]という小窓が表示される。

01

このDrawCallsの部分にDrawCallが呼ばれた回数が表示される。

3.DrawCallを抑えるには

マニュアルより抜粋

同じマテリアルを共有しているオブジェクトがバッチング可能になります。そのため、より効果的なバッチングをするには、できる限り違うオブジェクト間で多くのマテリアルを共有する必要があります。

マテリアルとはオブジェクトに貼り付ける模様の様なものである。
このマテリアルが増えるとDrawCall数が増える。

4.DrawCall数を計測

具体的にどのような場合にDrawCall数が増えるのか

シーン上に[Cube]を1つおいた場合、DrawCall数は1になる。
[Cube]には[Default-Diffuse]というマテリアルがデフォルトでついている。
02

シーン上の[Cube]を3つにした場合でも、DrawCall数は変わらず1である。
03

このようにオブジェクトの数が増えただけではDrawCall数は変わらない。
画面上には[Default-Diffuse]というマテリアル1つしか存在しないためである。

次に新たにマテリアルを作成し、3つの[Cube]それぞれにマテリアルを設定した場合。
04
[Blue]と[Red]という2つのマテリアルを作成。

05

この場合はDrawCall数が3になる。
画面上には[Blue]、[Red]、[Default-Diffuse]の3つのマテリアルがあるので
DrawCallが3回になる。

※オブジェクトがシーン上にあったとしても、画面に映らない場合、DrawCall数は増えない。

基本的にDrawCall数=画面上のマテリアル数という事になる。

4.その他のDrawCall数を増やす要因

UnityのGUI機能を使う

void OnGUI ()
{
	GUI.Box (new Rect(10, 10, 100, 20), "Box");
}

UnityのGUIでBoxを1つ表示するとDrawCallが2増える。
2つBoxを表示すると合計で4増える。

06

Scriptでマテリアルをコピーする
別なオブジェクト(ここではCubeとした)のマテリアルを代入すると、マテリアルがコピー(複製)され
DrawCall数も増える。

renderer.material = GameObject.Find("Cube").renderer.material;

Resouces.Loadでマテリアルをロード

マテリアルをロードした後、Instantiateで実態化するとマテリアルが増えてしまう。

renderer.material = Instantiate(Resources.Load("マテリアルのパス")) as Material;

マテリアルはInstantiateしないでも、ロードしたものをそのまま使える。
このようにしておくと、マテリアルの実態は1つだけに保つ事が出来る。

renderer.material = Resources.Load("マテリアルのパス") as Material;

5.DrawCallの目安
200以上 15FPS
100以上 30FPS
50くらい 60FPS

iPhone4での目標は25~45FPSと言われている。