[Unity3D]Shader學習筆記之Shader與DrawCall

Shader是什麼?

  Shader所在階段是渲染流水線的一部分,具體的說就是:

  • GPU流水線上一些可高度編程的階段,而由着色器編譯出來的最終代碼是會在GPU上運行的(對於固定管線的渲染來說,着色器有時等同於一些特定的渲染設置)
  • 有一些特定類型的着色器,如頂點着色器、片元着色器
  • 依靠着色器我們可以控制流水線中的渲染細節,例如用頂點着色器來進行頂點變換以及傳遞數據,用片元着色器來進行逐像素的渲染

  要的到出色的遊戲畫面是需要包括Shader在內的所有渲染流水線階段的共同參與纔可以完成:設置適當的渲染狀態,使用合適的混合函數,開始或關閉深度測試/深度寫入。

Draw Call

  Draw Call即CPU調用圖像編程接口。造成性能瓶頸的不是GPU,而是CPU。

CPU和GPU是如何實現並行工作的

  解決方案是命令緩衝區(Command Buffer)
  命令緩衝區包含一個命令隊列,由CPU向其中添加命令,而由GPU從中讀取命令,添加和讀取的過程是相互獨立的。命令緩衝區使得CPU和GPU可以相互獨立工作。
  當CPU需要渲染一些對象時,它可以向命令緩衝區中添加命令,而當GPU完成了上一次的渲染任務後,它就可以從命令隊列中再取出一個命令並執行它。
  命令緩衝區中的命令有很多種,而Draw Call是其中的一種,其他命令還有改變渲染狀態等(例如改變使用的着色器,使用不同的紋理等)。
這裏寫圖片描述

Draw Call多了爲什麼會影響幀率

  在每次調用Draw Call之前,CPU需要向GPU發送很多內容,包括數據
狀態和命令等。在這一階段,CPU需要完成許多工作,例如檢查渲染狀態等。而一旦CPU完成這些準備工作,GPU就可以開始本次的渲染。
  GPU的渲染速度往往快於CPU提交命令的速度。如果Draw Call的數量太多,CPU就會把大量時間話費在提交Draw Call上,造成CPU的過載。

如何減少Draw Call

  提交大量很小的Draw Call會造成CPU的性能瓶頸,即CPU把時間都花費在準備Draw Call的工作上。那麼一個很顯然的優化方案就是把很多小的Draw Call合併成一個大的Draw Call,這就是批處理(Batching)的思想。
  由於需要在CPU中合併網格,而合併的過程是需要消耗時間的,因此,批處理技術更加合適於那些靜態的物體,例如不會移動的大地、石頭等,對於這些物體我們只需要合併一次即可。對於動態物體也可以進行批處理,由於這些物體是不斷運動的,因此每一幀都需要進行合併然後再發送給GPU,這對空間和時間都會造成一定的影響。
  利用批處理技術,CPU在RAM把多個網格合併成一個更大的網格,再發送給GPU,然後在一個Draw Call中渲染它們。但要注意的是,使用批處理合並的網格將會使用同一種渲染狀態。也就是說,如果網格之間需要使用不同的渲染狀態,那麼就無法使用這種技術。

在遊戲開發過程中,爲了減少Draw Call的開銷,有兩點需要注意:

  • 避免使用大量很小的網格。當不可避免的需要使用很小的網格結構時,考慮是否可以合併它們。
  • 避免使用過多的材質。儘量在不同的網格之間共用同一個材質。

這裏寫圖片描述

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