图形学基础 | Deferred Shading(延迟渲染)

延迟渲染

1. 简介

在计算机图形学中 shading 表示对受光物体的渲染. 主要有几个步骤:

  1. 计算几何多变形(Mesh)
  2. 决定表面的材质特性.如法线 / 双向反射分布函数 (BRDF)
  3. 计算入射光照
  4. 计算光照的表面的影响. 并最终显示.

一般渲染引擎,渲染场景中的物体的时候,是将这四步一次执行完的。

延迟渲染则将 前两步和 后两步 分开到渲染管道相互独立的两个部分来执行。

2. 背景介绍

前向渲染有多种问题[1]:

  1. 计算每个几何体受那些光影响耗费了CPU的时间,更坏的是,这是个O(n*m)的操作
  2. Shader经常需要 超过一次以上的Pass来渲染光照,渲染n个灯光,对于复杂的Shader,可能需要O(n)次运算
  3. 增加新的光照模型和新的光源类型,可能需要改变所有Effect的源文件
  4. Shader很快就将达到或者超出SM2的指令限制

我们无法控制同屏可见的玩家数量、无法控制同屏会有多少特效和光源
由于 传统前向渲染缺乏对环境的控制,且对于光源的复杂度难于估量
所以选择 延迟渲染
这可以让我们的画面更接近于当今顶尖的游戏引擎,并且 让光照所耗费的资源独立于场景的几何复杂度

延迟渲染需要显卡提供MRT的支持

延迟渲染的好处:

  • 光照所耗费的资源独立于场景复杂度,这样就不用再费尽心机去想着处理那些光源影响几何体了
  • 不必要再为几何体的受光提供附加的Pass了,这样就 节省了Draw Call 和状态切换的数量
  • 在增加新的光源类型和光照模型时,材质的Shader不需要做出任何改变
  • 材质Shader不产生光照,这样就节省了计算额外的几何体的指令数

3. 基本原理

  • 目前我们看到最终画面都是2D的,只能看到有限的像素数,理论上我们只要处理(指光照,阴影处理)最终我们可以看到的点的效果就够了,多余的处理是浪费的。
  • 延迟渲染: 它先将摄像机空间的点光栅化转化成屏幕坐标后再进行处理。这样就能减少处理的次数,从而提高效率。
  • 把处理流程放在了后面,那么处理所需要的参数也必须带到后面的流程. 使用MRT(multi target render)就很重要,RT占用的显存越大,对显卡的的带宽要求也就越高. 后面的处理至少需要空间位置信息,可以通过Depth(至少16位) 获得,其他可以将 法线信息(normal),高光信息(specular),AO系数,diffuse,自发光(emissive),材质编号等信息放入MRT中

延迟渲染可化为为 四个阶段:

  • Geometry : 将本帧所有的 几何信息 光栅化到G-buffer。包括位置,法线,贴图等。
  • Lighting : 以G-buffer作为输入(位置,法线)进行 逐像素的光照计算 将 diffuse lighting和specular lighting 结果分别保存在两张RT上作为lighting buffer.
  • Composition : 将G-buffer中的 贴图bufferlighting buffer 融合,得到渲染结果。
  • Post-processing : 后处理 如HDR SSAO Blur Bloom等.

4. 延迟渲染核心部分

4.1 G-buffer

  • Geometry阶段将几何信息渲染到 multi render target 上 (MRT). 当前最后支持4个?
  • MRT中必须的信息:position(depth), normal, diffuse(texture)
  • 可能需要的信息:specular, power, emissive, ao, material id

4.2 光照计算以及相关优化

使用延迟渲染技术最大的好处就是可以渲染光照极为复杂的场景。
这里场景中的 光照可以分为两类 :

  • 影响 整个场景的scenelight
    • 如directionallight。
    • 渲染一个 screenquad,逐像素光照计算
  • 另一类是 只影响一部分区域的locallight
    • 如点光源、聚光灯、和特效等等。
    • 这些locallight只影响到屏幕上的某些像素,当然不需要逐像素的进行光照计算。
    • 最简单的方法是 绘制这些光源的包围体 (点光源的包围体是球,聚光灯的包围体是圆锥) ,包围体的大小要大于等于光源的衰减范围。这些包围体经过变换投影到屏幕上的对应区域,随后在pixelshader中计算光照.

优化:

  • 光源包围体的 视锥剔除 ,遮挡剔除。
  • 光源包围体 投影后很小时剔除若干个靠的比较近的小光源合并成一个较大的光源
  • 光源包围体的 backfaceculling 背面剔除
  • 屏幕空间中没有被光源照到的,或者被更近的物体遮挡住的像素不需要光照计算,因此可以逐像素的深度剔除
    • a. 使用正确的stencillightvolume
    • b.使用ztest,可以得到“一定程度上正确”的结果

4.3 阴影的计算

  • 光照计算的同时计算阴影。使用传统的shadowmap,预先生成一张阴影图(相关)

  • 考虑在编辑场景的时候指定那些重要的光源才会产生阴影。在计算shadowmap时要针对光源的bindingvolume进行剔除。

  • 方向光和聚光灯可以使用基本的Shadow Map投影(正交投影,透视投影)

  • 点光源会复杂一些,需要使用Cube Shadow Map

5 延迟渲染优缺点分析

延迟渲染优点:

  • 光照的开销与场景复杂度无关;
  • Shader可以访问深度和其他像素信息
  • 每个像素对每个光源仅运行一次. 那些被遮挡的像素是不会被光照计算到的
  • 材质和光照的Shader完全分开

延迟渲染还需要克服的主要障碍:

  • 较高的显存带宽占用
  • G-buffer消耗较多的填充率,这个问题在游戏机上比较严重
  • 无硬件反锯齿的支持
  • 对Alpha Blend支持较差

解决方案:

  1. 增强了MRT的性能. DX10和SM4都提供了GPU支持的整数处理,以及从深度缓冲中读取数据。所有这些都可以减少显存带宽。当提供了新的硬件和特性时,性能自然就会提升。

  2. 在合适的Filter作用下,精确的边缘检测可以减少几何体边缘的锯齿。

  3. 对不透明物体采用延迟渲染,透明物体采用正向渲染,可以解决Alpha Blend的问题

参考文献:
[1]http://blog.csdn.net/noslopforever/article/details/3951273
[2]http://www.opengpu.org/forum.php?mod=viewthread&tid=434
[3]http://blog.csdn.net/pizi0475/article/details/7521394
[4]http://blog.csdn.net/Garuda/article/details/5273106
[5]http://blog.sina.com.cn/s/blog_766f82770100p2kc.html
[6]Akenine-Möller T, Haines E, Hoffman N. Real-time rendering 3 [M].

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值