本文轉自:http://blog.csdn.net/lyh916/article/details/45725499,請點擊鏈接查看樓主大神原文,尊重樓主版權。
參考鏈接:Unity聖典:http://www.ceeger.com/Script/Mesh/Mesh.CombineMeshes.html
一、批處理
1.批處理的目的就是為了減少DrawCall。DrawCall即CPU命令GPU去繪制。
2.如果我們需要渲染一千個三角形,那么把它們按一千個單獨的網格進行渲染所花費的時間要遠大於直接渲染一個包含了一千個三角形的網格。
3.要想使用批處理,需要物體有相同的材質。這是因為,對於使用同一個材質的物體,它們的不同僅僅在於頂點數據的差別,我們可以把這些頂點數據合並在一起,再一起發送給GPU,就可以完成一次批處理。
4.在unity中,有兩種批處理:一是動態批處理,二是靜態批處理。
對於動態批處理,unity會自動完成,不需要我們進行操作,而且物體是可以移動的,但是動態批處理有許多限制條件。
對於靜態批處理,物體不可移動,但是限制條件很少。
二、動態批處理
原理:每一幀把可以進行批處理的模型網格進行合並,再把合並后模型數據傳遞給GPU,然后使用同一個材質對其渲染。
限制:
1.頂點屬性要小於900。例如,如果shader中需要使用頂點位置、法線和紋理坐標這三個頂點屬性,那么要想讓模型能夠被動態批處理,它的頂點數目不能超過300。因此,優化策略就是shader的優化,少使用頂點屬性,或者模型頂點數要盡可能少。
2.多Pass的shader會中斷批處理。
3.在unity5中,動態批處理對於模型縮放的限制已經不存在了。
4.使用光照紋理的物體需要小心處理。為了讓這些物體可以被動態批處理,需要保證它們指向光照紋理中的同一位置。
三、靜態批處理
原理:只在運行開始階段,把需要進行靜態批處理的模型合並到一個新的網格中,這意味着這些模型數據不可以在運行時刻被移動。
優點:因為它只需要進行一次合並操作,因此比動態批處理更加高效。
缺點:需要占用更多的內存來存儲合並后的幾何結構。
操作:將Inspector面板右上角的Static勾選(實際上只需要勾選Batching Static即可)
四、DrawCall
渲染統計窗口
Batches:相當於DrawCall
Saved by batching:通過批處理節省的DrawCall
SetPass calls:跟Shader中Pass的數量有關,Pass越多這個越大
Ps:當對場景中的物體進行修改時,有時需要點擊一下Game視圖,渲染統計窗口才會刷新。
五、影響DrawCall的因素:
1.Pass數量
新建一個場景,將天空盒改為純色,將平行光的陰影類型改為無。此時Batches值為1,當禁用相機時,值為0。
新建一個cube,新建一個材質和三個shader,其中OnePass含一個Pass,TwoPass含兩個,ThreePass含三個。將OnePass給材質,材質給cube。
然后依次將TwoPass和ThreePass給材質。
可以看出,Pass越多DrawCall越大。可以通過FrameDebugger來查看DrawCall,當然也可以用Profiler,但后者不能查看DrawCall的具體情況。
2.材質
a.在場景中放三個cube,cube材質為一個pass
結論:經過動態批處理后,相同材質的物體只占一個DC
b.將上面的cube改為Capsule
結論:對於頂點數太多的物體,無法進行動態批處理,無法減少DC
c.場景放兩個不同材質的cube
結論:不同材質的物體,無法進行動態批處理,無法減少DC
d.針對b情況,勾選Static,然后點擊運行(不運行就無法查看靜態批處理結果)
結論:對於頂點屬性太多的物體(>900),可以使用靜態批處理來減少DC
合並之后的網格
e.那么對於d,再添加一個不同材質的Sphere,勾選Static
結論:不同材質的物體,無法通過靜態批處理減少DC。但是靜態批處理可以通過合並網格來提高性能。
六、合並網格
創建一個空物體,確保縮放為(1,1,1),在空物體下隨便創建一些物體。Ps:要使合並后不變形,就要確保根物體的縮放比例為(1,1,1)
添加以下代碼到空物體上。
此處請查看原文
void CombineMeshes(CombineInstance[] combine, bool mergeSubMeshes = true, bool useMatrices = true);
結合網格有利於性能最優化。如果mergeSubMeshes為true,所有的網格會被結合成一個單個子網格。否則每一個網格都將變成單個不同的子網格。如果所有的網格共享同一種材質,設定它為真。如果useMatrices為false,在CombineInstance結構中的變換矩陣將被忽略。