一、前言
在Unity的Camera中常常会看到一个Rendering Paths的选项,里面有5个选项,其中两个比较重要的选项分别是“Deferred Shading”和“Forward Rendering”,在我还是初学Unity的时候,并没有在意太多。如今随着学习Shader的深入慢慢领会到了这两个渲染路径的重要性。下面就这两个渲染路径的区别和优缺点做一个学习记录。主要参考文献
维基百科:Deferred_shading
Unity官网:Deferred shading rendering path
Forward Rendering vs. Deferred Rendering
在介绍这两个渲染路径的开始不得不先介绍一下现在的图形渲染管线,如图所示为一个现代GPU的渲染过程。因为,硬件的限制,我们不能改变如何绘制单个的像素,只能通过给硬件输送不同的纹理来进行改变。自从有了可编程图像管线,我们现在可以通过代码来修改顶点,或扭曲或移动来改变像素的外观,至此从本质上改变图形硬件如何渲染目标物体。
首先要介绍的就是常用的延迟着色渲染(Deferred Shading)
二、延迟着色渲染(Deferred Shading)
1.1、漫反射颜色几何缓冲区
1.2、深度缓冲区(Z-buffering)
1.3、表面法线几何缓冲区
1.4、最后的合成效果(图中还含有阴影,
因此计算阴影映射和阴影
卷必须和延迟渲染一起使用)
2、优点支持DirectX 10以及更高版本的现代GPU显示硬件通常能够足够快的执行批次处理,以保持交互式帧率的稳定。当需要产生顺序无关的透明度时(通常在一些游戏中),延迟渲染并不会比正向渲染使用相同的技术有效。
(注:延迟渲染在正交摄像机模式下也是不支持的,如果摄像机切换到了正交模式之后就会默认使用正向渲染)
另外一个比较严重的缺点是使用多材质比较困难。要使用多材质不是不可能,需要在几何缓冲区存储更多的数据,这就需要更大的内存宽带。
一个更致命的缺点是,由于光照和几何渲染的分离,导致抗锯齿变得不稳定,主要是因为这种分离会导致内插子样本会产生不稳定的位置、法线和切线属性。克服这种限制的常用方法是在最终的图像上使用边缘检测,然后在边缘上使用模糊处理。而且,如今有更高级的边缘平滑处理技术,如MLAA(Efficiently MovingAntialiasing from the GPU to the CPU,https://software.intel.com/sites/default/files/m/d/4/1/d/8/MLAA.pdf),时间反混叠法(Temporal anti-aliasing https://en.wikipedia.org/wiki/Temporal_anti-aliasing用在虚幻引擎中),尽管它不是一个完全的边缘平滑处理技术,但是能使得给定的边缘一个平滑的表面。
4、延迟光照(内容有争议)
延迟光照是延迟渲染的修订。这个技术在延迟渲染的时候使用了3个通道,而不是2个。第一个通道覆盖了场景几何体,仅仅将计算每个像素照明所必需的属性写入几何缓冲区。在屏幕空间,“延迟”通道然后输出仅仅漫反射和高光反射光数据信息,因此,必须在场景上进行第二遍,以回读光照信息和最终输出的逐像素渲染。延迟光照最明显的优点是动态的减少了几何缓冲区的大小。最明显的成本就是需要渲染场景几何体两次而不是一次。另外一个额外的消耗是在延迟光照的延迟通道必须单独输出漫反射和镜面反射,然而延迟渲染的延迟通道仅仅需要输出一个两者组合的辐射值。
由于几何缓冲区的大小的减少技术,部分克服了延迟着色的一个严重缺点—多个材质。
5、Unity中的延迟渲染
当使用延迟渲染,影响一个游戏物体的光照的光源数量没有限制。所有光源都是逐像素评估,这就意味着它们都与法线贴图进行正确的交互。另外,所有光源都有Cookies和阴影。
它要求显卡具有MRT(多渲染目标),渲染模型3.0或者更高,并且支持深度渲染纹理。在2006年之后的PC显卡都支持延迟渲染技术,如GeForce 8xxx、Radeon x2400和Intel G45。在手机端,延迟渲染是不支持的。
(注:延迟渲染在正交摄像机模式下也是不支持的,如果摄像机切换到了正交模式之后就会默认使用正向渲染)
延迟着色中的实时渲染开销与由光照射的像素的数量成比例,并且不依赖于场景复杂度。因此,小小的点光源和聚光源都是开销非常小的渲染,特别是不会穿过摄像机的近平面的点光源和聚光源,渲染开销就更小。另外,带阴影的光源比不带阴影的光源开销要更高。因为在延迟渲染中,阴影投射到的物体上需要为每个阴影投射光渲染一次或多次。三、延迟着色渲染(Forward Rendering)
1、介绍
正向渲染是标准的多数引擎使用的白箱渲染技术,给图形渲染硬件提供几何图形数据,最后转换并分割为片段或像素,在传递到屏幕之前进行最终渲染。它是线性的,几何图形一个一个的传递到管线中以产生最终图像。
正向渲染对一个对象会在多个通道上进行渲染,并且渲染取决于影响物体的光源。光源本身也会根据其设置和强度在进行正向渲染的时候进行不同的处理。
2、Unity中使用它
在正向渲染中,影响每个对象的一些数量的最亮的光源以完全每个像素光照模式渲染。然而,每个顶点最多计算4个点光源。其他光源被计算成球面谐波(Spherical Harmonics),这是更快,但只是一个近似。一个光源是否进行逐像素光照主要依靠以下几点:
●当光源的渲染模式被渲染成Not Important,则光源是进行逐顶点计算或者SH
●最亮的直光源是总是逐像素
●光源渲染模式设置为Important总是逐像素光照
●如果在Quality Setting里面设置的光源数量在上述设置中超过了,那么超过的光源按照亮度的顺序逐像素的渲染。
比如,如果一个物体的渲染被如图2.1所示的A—H的光源影响。假设A到H的光源都有同样的颜色和强度并且渲染模式都是Auto,那么这些光源将按照距离远近的顺序进行排序最后渲染。最近的光源,也即是最亮的光源将被作为逐顶点渲染
如图2.2所示为各个光源的渲染模式。
(注意:光源的重叠)
2.1:影响游戏对象的周围光源
2.2:影响游戏对象的周围光源的渲染
3、性能
●正向渲染是计算物体的顶点而不是像素,这就意味着它们不支持光源Cookies和法线贴图映射。
●球谐波是非常低频的方法。你不能用球谐波渲染进行快速的转换。它们也仅仅影响漫反射光源以及非常低频的高光反射。
●球谐波不是局部的;点或者聚光源靠近一些表面的时候会产生混乱和模糊。
总得来说,球谐波是非常适合一些动态的物体。
四、Unity中其他的渲染路径
1、传统延迟光照渲染(Legacy Deferred LightingRendering Path)
这是随着Unity5.0遗留下来的延迟光照特性,新的工程都应该考虑使用前面讲的延迟渲染。
2、顶点光照渲染(Vertex Lit Rendering Path Detail)
顶点光照渲染通常渲染每一个物体都在一个通道上,计算在物体每个顶点上的所有光源的光。这是最快的渲染方式,并且有着最为广泛的硬件支持。(当然不能工作在控制台上)。因为,所有的光照计算都发生在顶点着色器上,因此这个渲染方式不能计算许多逐像素的效果,比如,阴影、法线映射以及光源Cookies