【Unity】DrawCall 研究隨記

皮卡味月亮發表於2024-11-29

參考文件:1. BatchBatchBatch.PDF

參考文件:2. DrawCall,Batches,SetPass calls是什麼?原理?【匠】

DrawCall (繪製呼叫) 是什麼

DrawCall就是CPU呼叫影像程式設計介面,比如 DirectX 的 DrawPrimitive/DrawIndexedPrimitive ,OpenGL 的 glDrawElement/glDrawArrays,以命令 GPU 進行渲染的操作

簡單來講,就是指 CPU 向 GPU 傳送一條指令,用於進行渲染操作。即:DrawCall 就是一次渲染指令呼叫

Batches (批處理)又是什麼

把資料載入到視訊記憶體,設定渲染狀態及資料,CPU 呼叫 DrawCall 的這一整個過程就是一個 Batch。

這個過程當中主要效能消耗點在於上傳物體資料(載入到視訊記憶體)和設定渲染狀態及資料這一塊,而不是DrawCall命令本身。

所以我們將多個 DrawCall 合併為一個 DrawCall 來減少呼叫DrawCall的開銷(主要是呼叫DrawCall之前的一系列設定)

這個操作就是 Batches 批處理。

什麼會造成DrawCall增加

1.無法合批/打斷合批

1.Batch Breaker: Texture Change

紋理的更改會造成合批被打斷,即:會增加 Batches 的數量,而 Sprite 的更改不會。

解決方法:若要降低 DrawCall ,可使用打包圖集的方法。

RawImage 的圖片更換則一定會打斷合批。

2.Batch Breaker: Transform Change

位置、旋轉、縮放、等空間變化的更改會打斷合批。

解決方法:在 UGUI 的使用中進行動靜分離,以減少 UI 重繪,降低 DrawCall

3.Batch Breaker: Material Change

不同材質的物體也沒辦法進行合批,會造成合批被打斷

解決方法:1.使用材質圖集將多個紋理合併為一個紋理,以便多個物件可以使用同一個材質,從而實現合批。

2.使用 Material Property Blocks 進行材質的動態屬性修改

示例:
// 獲取材質例項
Material instanceMaterial = renderer.material;

// 使用 Material Property Blocks
MaterialPropertyBlock propertyBlock = new MaterialPropertyBlock();
propertyBlock.SetColor("_Color", Color.red); // 修改顏色
renderer.SetPropertyBlock(propertyBlock);

2.透明物體

對於透明物體而言,透明物體必須按照特定的順序進行渲染,通常是從後到前。這是因為透明物體的混合效果依賴於其後面的物體的渲染結果。因此,透明物體的渲染順序要求額外的處理

相關文章