遊戲卡頓竟是因爲DrawCall?到底什麼是DrawCall?

在玩遊戲時遇到的掉幀、操作延遲,大概率和一個叫Draw Call的指標有關。

它是遊戲渲染的核心環節,也是性能優化繞不開的坎,哪怕是Unity、UE 引擎的資深開發者,也得在它身上下功夫。

什麼是Draw Call?

Draw Call僅僅是一條指令。

是CPU向GPU發送的繪圖指令,包含頂點、材質、紋理、着色器參數等,GPU接收後執行繪製。例如在Unity引擎中,每個使用獨立材質的物體都會觸發一次Draw Call,GPU接收到指令後執行頂點變換、光照計算、像素填充等操作,最終輸出到顯示設備。

就好比CPU是廚師長,下單(發Draw Call)告知GPU(廚師)做什麼菜(繪圖數據)、怎麼炒(渲染狀態),指令越多通信越耗時,越容易導致畫面卡頓。

其核心流程包含三個階段:

1、數據準備:CPU將這些數據從內存(RAM)傳輸至GPU顯存(VRAM)

2、狀態配置:設置渲染管線狀態(如着色器、混合模式、深度測試)和全局參數(如光照、投影矩陣)

3、指令提交:調用glDrawElements或DrawIndexedPrimitive等API觸發GPU渲染

關鍵特性:

命令緩衝區機制:CPU與GPU通過Command Buffer實現異步通信,CPU寫入指令,GPU按隊列順序執行

渲染狀態切換成本:每次材質、紋理或着色器變更需重新配置全局狀態,產生額外開銷

你在遊戲裏看到的每棵樹、每個角色、每道特效,背後都需要CPU發一次(或多次)命令,告訴 GPU “該畫這個東西了”。比如屏幕上有100棵樹,默認情況下可能就有100個Draw Call,GPU收到命令後纔會執行渲染操作。

這裏要明確一個關鍵點:Draw Call就是一個命令,它的發起方是CPU,接收方是GPU。這個命令僅僅會指向一個需要被渲染的圖元(primitives)列表,而不會再包含任何材質信息。

而Draw Call中造成性能問題的元兇其實不是的GPU真正“拖後腿”其實的是CPU

Draw Call多了會影響幀率?

舉個栗子:先創建10000個小文件,每個文件的大小爲1KB,然後把它們從一個文件夾複製到另一個文件夾。你會發現,儘管這些文件的空間總和不超過10MB ,但要花費很長時間。


然後再創建一個單獨的文件,它的大小是10MB,然後也把它從一個文件夾複製到另一個文件夾。而這次複製的時間卻少很多。

這是爲什麼呢?明明它們所包含的內容大小是一樣的。原因在於,每一個複製動作需要很多額外的操作,例如分配內存、創建各種元數據等。

如你所見,這些操作將造成很多額外的性能開銷,如果我們複製了很多小文件,那麼這個開銷將會很大。

渲染的過程雖然和上面的例子有很大不同,但也是類似的道理。在每次調用Draw Call之前, CPU需要向GPU發送很多內容,包括數據、狀態和命令等。

在這一階段, CPU需要完成很多工作,一旦CPU完成了這些準備工作, GPU就可以開始本次的渲染。

影像CPU還是GPU?

如果Draw Call的數量太多,CPU就會把大量時間花費在提交Draw Call上,造成CPU的過載,CPU會首先成爲瓶頸。

其次是GPU,GPU的吞吐量其實遠遠大於CPU,但DrawCall過多也會在一定程度上影響GPU,這是由於數據沒有組織好,導致GPU頻繁切換硬件狀態,頻繁請求顯存數據,頻繁出現Cache Miss情況造成的。

所以對於開發者來說,Draw Call作爲遊戲性能的關鍵指標,優化的核心從來不是讓GPU少畫,而是讓CPU少發命令

比如批處理的方法,很顯然就是在CPU中把很多小的DrawCall合併成一個大的Draw Call,再發送給GPU。

而批處理也分靜態和動態,由於需要在CPU的內存中合併,而合併的過程是需要消耗時間的。因此,批處理技術更加適合於那些靜態的物體,例如不會移動的大地、石頭等,對於這些靜態物體只需要合併一次即可。


當然,也可以對動態物體進行批處理。但是,由於這些物體是不斷運動的,因此每一幀都需要重新進行合併然後再發送給GPU,這對空間和時間都會造成一定的影響。

🙏感謝閱讀、點贊和充電

更多遊戲資訊請關註:電玩幫遊戲資訊專區

電玩幫圖文攻略 www.vgover.com