1. 程式人生 > >遊戲引擎中的光照演算法

遊戲引擎中的光照演算法

前言

今天我們來聊一下游戲引擎中的光照演算法,從最開始的Forward Render,到後來的Deferred Render再到後面的Clustered Forward Render以及Clustered Deferred Render,分析一下實現步驟以及它們的優缺點。

Forward Render

這個是最傳統的方法,對於多光源的處理比較有限,它的基本演算法如下所示:

一般遊戲引擎為了減少批次和處理光照的次數,會讓每個物體受影響的光源有個上限比如3個或者4個,而且一般是在一個shader裡面直接處理多個光源的情況。這個在最開始的遊戲引擎中比較常見。目前基本上只會使用在移動平臺上。比如Unity和UE4移動平臺的低配版本都是這樣的。

Deferred Shading

隨著遊戲中支援光源的數量越來越多,傳統的Forward Render已經不能滿足遊戲的需求,Deferred Shading應運而生,這個技術基本上是從Deferred shading in S.T.A.L.K.E.R. 進入大家的視野的。基本思路如下圖所示:

基本上GBuffe的內容大體如上圖所示,當然目前大多數引擎為了支援多材質一個會有一個位元組用於寫入Material ID或者Shading Model ID(UE4)來區分不同的著色模型。

Tiled Deferred Shading

Tile Deferred Shading就是在Deferred Shading基礎上按一定畫素大小分塊(比如32x32),計算每一塊中光源的數量,這樣我們可以對多個光源計算光照只讀取一次GBuffer資訊,節省了頻寬。

Deferred Lighting

Cryengine3早期版本中使用過該技術,大體演算法如下圖所示:

這個演算法跟Deferred Shading差不多,目前基本上沒有引擎再使用這個方法。

Forward Plus Shading(Tiled Forward Rendering

Forward+ Rendering最初是從AMD的論文Forward+: Bringing Deferred Lighting to the Next Level開始流行起來的。基本演算法如下圖所示:

Clustered Forward Rendering

在Forward+ Rendering的基礎上又沿著相機深度的方向切了很多片。

Clustered Deferred Rendering

Clustered Forward Rendering也即是在Tiled Deferred Rendering的基礎上又沿著相機深度的方向上進行了切片。

切片演算法

總結

到這裡我們把基本的光照演算法都講一遍了,讀者可以看到上面的這些光照演算法無非就是下面的幾種組合:Forward/Deferred + (Tiled/Clustered)?,這裡?代表0或1。演進過程是這樣的,最開始只有傳統的Forward Rendering,為了解決多光源的問題,引入了Deferred Rendering,帶來了很多好處,包括各種後期效果。但是頻寬是個問題,於是出現了Forward Plus(Tiled) Rendering解決頻寬問題,也就有了Tiled Deferred Shading,但是還可以進一步優化,那就是在Tile的基礎上再切片,於是就有了Clustered Forward Rendering和Clustered Deferred Rendering。下面我們列個簡單的表格來對比下他們的優缺點。

光照演算法

優點

缺點

Forward Rendering

  1. 實現最簡單。
  2. MSAA和透明渲染都能正常工作。
  3. 頻寬消耗小。
  1. 對大規模點光源支援不好。
  2. 對各種需要深度和法線的後期處理演算法不友好。

Deferred Shading

  1. 支援大規模點光源。
  2. 對各種需要深度和法線的後期處理演算法很友好。
  1. 頻寬消耗大。
  2. MSAA和透明渲染支援不友好。
  3. 視訊記憶體消耗大。

Forward+ Rendering

  1. MSAA和透明渲染都能正常工作。
  2. 頻寬消耗小。
  3. 支援大規模光源。
  1. 對各種需要深度和法線的後期處理演算法不友好。
  2. 強制需要一個Pre-Z Pass

Tiled Deferred Shading

  1. 支援大規模點光源
  2. 對各種需要深度和法線的後期處理演算法很友好。
  3. 相對Deferred Shading頻寬消耗在光源計算的時候會減少。
  1. 頻寬消耗大
  2. MSAA和透明渲染支援不友好。
  3. 視訊記憶體消耗大。

Clustered Forward Rendering

  1. MSAA和透明渲染都能正常工作。
  2. 頻寬消耗小。
  3. 支援大規模光源。
  4. 相對Forward+ Rendering在光源多的時候會有效率提升。
  1. 對各種需要深度和法線的後期處理演算法不友好。
  2. 強制需要一個Pre-Z Pass

Clustered Deferred Shading

  1. 支援大規模點光源
  2. 對各種需要深度和法線的後期處理演算法很友好。
  3. 相對Deferred Shading頻寬消耗在光源計算的時候會減少。
  4. 相對Tiled Deferred Rendering在光源很多的情況下會有效能提升。

1、頻寬消耗大

2、MSAA和透明渲染支援不友好。

3、視訊記憶體消耗大。

從上表可以看出,這些演算法的優缺點基本就是Forward/Deferred以及Tiled/Clustered優缺點的組合。

參考文章

  1. http://download.nvidia.com/developer/presentations/2004/6800_Leagues/6800_Leagues_Deferred_Shading.pdf
  2. https://www.slideshare.net/guest11b095/a-bit-more-deferred-cry-engine3
  3. https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter09.html
  4. http://www.yosoygames.com.ar/wp/2016/11/clustered-forward-vs-deferred-shading/
  5. https://www.gdcvault.com/play/1014915/Lighting-in-Crysis
  6. https://pydonzallaz.wordpress.com/2013/08/23/gdc-europe-2013-shining-the-light-on-crysis-3/
  7. https://developer.nvidia.com/gpugems/GPUGems2/gpugems2_chapter09.html
  8. https://takahiroharada.files.wordpress.com/2015/04/forward_plus.pdf
  9. https://www.3dgep.com/forward-plus/
  10. https://www.slideshare.net/takahiroharada/forward-34779335
  11. http://www.cse.chalmers.se/~uffe/clustered_shading_preprint.pdf
  12. http://www.humus.name/Articles/PracticalClusteredShading.pdf
  13. Forward+: A Step Toward Film-Style Shading in Real Time -- GPU Pro 4
  14. https://www.gdcvault.com/play/1025420/Cluster-Forward-Rendering-and-Anti
  15. http://www.dice.se/wp-content/uploads/2014/12/GDC11_DX11inBF3_Public.pdf