上文讲到了如何把信息挤入有限的G-Buffer,另一个在实际中面临的问题是如何渲染透明物体。
透明物体
游戏中透明物体是不可缺少的,对于Deferred Rendering来说,透明物体一直是痛苦的。常见的做法是在deferred rendering的场景之上用forward shading来单独渲染透明物体,但那样就意味着必须单独实现一整套forward shading的流水线。这对于维护和扩展都是很不利的,对性能也很有影响。
在KlayGE 4.0里,我用的方法被称为Deep G-Buffer。其基本过程是,把第一篇所描述的Deferred Rendering流水线复制三份,不透明的物体、透明物体的背面、透明物体的正面分别有自己独立的G-Buffer、lighting pass、shading pass和special shading pass。最 ...
上一篇讲了在KlayGE 4.0中,Deferred Rendering的流水线改进。本篇继续讲G-Buffer的变化。
G-Buffer布局
前面提到了G-Buffer改成了MRT,那么现在就来比较一下新老G-Buffer的区别。老G-Buffer的安排如下:
老G-Buffer是4个通道、每个通道都是fp16的RGBA16F格式。其中normal用Spheremap Transform的方式映射到2个通道;depth单独存一个通道;specular和shininess挤在一个通道内,整数部分为specular * 100,小数部分为shininess / 256.0f。
这样的G-Buffer需要占据64-bit,IO开销不小,而且depth精度有限。如果按照新的MRT G-Buffer扩展到2个RT,就需要再增加一个32-bit的RT。对于不支持Independent MRT的D3D9硬件来说,甚至要增加 ...
Deferred Rendering在KlayGE中已经出现比较长时间了,我也写过系列文章来阐述KlayGE中的延迟渲染。在将要推出的KlayGE 4.0中,Deferred Rendering进入了渲染系统的核心,可以作为更通用更方便的一个渲染封装来使用。
在功能上,KlayGE 4.0中的Deferred Rendering也有了长足的进步。本系列将着重于解析这些新改进。
流水线
先来看看Deferred Rendering的流水线。
在流水线方面,第一个比较大的变化是,G-Buffer改成了MRT的,用类似Deferred Shading的fat G-Buffer来避免在shading pass再次渲染一遍物体。新G-Buffer的布局将在下一篇分解。在shading pass阶段,只需要渲染一个全屏quad,在每个pixel上把材质和光照信息结合就可以了 ...
正如不久前的帖子所描述的,KlayGE 4.0的渲染系统将会过渡到deferred rendering的框架。这样做
好处
各种效果都可以在这个框架内得到整合、发挥和发展
方便未来编辑器的构建
坏处
只需要一些底层的geek变得不方便了
我现在的考虑是,把渲染系统分为两层,底下一层是API抽象层,负责把图形API抽象成同样的接口;上一层是deferred rendering层,提供高级功能。这样就可以兼顾两种应用需要。
在deferred rendering里面,除了deferred框架本身,还会包含GI、SSVO、HDR tone mapping、FXAA、Color grading以及Stereo。
前一阵子连载的“KlayGE中的延迟渲染”系列文章经过整理,现在有一个完整的版本放在wiki网站:http://www.klayge.org/wiki/index.php?title=%E5%BB%B6%E8%BF%9F%E6%B8%B2%E6%9F%93。
KlayGE中的延迟渲染(四)集中在Anti-alias的方法,本篇是这个系列的完结篇,我们一起来探讨未来将对延迟渲染所做的改进。
展望未来
shading pass再次渲染物体的改进
Deferred Lighting最受争议的一点应属在shading pass需要再次渲染几何体了。如果物体很多,尤其是有tessellation和GS的,多渲一遍有可能抵消了lighting pass带来的性能提升。改进的方法之一就是在建立G-Buffer阶段,用类似Deferred Shading的fat G-Buffer。除了原先的一张纹理,还需要一张纹理用来存放diffuse信息。但是lighting pass和原来一样,不涉及diffuse。shading pass就变成画一个全屏四边形,从G-Buffer的第二章纹理读取diffuse,进行着色。甚至emit也这么处理。 ...
KlayGE中的延迟渲染(三)介绍了lighting pass的优化技巧,本篇将讲解anti-alias。
Anti-Alias
从Deferred Shading发明的一天起,anti-alias的问题就一直困扰着所有Deferred的方法。虽然很多无良的游戏厂商直接在Deferred Rendering的游戏里不支持AA,但确实AA对提升画面质量很有帮助。
Edge AA
在Deferred的框架里,很自然会想到用Edge AA来处理AA。其过程不外乎:
边缘检测,得到每个像素“像边缘的程度”
在shader里根据“像边缘的程度”来控制采样坐标
这本身并不是个复杂的过程,尤其是第二步,非常直截了当了,所以这里集中讨论的是如何进行边缘检测。
GPU Gems 2的“Deferred Shading in STALKER”一文提供了一种边缘检测的 ...
在KlayGE中的延迟渲染(二)里,Deferred Lighting的3个阶段都已经得到解释,本篇将讲解如何更快地计算lighting pass。
Light volume
在Deferred Rendering中,表示一个光源最简单的方法就是一个全屏的四边形。它能让G-Buffer的每一个pixel都参与计算,在pixel shader中才过滤掉多余的像素。虽然可以保证结果正确,但毕竟多余计算太多,效率不高。这里常用的一个优化就是用一个凸的几何形状来表示光源。该几何 形状覆盖的pixel才计算该光源对它的贡献。显而易见的是,spot light用圆锥,point light用球或者立方体,directional light和ambient light用全屏四边形。下图画了一个spot light的volume:
这样的几何体类似于古老的shado ...
在KlayGE中的延迟渲染(一)里,我们推出了lighting pass里的计算,本篇将讲解G-Buffer阶段和Shading pass阶段。
G-Buffer分配
在Deferred Rendering的框架中,不管是Deferred Shading还是Deferred Lighting,G-Buffer的分配都是非常关键的。上一篇得出的lighting pass公式如下:
[latex]float4(1, 1, 1, (\mathbf{n} \cdot \mathbf{h_n})^{\alpha} F(c_{spec}, \mathbf{l_{cn}},\mathbf{h_n})) \times \mathbf{c}_{lightn} (\mathbf{n} \cdot \mathbf{l_{cn}})[/latex]
从公式可以看出,在light pass里需要的量有n,h,alpha,cspec,lc。因为h = (v + lc) / 2(见游戏中基于物理的渲染系列文章),而lc = normalize(l - p)(l是光源位 ...
KlayGE中的延迟渲染系列文章将讲述在KlayGE 3.11的Deferred Rendering例子中使用的延迟渲染方法,由5篇文章组成。
Deferred Lighting的框架
KlayGE 3.11的例子已经从Deferred Shading改成了更节省带宽的Deferred Lighting。这里先对Deferred Lighting作一个简要的介绍,并假设读者已经了解了Deferred Shading。
Deferred Lighting的渲染架构可以分为三个阶段:
G-Buffer的生成
for each light
{
Lighting pass
}
Shading pass
与Deferred Shading不同的是,shading(也就是和材质相关)的计算仅仅发生在最后一个阶段。所以,G-Buffer中需要保存的信息得到极大地减小,甚至不再需要MRT。
Lighting pass
Lighting pass ...