unity3d優化DrawCall

在屏幕上渲染物體,引擎需要發出一個繪製調用來訪問圖形API(iOS系統中爲OpenGL ES)。每個繪製調用需要進行大量的工作來訪問圖形API,從而導致了CPU方面顯著的性能開銷。

Unity在運行時可以將一些物體進行合併,從而用一個繪製調用來渲染他們。這一操作,我們稱之爲“批處理”。一般來說,Unity批處理的物體越多,你就會得到越好的渲染性能。

Unity中內建的批處理機制所達到的效果要明顯強於使用幾何建模工具(或使用Standard Assets包中的CombineChildren腳本)的批處理效果。這是因爲,Unity引擎的批處理操作是在物體的可視裁剪操作之後進行的。Unity先對每個物體進行裁剪,然後再進行批處理,這樣可以使渲染的幾何總量在批處理前後保持不變。但是,使用幾何建模工具來拼合物體,會妨礙引擎對其進行有效的裁剪操作,從而導致引擎需要渲染更多的幾何面片。

材質

只有擁有相同材質的物體纔可以進行批處理。因此,如果你想要得到良好的批處理效果,你需要在程序中儘可能地複用材質和物體。

如果你的兩個材質僅僅是紋理不同,那麼你可以通過 紋理拼合 操作來將這兩張紋理拼合成一張大的紋理。一旦紋理拼合在一起,你就可以使用這個單一材質來替代之前的兩個材質了。

如果你需要通過腳本來訪問複用材質屬性,那麼值得注意的是改變Renderer.material將會造成一份材質的拷貝。因此,你應該使用Renderer.sharedMaterial來保證材質的共享狀態。

動態批處理

如果動態物體共用着相同的材質,那麼Unity會自動對這些物體進行批處理。

動態批處理操作是自動完成的,並不需要你進行額外的操作。

Tips:

提醒:

1、 批處理動態物體需要在每個頂點上進行一定的開銷,所以動態批處理僅支持小於900頂點的網格物體。

2、 如果你的着色器使用頂點位置,法線和UV值三種屬性,那麼你只能批處理300頂點以下的物體;如果你的着色器需要使用頂點位置,法線,UV0,UV1和切向量,那你只

能批處理180頂點以下的物體。

請注意:屬性數量的限制可能會在將來進行改變。

4、 不要使用縮放尺度(scale)。分別擁有縮放尺度(1,1,1)和(2,2,2)的兩個物體將不會進行批處理。

5、 統一縮放尺度的物體不會與非統一縮放尺度的物體進行批處理。

使用縮放尺度(1,1,1)和 (1,2,1)的兩個物體將不會進行批處理,但是使用縮放尺度(1,2,1)和(1,3,1)的兩個物體將可以進行批處理。

6、 使用不同材質的實例化物體(instance)將會導致批處理失敗。

7、 擁有lightmap的物體含有額外(隱藏)的材質屬性,比如:lightmap的偏移和縮放係數等。所以,擁有lightmap的物體將不會進行批處理(除非他們指向lightmap的同一

部分)。

8、 多通道的shader會妨礙批處理操作。比如,幾乎unity中所有的着色器在前向渲染中都支持多個光源,併爲它們有效地開闢多個通道。

9、 預設體的實例會自動地使用相同的網格模型和材質。

Static Batching

靜態批處理

相對而言,靜態批處理操作允許引擎對任意大小的幾何物體進行批處理操作來降低繪製調用(只要這些物體不移動,並且擁有相同的材質)。因此,靜態批處理比動態批處理更加有效,你應該儘量低使用它,因爲它需要更少的CPU開銷。

爲了更好地使用靜態批處理,你需要明確指出哪些物體是靜止的,並且在遊戲中永遠不會移動、旋轉和縮放。想完成這一步,你只需要在檢測器(Inspector)中將Static複選框打勾即可,如下圖所示:

使用靜態批處理操作需要額外的內存開銷來儲存合併後的幾何數據。在靜態批處理之前,如果一些物體共用了同樣的幾何數據,那麼引擎會在編輯以及運行狀態對每個物體創建一個幾何數據的備份。這並不總是一個好的想法,因爲有時候,你將不得不犧牲一點渲染性能來防止一些物體的靜態批處理,從而保持較少的內存開銷。比如,將濃密森裏中樹設爲Static,會導致嚴重的內存開銷。

靜態批處理目前只支持Unity iOS Advanced。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章