简介:

Vertex Lit path通常在一个pass里渲染每个物体,在物体顶点计算所有灯光的光照。每个顶点的光照计算出后,会对灯光进行插值,所以多边形效果很明显。

这是最快的渲染路径,并支持硬件最广泛。

因为所有光照都是计算在顶点的,这个通道并不支持逐像素效果:阴影,法线贴图,light cookies,高度细节贴图等都不支持。


参考:
Vertex Lit Rendering Path Details

注意

  1. Deferred Lighting在Unity5.0后被认为是遗留功能,因为它不支持一些渲染特性(比如Standard shader, reflection probes)。新的项目推荐使用Deferred Shading渲染通道代替。

  2. 当相机是Orthographic投影,并不支持Deferred模式。会被处理为Forward rendering模式。

预览

当时用Deferred Lighting,影响物体的光源没有数量限制。所有灯光都是逐像素计算,意味着都可以正确的与法线贴图交互等等。另外所有灯光都可以有cookies和阴影。

Deferred lighting的优势是处理消耗和灯光照亮的像素数成正比。这只与灯光体积有关而与它照到的物体数量无关。因此保持较小的光体积可以提高性能。因为它是逐像素计算光照,所以不像顶点着色多边形明显,不真实。

但缺点是,deferred shading并不真正支持抗锯齿,也不能处理半透明物体(这是在forward rendering中处理)。也不支持Mesh Renderer的Receive Shadows标志,而且只能使用4个culling masks。

需求

需要Shader Model 3.0及以上,支持Depth render textures和two-sided stencil buffers,2004年后的大部分的pc都支持。移动平台上,所有兼容OpenGL ES 3.0的GPU都支持deferred lighting。

性能考量

灯光的渲染开销与灯光照射的像素数有关而与场景的复杂度无关。所以小的点光或聚光开销很少,而如果它们被场景物体全部或部分挡住,开销会更少。

当然,使用阴影的灯光更加消耗性能。在deferred lighting中,对每个阴影投射灯光,阴影投射的物体仍需要被渲染一次或多次。此外,应用了阴影的灯光shader拥有更多渲染开销。

实现细节

当时用deferred lighting,渲染过程发生在三个通道:

  • Bass pass:渲染生成屏幕空间缓冲信息:depth, normals, 和specular power.
  • Lighting pass:使用上面计算的缓冲来计算灯光到另一个屏幕空间缓存。
  • Final pass:物体再次被渲染。获取上面计算的光照和贴图再加上环境光/自发光等等混合在一起。

不能使用deferred shading的物体,会在这个过程完成后使用forward渲染路径。

  • Base Pass
    渲染每个物体一次。视图空间法线和specular power会被渲染为一个ARGB32的Render Texture,法线使用RGB通道,specular power使用A通道。如果平台允许Z缓存从贴图读取,那么深度值不会明确的渲染。如果深度不能从贴图读取,那么深度会使用shader replacement在额外的通道渲染。

    Base Pass的结果就是把场景信息和一张包含normal与specular power信息的Render Texture 填充在z buffer中。

  • Lighting Pass
    Lighting pass 根据depth, normals and specular power计算光照值。灯光在屏幕空间中计算,所以消耗时间与场景复杂度无关。灯光缓存是一个ARGB32 Render Texture,包含使用RGB通道的diffuse lighting和使用A通道的单色specular lighting。灯光值是用对数编码的,以提供相对于使用ARGB32 texture更大的动态范围。当摄像机开启了HDR rendering,那么灯光缓存会使用ARGBHalf格式,而且不会使用对数编码。 不穿过相机近平面的点光和聚光就像3D图形一样根据z缓冲测试被渲染。穿过近平面的光也会想3D图形一样渲染,但是背面的面使用相反的深度测试。这会使部分或全部被堵住的点光/聚光渲染消耗很低。如果一个灯光既与相机近平面又与远平面相交,那么上面的优化方法就不能使用,灯光会被渲染为没有深度的紧密四边形。

    以上并不适用于方向光,方向光总会渲染为全屏四边形。

    如果一个灯光开启了阴影那么也会在这个pass渲染。

    唯一允许的灯光模型是Blinn-Phong。如果lighting pass shader想使用不同的光照模型,可以把修改过的内建Internal-PrePassLighting.shader文件放到Resources文件夹。然后到Edit->Project Settings->Graphics窗口,更改Deferred到Custom Shader。

  • Final Pass
    Final Pass产生最终的渲染贴图。获取灯光并混合贴图与额外的发散光来渲染所有物体。光照贴图也会在这个通道应用。相机离得近的地方进行实时光照,只烘焙 indirect lighting。相机离得远的地方,全部烘焙。


参考:
Legacy Deferred Lighting Rendering Path

Forward Rendering Path 根据影响物体的灯光,在一个或多个通道中渲染每个物体。根据每个灯光的设置和强度,每个灯光也被Forward Rendering不同对待。

实现细节

在正向渲染中,一些影响物体的最亮的灯会被逐像素模式渲染。然后,最多4个点光会逐顶点渲染。其他灯光则被计算为Spherical Harmonics(SH),这样速度更快但只是一种近似值。一个灯光是否是逐像素灯光取决于:

  • 渲染模式设置为Not Important的灯光始终是逐顶点或SH。
  • 最亮的灯光总是逐像素的。
  • 渲染模式为Important的灯光总是逐像素的。
  • 如果上面的总结出的灯光数量少于Quality Setting中设置的Pixel Light Count,那么多出数量的灯光会按亮度减少的顺序逐像素渲染。

对每个物体的渲染如下:

  • 根据Pass应用一个逐像素方向光和所有的逐顶点/SH光。
  • 其他逐像素光是在额外的pass渲染,每个pass对应一个灯光。

比如,有一些物体收到多个灯光(A-H)影响的物体:

我们假设灯光A-H都是同样的颜色和强度并且都设置为Auto rendering mode,所以它们都只会按照距离物体的远近来排序。最亮的光会被渲染为逐像素模式(A-D),然后最多4个光为逐顶点(D-G),然后最后剩下的光是SH(G-H):

注意灯光组的重叠,比如最后一个逐像素光源也以逐顶点光照模式的方式渲染,这样能减少当物体和灯光移动时可能出现的”光照跳跃”现象。

Base Pass

Base pass使用一个逐像素方向光和所有SH光渲染物体。此通道还负责渲染着色器中的 lightmaps, ambient 和 emissive lighting。在此通道中渲染的方向光可以产生阴影。需要注意的是,使用了光照贴图的物体不会得到SH光的光照。

Additional Passes

附加通道用于渲染影响物体的其他逐像素光源。这些通道中渲染的光源无法产生阴影(因此, Forward Rendering只支持一个能产生阴影的方向光)。

性能考量

渲染球面调和(SH)光很快。它们只花费很少的CPU计算时间,并且实际上无需花费任何GPU计算时间(换言之,基础通道会计算所有SH光照,但由于SH光的计算方式,无论有多少SH光源,计算它们所花费的时间都是相同的)。

球面调和光源的缺点有:

  • 它们计算的是物体的顶点而不是像素。这意味着它们不支持light Cookies和normal maps。
  • 球面调和光只有很低的频率。球面调和光不能产生锋利的照明过渡。它们也只会影响散射光照(对高光来说,球面调和光的频率太低了)。
  • 球面调和不是局部的,靠近曲面的球面调和点光和聚光可能会”看起来不正确”。

总的来说,球面调和光的效果对小的动态物体来说已经足够好了。


参考:
Forward Rendering Path Details

概览

当使用Deferred Shading,对于灯光可以影响的物体数量没有限制。所有灯光基于每个像素评估,即意味着它们都与法线贴图交互正常等。所有灯光都可以有cookies 和阴影。

Deferred shading的优势是灯光处理开销是和灯光照射到的像素数成比例的。这是由场景中灯光体积决定的,而与灯光照射多少物体无关。因此,让灯光小一些可以提高性能。Deferred shading也拥有高度统一和可预测的行为。每个灯光是逐像素计算的,所以在大三角形面上也不会有灯光计算失误。

但是另一方面,deferred shading并不真正支持抗锯齿,也不能处理半透明物体(这是在forward rendering中处理)。也不支持Mesh Renderer的Receive Shadows标志,而且对于culling masks也有限制。只能使用4个culling masks。意味着 ,你的遮挡层最多只有四个,即28-32的layers 必须被设置。

要求

需要图形卡支持Multiple Render Targets(MRT),Shader Model 3.0及以后,支持深度渲染贴图和双面模板缓存。大部分2005年之后的显卡都支持延迟光照。对于移动平台,支持更有限因为MRT格式的使用。

注意:延迟渲染不支持Orthographic 投影。

性能考量

前面说过,deferred shading中灯光的渲染开销与灯光照射的像素数有关而与场景的复杂度无关。所以小的点光或聚光开销很少,而如果它们被场景物体全部或部分挡住,开销会更少。

当然,使用阴影的灯光更加消耗性能。在deferred shading中,对每个阴影投射灯光,阴影投射的物体仍需要被渲染一次或多次。此外,应用了阴影的灯光shader拥有更多渲染开销。

实现细节

Deferred shading的基本思想是分两步进行:第一步,场景在不进行光照模型运算的情况下渲染,然后将每个像素的位置、法线、高光颜色等数据存储在中间缓存区,叫做G-buffer(G是geometry)。第二步,从G-buffer中读取信息,应用反射模型,计算出每个像素的最终颜色,即每个光源使用G-buffer数据将以一个2D后期处理的方式施加到最终图像上。 这种技术是我们避免了应用光照模型在最终不可见的片段上。对于屏幕上的每个像素,反射模型的计算只会发生一次。 这其实就是OpenGL中的帧缓存处理。

当使用Deferred Shading,Unity的渲染过程发生在两个passes:

  1. G-buffer Pass:物体使用 diffuse color, specular color, smoothness, world space normal, emission and depth 来渲染产生屏幕空间的缓存。
  2. Lighting pass:前面生成的缓存用于增加灯光到emission缓存。

不能使用deferred shading的物体,会在这个过程完成后使用forward渲染路径。

默认的g-buffer布局如下:

  • RT0, ARGB32 格式:Diffuse color (RGB), unused (A).
  • RT1, ARGB32 格式: Specular color (RGB), roughness (A).
  • RT2, ARGB2101010(30BIT) 格式: World space normal (RGB), unused (A).
  • RT3, ARGB32 (non-HDR) 或 ARGBHalf (HDR) 格式: Emission + lighting + lightmaps + reflection probes buffer.
  • Depth+Stencil buffer.

所以默认g-buffer布局是160位每像素(非HDR)或192位每像素(HDR)。

Emission+lighting(RT3)是对数编码的,在非相机HDR时,相比通常使用的ARGB32 texture会提供更大的动态范围。 注意当摄像机使用HDR 渲染,将没有为 Emission+lighting buffer (RT3) 创建的单独渲染目标,反而相机将要渲染的目标会使用RT3。

  • G-Buffer Pass
    g-buffer pass渲染每个物体一次,Diffuse 和 specular 颜色, surface smoothness, world space normal, emission+ambient+reflections+lightmaps 会渲染进g-buffer贴图。g-buffer texture 是设置为全局shader属性,便于之后shader获取。

  • Lighting Pass
    Lighting Pass根据g-buffer和depth计算光照。光照是在屏幕空间计算的,所以它处理的时间是和场景复杂度无关的。灯光是添加到emission buffer。

    不穿过相机近平面的点光和聚光就像3D图形一样根据z缓冲测试被渲染。这会使部分或全部被堵住的点光/聚光渲染消耗很低。直光和穿越了相机近平面的点/聚光就会被渲染为全屏四边形。

    如果灯光开启了阴影,那么它们也会被渲染并应用在这个pass。阴影并不是“免费”的,阴影投射器也需要被渲染而且需要使用更复杂的shader。

    唯一可用的灯光模型就是Standard。如果你想用不同的模型,你可以修改 lighting pass shader,通过把修改过的内建Internal-DeferredShading.shader文件放到Resources文件夹。然后到Edit->Project Settings->Graphics窗口,更改Deferred到Custom Shader。


参考:
Deferred Shading Rendering Path

Rendering Paths

Unity支持不同的渲染路径,你可以根据你的游戏内容和目标平台选择合适的使用。不同渲染路径有不同的表现特征,区别主要体现在灯光和阴影上。

Unity中可以在Player Setting设置渲染路径,也可以为每个摄像机单独设置。
Unity共支持四种渲染路径:

  • Deferred Shading
    这是灯光和阴影效果最真实的渲染路径,最适合有许多实时灯光的情况。需要一定水平的硬件支持。

  • Forward Rendering
    这是传统的渲染路径,支持所有典型的图形特性(法线贴图,像素光照,阴影等)。然而,在默认设置下,只有少数最亮的灯光可以使用逐像素光照模式,其他灯光对每个物体使用逐顶点计算。

  • Legacy Deferred
    Legacy Deferred (light prepass)与Deferred类似,根据权衡使用了不同技术。不支持Unity5的基于物理标准shader。

  • Legacy Vertex Lit
    这是最低真实度的渲染路径,不支持实时阴影。是 Forward rendering path 的子集。

注意,当摄像机为Orthographic投影,不能使用 Deferred rendering 。如果使用Orthographic,总会使用Forward rendering。

Unity’s Rendering Pipeline

shaders既定义了一个物体自身如何显示(它的材质属性)也定义了它如何反应灯光。因为灯光计算必须在shader中构建,而且有许多不同的灯光和阴影类型,所以写出正好合适的shader是复杂的工作。为了使这个过程更简单,Unity拥有Surface shader,所有的灯光、阴影、光照贴图都会自动的处理为forward或是deferred。

  • Rendering Paths
    灯光如何应用和哪个pass被使用,是依据Rendering path决定的。每个pass通过pass tag传达它的灯光类型。

    • Forward Rendering:ForwardBase 和 ForwardAdd pass会被使用。
    • Deferred Shading:Deferred pass被使用。
    • legacy Deferred Lighting:PrepassBase 和 PrepassFinal passes 被使用。
    • legacy Vertex Lit:Vertex, VertexLMRGBM 和 VertexLM passes 被使用。
    • 如果不包括上述任何情况,为了渲染阴影和深度贴图,ShadowCaster pass 被使用。
  • Forward Rendering path
    ForwardBase pass 一次渲染ambient, lightmaps, 主要的 directional light 和不重要的(vertex/SH)灯光。ForwardAdd pass 用与额外的逐像素灯光,每个被这个灯光照明的物体调用一次。 如果forward rendering 使用了,但并没有合适的pass,物体会渲染为和使用Vertex Lit path一样。

  • Deferred Shading path
    Deferred pass 为灯光渲染所有需要的信(对于内建shader:diffuse color, specular color, smoothness, world space normal, emission)息。还会添加光照贴图,reflection probes 和 ambient lighting 到emission通道。

  • Legacy Deferred Lighting path
    PrepassBase pass 渲染法线和高光指数;PrepassFinal pass 渲染最终颜色,通过混合贴图、灯光和emissive材质属性。场景内的灯光分别的在屏幕空间完成。

  • Legacy Vertex Lit Rendering path
    因为顶点光照多用于不支持可编程shader的平台,Unity不能内部创建多个shader变体来处理 lightmapped vs. non-lightmapped 的情况。所以为了处理 lightmapped 和 non-lightmapped 物体,必须要编写多个passes。

    • Vertex pass: 用于non-lightmapped 物体。一次渲染所有灯光,使用固定函数光照模型(Blinn-Phong)。
    • VertexLMRGBM pass: 用于 lightmapped 物体,当光照贴图是RGBM编码(PC和主机)。没有实时光照应用,pass用于混合贴图和光照贴图。
    • VertexLMM pass: 用于 lightmapped 物体,当光照贴图是double-LDR编码(移动平台)。没有实时光照应用,pass用于混合贴图和光照贴图。

参考:
Rendering Paths
Unity’s Rendering Pipeline