DrawCall

1、定義:每次引擎準備數據並通知GPU的過程稱爲一次Draw Call,我們關心每幀的DrawCall次數

2、Unity生成一幀畫面的處理過程:

      首先,經過簡單的可見性測試,確定攝像機可以看到的物體

      然後,把這些物體的頂點(包括本地位置、法線、UV等),索引(頂點如何組成三角形),變換(就是物體的位置、旋轉、縮放、以及攝像機位置等),相關光源,紋理,渲染方式(由材質Shader決定)等數據準備好

     接着,把這些數據發送給GPU

     最後,GPU基於這些數據,經過一系列運算,在屏幕上畫出成千上萬的三角形,最終構成一幅圖像

3、openGL的一次draw call的繪圖次序是:設置顏色(color filter)→繪圖方式(shader)→頂點座標(model)→繪製→結束。所以,在openGL繪製前如果色彩通道,繪圖方式,頂點座標不同的情況下draw calls就會增加

4、Draw Call Batching批處理

      1)定義:在可見性測試之後,檢查所有要繪製的物體的材質,把相同材質的分爲一組(一個Batch),然後把它們組合成一個物體,這樣就可以在一個Draw Call中處理多個物體了。因爲只要物體的變換和材質相同,GPU就可以按完全相同的方式進行處理

      2)Unity提供了Dynamic Batching和Static Batching兩種方式。Dynamic Batching是完全自動進行的,不需要也無法進行任何干預,對於頂點數在300面以內的物體,只要使用相同的材質球,就會組成Batch。Static Batching則需要

            動態批處理:好消息是一切處理都是自動的,不需要我們自己做任何操作,而且物體是可以移動的;但壞消息是,限制很多,可能一不小心我們就會破壞了這種機制,導致Unity無法批處理一些使用了相同材質的物體。動態批處理的充分條件有:物體使用同一份材質、頂點個數最大限制(900)、所有對象必須使用同一個縮放尺度、使用lightmap的物體不會批處理、接受實時陰影的物體也不會批處理。

    靜態批處理:把靜止的物體標記爲Static,然後無論大小,都會組成Batch。所以,Static Batching顯然比Dynamic Batching要高效得多,優先使用。但是時刻小心對內存的影響。

      3)缺陷:它需要把一個Batch中的所有物體組合到一起,相當於創建了一個與這些物體加起來一樣大的物體,與此同時就需要分配相應大小的內存。這不僅會消耗更多內存,還需要消耗CPU時間。特別是對於移動的物體,每一幀都得重新進行組合,這就需要進行一些權衡,否則得不償失。但對於靜止不動的物體來說,只需要進行一次組合,之後就可以一直使用,效率要高得多

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

     5)減少場景中使用的材質數量:即儘量共享材質,對於僅紋理不同的材質可以把紋理組合到一張更大的紋理中;

           把不會移動的物體標記爲Static;

     6)渲染順序:把材質相同物體的depth調到相近,因爲unity會根據層級從小到大依次渲染物體。例如:A和B使用材質1,C使用材質2,這時候如果層級關係爲A<B<C,那麼就2個DrawCall;如果層級關係爲A<C<B,那麼就有3個DrawCall。

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

     8)擁有lightmap的物體含有額外(隱藏)的材質屬性,比如:lightmap的偏移和縮放係數等。所以,擁有lightmap的物體將不會進行批處理

5、根據各個UI控件的設計安放Panel,隔開DrawCall

  原因:當一個UI控件(UIWidget)的位置、大小或顏色等屬性發生變化時,UIPanel就需要重建這個控件所用的DrawCall,某些情況下還要重建Panel上的所有DrawCall。如果很多控件都集中在同一個DrawCall上,那麼只要一個控件有一點點變化,這個DrawCall上的所有控件的頂點就都要重新遍歷一邊;而我們的UI又大量採用了九宮格拉伸,使控件的頂點數量變得更多,因此重建一個DrawCall的開銷就更大。
建議:將運行時會運動變化的UI控件放在一個UIPanel上、靜止不變的UI控件放在另外一個UIPanel上,這樣它們的DrawCall相互獨立。這樣兩類控件就被隔開到不同的DrawCall不同的Panel中,當一個控件發生變化而導致DrawCall重建時,就不需要遍歷那些沒有變化的控件。雖然這種做法會增加一些DrawCall,但不會有什麼影響。

           

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