Unity優化 drawcall系列

2022-08-18 21:15:16 字數 2418 閱讀 7768

*drawcall影響的是cpu的效率。因為draw call是cpu呼叫圖形介面在螢幕上繪製對應的東西。

主體:

為了在螢幕上draw乙個物件(因為render和draw有些區別,所以為了區分清楚,這些概念用英文),引擎需要提供乙個draw call的api。draw call呼叫效能開銷是很大的,會導致cpu部分的效能負載。這通常是因為draw call間的狀態改變(例如不同材質間的切換)導致,因為這些行為會導致顯示卡驅動進行開銷很大的驗證和轉化步驟。

unity用static batch來處理這件事情。static batch的目的是為了用盡可能少的緩衝區來重組盡可能多的mesh,從而獲得更好的效能。因而static batch會出現一些巨大的mesh被渲染,而不是很多的小mesh被渲染。合併後的這些資源雖然在不同的地方出現,但是unity會認為是同樣的資源(因為這些小資源已經合併了)來迴圈進行渲染。它會為每個static bached mesh來做一系列的快速的draw call。

構建時做batch,在unity5中只有一種方式,會構建index buffer, 然後乙個draw call會被提交來用來處理合併的mesh裡的每個可見的子mesh

材質

只有使用同樣材質的物件才能夠合併。因而,如果你想獲得好的合併效果,你需要盡可能多的使不同的物件貢獻同樣的材質。

*texture atlasing可參見以下網頁

如果你需要從指令碼裡獲得共享重用的材質屬性,你要注意修改rendering.material將會建立這個材質的拷貝。因而你需要使用renderer.sharedmaterial來獲取找個共享的材質。

static batching(靜態批次)

靜態批次,對於沒有移動且公用材質的物件,能有效減少drawcall。一般來說,靜態批次比動態批次更有效,但它會占用更多的記憶體,也會消耗更少的cpu。

為了達到靜態批次的效果,你需要顯式的註明哪些物件是靜態的,不移動,不旋轉也不縮放的。你可以通過下面的方式來表明使用靜態批次:

使用靜態批次,需要額外的記憶體來儲存合併的圖形。如果一些物件使用的是同乙份幾何圖形,做靜態批次後,每個物件都會建立乙份幾何圖形,無論是在編輯器還是執行時。這不是個好的方案,因此有時不得不避免採用靜態批次(雖然會損失渲染的效能),但是可以保持乙個較小的記憶體。例如,在乙個密集的森林裡把樹都標記成需要靜態批次的,會有嚴重的記憶體影響。

靜態批次是通過轉換一堆的靜態物件到世界座標系,來構建乙個大的頂點和索引buffer。可見的物件在同乙個靜態批次,而且不會有狀態的切換(狀態切換的代價是很大的)

dynamic batching(動態批次)

當物件使用相同的材質,並且滿足一定的條件時,unity會自動合併物件來減少draw call。dynamic batching 是自動做的,不需要教你做其他的事情。

tips:

*batching動態物件會給個頂點增加額外的開銷,所以batch只適用於所有mesh合起來少於900個頂點的情況

**如果你的shader用的是vertex position, normal和 single uv,你能合併300個頂點;如果你的shader用的是vertex position ,normal, uv0, uv1和tangent,只能達到180個

**ps:這條unity5的規則數目新的版本裡有可能會變

*一般來說,物件應該使用相同的trasform scale。

**對於不規則縮放的物件除外;如果一些物件有自己的不同的不規則的transform,他們還是會被batch的

*用不同的材質例項,會導致物件不被batch(即便這些材質例項實際上是相同的)

*使用光照圖的物件會有額外的渲染引數:包括光照圖的索引、相對光照圖縮放和偏移。最好動態的光照圖的物件能指向同乙個光照圖的位置,這樣可以batch

*接收實時陰影的物件不會batch

*多通道的shader會破壞batch。幾乎unity中所有的著色器在前向渲染中都支援多個光源,並為它們有效地開闢多個通道。為了「額外的每個畫素光照」的draw call是不會batch的

other batching tips

目前,只有mesh render和粒子系統被batch。其他的元件(如skin mesh, 布料)都不會被batch。另外半透明的shader因為要渲染半透明的效果常常要求物件是從後往前來繪製。unity會按照這個順序給物件排序,然後再嘗試batch他們。但是因為順序是嚴格要求的,所以半透明的物件能被batch的效果遠不如不透明的物件。

一些unity的render不能被batch。比如shadow casters,攝像機的深度圖和gui都會batch.

Unity優化 drawcall系列

知識普及 drawcall影響的是cpu的效率。因為draw call是cpu呼叫圖形介面在螢幕上繪製對應的東西。主體 為了在螢幕上draw乙個物件 因為render和draw有些區別,所以為了區分清楚,這些概念用英文 引擎需要提供乙個draw call的api。draw call呼叫效能開銷是很大...

Unity效能優化 DrawCall

1.drawcall是啥?其實就是對底層圖形程式 比如 opengl es 介面的呼叫,以在螢幕上畫出東西。所以,是誰去呼叫這些介面呢?cpu。比如有上千個物體,每乙個的渲染都需要去呼叫一次底層介面,而每一次的呼叫cpu都需要做很多任務作,那麼cpu必然不堪重負。但是對於gpu來說,圖形處理的工作量...

Unity效能優化之Draw Call

unity 或者說基本所有圖形引擎 生成一幀畫面的處理過程大致可以這樣簡化描述 引擎首先經過簡單的可見性測試,確定攝像機可以看到的物體,然後把這些物體的頂點 包括本地位置 法線 uv等 索引 頂點如何組成三角形 變換 就是物體的位置 旋轉 縮放 以及攝像機位置等 相關光源,紋理,渲染方式 由材質 s...