代码改变世界

游戏引擎中的光照算法

2019-01-12 12:13  风恋残雪  阅读(3661)  评论(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