Unity優化----drawcall系列


本文由博主(國寶大熊貓)原創,轉載請注明出處:http://www.cnblogs.com/xsln/p/5151951.html
知識普及
     *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(也就是圖集)。一旦貼圖在同一個圖集里,你就能只使用一個材質來代替。
    *texture atlasing可參見以下網頁https://en.wikipedia.org/wiki/Texture_atlas
    如果你需要從腳本里獲得共享重用的材質屬性,你要注意修改 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.
 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM