Unity性能優化之-DrawCall

文章爲方便自己查看,轉自Unity官方文檔:

https://docs.unity3d.com/Manual/DrawCallBatching.html

什麼是Draw Call?  

Draw Call就是CPU調用圖形編程接口,比如DirectX或OpenGL,來命令GPU進行渲染的操作。

要在屏幕上繪製遊戲對象,引擎必須向圖形 API(例如 OpenGL 或 Direct3D)發出繪製調用。繪製調用通常爲資源密集型操作,圖形 API 爲每次繪製調用執行大量工作,從而導致 CPU 端的性能開銷。此開銷的主要原因是繪製調用之間的狀態變化(例如切換到不同材質),而這種情況會導致圖形驅動程序中執行資源密集型驗證和轉換步驟。

Unity 使用兩種方法來應對此情況:

  • __動態批處理__:對於足夠小的網格,此方法會在 CPU 上轉換網格的頂點,將許多相似頂點組合在一起,並一次性繪製它們。
  • __靜態批處理__:將靜態(不移動)遊戲對象組合成大網格,並以較快的速度渲染它們。

與手動合併遊戲對象相比,內置批處理有幾個好處;最值得注意的是,仍然可以單獨剔除遊戲對象。但是,也有一些缺點;靜態批處理會導致內存和存儲開銷,動態批處理會產生一些 CPU 開銷。

批處理的材質設置

只有共享相同材質的遊戲對象纔可一起接受批處理。因此,如果想要實現良好批處理,應在儘可能多的不同遊戲對象之間共享材質。

如果兩種相同材質僅在紋理上不同,可將這些紋理組合成單個大紋理。此過程通常稱爲紋理鑲嵌(請參閱有關紋理圖集 (Texture atlases)的 Wikipedia 頁面以瞭解更多信息)。一旦紋理位於相同圖集中,即可使用單個材質。

如果需要從腳本訪問共享材質屬性,必須注意,修改 Renderer.material 將創建該材質的副本。應改用 Renderer.sharedMaterial 來保留共享的材質。

陰影投射物即使材質不同,通常也可以在渲染時接受批處理。Unity 中的陰影投射物即使具有不同材質也可以使用動態批處理,只要陰影 pass 所需材質中的值相同即可。例如,許多板條箱可能使用具有不同紋理的材質,但是由於渲染紋理的陰影投射物不相關,所以在此情況下,它們可以一起接受批處理。

動態批處理 (Meshes)

如果移動的遊戲對象共享相同材質並滿足其他條件,則 Unity 可自動在同一繪製調用中批處理這些遊戲對象。動態批處理是自動完成的,無需您進行任何額外工作。

  • Batching dynamic GameObjects has certain overhead per vertex, so batching is applied only to Meshes containing no more than 900 vertex attributes, and no more than 300 vertices.
    • 如果着色器使用頂點位置、法線和單個 UV,最多可以批處理 300 個頂點,而如果着色器使用頂點位置、法線、UV0、UV1 和切線,則只能批處理 180 個頂點。
    • __注意__:將來可能會更改屬性數量限制。
  • 如果遊戲對象在變換中包含鏡像,則不會對這些對象進行批處理(例如,具有 +1 縮放的遊戲對象 A 和具有 –1 縮放的遊戲對象 B 無法一起接受批處理)。
  • 即使遊戲對象基本相同,使用不同的材質實例也會導致遊戲對象不能一起接受批處理。例外情況是陰影投射物渲染。
  • 帶有光照貼圖的遊戲對象具有其他渲染器參數:光照貼圖索引和光照貼圖偏移/縮放。通常,動態光照貼圖的遊戲對象應指向要批處理的完全相同的光照貼圖位置。
  • 多 pass 着色器會中斷批處理。
    • 幾乎所有的 Unity 着色器都支持前向渲染中的多個光照,有效地爲它們執行額外 pass。“其他每像素光照”的繪製調用不進行批處理。

舊版延遲(光照 pre-pass)渲染路徑會禁用動態批處理,因爲它必須繪製兩次遊戲對象。

靜態批處理

使用靜態批處理,引擎可減少任何大小的幾何體的繪製調用,但前提是它共享相同材質並且不移動。這種處理方式通常比動態批處理更高效(它不會在 CPU 上轉換頂點),但是使用更多內存。

爲了利用靜態批處理,您需要顯式指定某些遊戲對象是靜態對象且不會在遊戲中移動、旋轉或縮放。爲此,請使用 Inspector 中的 Static 複選框,將遊戲對象標記爲靜態:

  •  

    使用靜態批處理需要額外的內存來存儲組合的幾何體。如果多個遊戲對象在靜態批處理之前共享相同幾何體,則會在 Editor 中或運行時爲每個遊戲對象創建幾何體的副本。這可能並非總是好辦法;有時您必須避免爲某些遊戲對象進行靜態批處理,這樣會犧牲渲染性能,但可保持較小的內存佔用量。例如,在茂密森林關卡中,將樹標記爲靜態可能會產生嚴重的內存影響。

發佈了31 篇原創文章 · 獲贊 6 · 訪問量 2810
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章