Unity3D-Rendering Paths(渲染路径)及LightMode(光照模式)
简述
U3D支持不同的Rendering Path(渲染路径),开发者应该根据游戏内容和目标平台,硬件等来选择使用哪个Rendering Path。不同的Rendering Path具有不同的表现效果,这些不同之处多体现在光照和阴影方面。查阅Render Pipeline获取更多的细节。
可以在Editor-->Project Setting-->Graphics中设置默认的Rendering Path,也可以针对单独的Camera进行设置。
如果目标平台的显卡不能处理所选择的硬件,那么Unity会自动过渡至低保真档次Rendering Path去。比如有的GPU不能处理Deferred Shading,那就会自动采用Forward Rendering。
下面按从高效果至低效果的顺序开始讲解不同的Rendering Path。
Deferred Shading Rendering Path
概述
由于在移动开发中并不常用Deferred Shading,故本节不细述。
Shader中使用的LightMode Pass Tag: Deferred
Deferred Shading拥有最佳的光照和阴影效果。当场景中存在许多的实时光照时,使用Deferred Shading也是最佳的方案。当然Deferred Shading对硬件的要求稍高。
Deferred Shading是一种屏幕空间着色技术,之所以叫做Deferred(延迟的,延期的),是因为Shading的时机不是发生在第一个Pass的Vertex和Pixel/Fragment函数内,而是存在延迟,直到第二Pass的时候才执行。
Deferred Shading对影响物体的光源数量没有限制,所有的光源都是Per-Pixel(逐像素)光照,即所有光源都可以正确的和法线贴图得到正确的计算结果。另外,所有的光源都可以有Light Cookie和阴影。其性能开销与光源数量成正比,这意味着可以通过控制光照面积,减少单个物体受到光照影响的数量来获得性能方面的提升。Deferred Shading的另一个优点是结果能够很方便的预测,被个光源都是逐像素光照,具有一致的光照计算过程。
缺点在于,其不能真正的支持抗锯齿以及半透明物体(半透明物体是用 Forward Rendering 渲染路径)。同时也不支持Unity3D中的Mesh Renderer组件的Receive Shadows功能,对Culling Masks的支持也不完善,最多能使用四个Culling Mask。
Q: 什么是Light Cookie?
A: Light Cookie又被称作Cucoloris。是一种应用在电影摄制时的小技巧,如下两张图,具体的解释可以查看Wiki,Unity3D中的应用可以查看Unity3D Cookies手册或Unity3d Spot Light Cookie,Unity3D中的实现视频过程可以点击这里:
要求
显卡应支持Multiple Render Targets(MRT),Shader Model 3.0(及更高),Depth Render Textures。大多数产于2006年以后的PC显卡都支持本功能。
因为对MRT功能支持的缺失,本功能在移动端不受支持。(有的GPU支持,但是支持的程度也非常有限。)
注意:当使用Orthographic projection(正交投影)时Deferred rendering不适用。当使用正交投影时会降至 Forward Rendering。
性能方面
性能方面的影响取决于物体受光源影响的数量,而不是场景的复杂度。小面积的点光源或聚光灯,或光源被部分或完全摭挡,可以在很好的降低性能开销。
有阴影的光源开销更大,在Deferred rendering中,受到投影光源影响的,且可投影的物体依然是要对影响其的每个投影光源都进行计算。具有阴影的光照Shader也肯定比没有阴影的开销更大。
Forward Rendering Rendering Path
概述
Shader中使用的LightMode Pass Tag: ForwardBase和ForwardAdd
当Forward不可以用时会以Legacy Vertex Lit Rendering Path的效果进行渲染
Forward是传统渲染路径。支持所有的Unity图形特性。在默认情况下,只有少数最亮的光源得以成为Per-Pixel光源。其他的光源则视为Per-Vertex。
取决于影响物体的光源数量,Forward 在单个或多个Pass内渲染物体。需要注意的是,光源根据设置或强度的不同,本身也会具有不同的特性。
使用指南
Forward下,一些(视Quality Setting里面的设置而定)最亮的光源渲染物体时以Per-Pixel的方式进行。紧接着可有四个光源为Per-Vetex光源。其余的光源都以球谐函数(SH:Spherical Harmonics)进行计算,可以高效但是粗略的得到计算结果。无论光源是不是Per-Pixel的都依赖以下规则:
- 光源的Render Mode设为Not Important的,则不是Per-Pixel光源
- 最亮的平行光是Per-Pixel光源
- 光源的Render Mode设为Important的,则为Per-Pixel光源
- 如果场景中的per-pixel光源数量少于Quality Setting中的Pixel Light Count设置的数量,则会按光照强度从强至弱的顺序,将更多的光源设置为per-pixel。
渲染每个物体时会依以下规则:
- Base Pass只会用到一个per-pixel光源,以及所有其它Per-Vertex光源或SH光源
- 其它的per-pixel光源则在Additional Pass中渲染,并且每个Pass对应一个per-pixel光源
例如有物体受到如下A-H光源的影响:
假设所有光源都有相同的强度和颜色,并且Render Mode都设为Auto。最亮的4个光源A-D则为per-pixel光源,接着是四个per-vertex光源,D-G,最后余下的光源则是SH球谐光源,G-H。
注意上图中光源分组的重叠部份。例如最后一个既可以成为per-pixel光源也可以成为per-vertex光源,因此当物体或光源移动时,产生Light Popping(因光照导致的画面不正常)的可能性更小。
关于Light Popping问题的实例,点击这里 ,提问者最后通过调整光照亮度得以解决。
Base Pass
Base Pass只用一个per-pixel光源和所有的SH/Vertex 光源来渲染物体。在这个pass内也能通过shader加入光照贴图(Lightmaps),环境光(ambient),自发光(Emissive)等。平行光在这个Pass内产生阴影。
注意:
- 使用LightMaps的物体(烘培过的物体)不会受到SH光源的光照。
- 当在Shader中使用Passflag tag “OnlyDirectional”时,forward base pass只会渲染主平行光,环境光照探头(Ambient/Light Probe)和光照贴图,SH和vertex光源没有被包含在此pass的数据内。
Additional Passes
Additional Passes用于渲染每个额外的per-pixel光源。在这些pass中的光源默认是不会产生阴影的(也就是说,Forward Rendering默认只支持一个光源可以产生阴影)。除非使用multi_compile_fwdadd_fullshadows宏。
性能相关
Spherical Harmonics lights(球谐光照)非常高效。对CPU的消耗极其微小,对于GPU来说不会有额外的负担(因为base pass原本就会一直计算SH Lighting;和球谐光照的机制有光,无论有多少球谐光的存在,消耗都是一样的)。
扩展阅读,Enlighten的简化球谐光照文档,《球谐照明:细节》,《球谐照明:细节》讲义,球谐照明原理
SH光照的缺点:
- 利用物体的vertices(Vertex单词的复数形式,Vertex的复数有三种写法: vertexes,vertices ,vertexs)进行计算,而不是pixels。因此不支持法线贴图和Light Cookies。
- SH光照函数是种非常低频的照明函数,不会有非常锐利的照明过渡,另外也只会响应Diffuse Lighting(漫反射),对于Specular Highlight(镜面高光)而言其频率太低了。
- SH lighting is not local; point or spot SH lights close to some surface will “look wrong”. 球谐照明不是局部的(?局部坐标系?),点光源或聚光灯形式的SH Light在靠近一些表面时看上去会不正常。
总结,SH Light适用于小型动态物体。
Legacy Deferred Lighting Rendering Path
概述
Shader中使用的LightMode Pass Tag: PrepassBase和PrepassFinal
Legacy Deferred (light prepass) 类似于Deferred Shading,但是和其运用了不同的技术,有不同的侧重。不支持Unity5的Physically Based Standard Shader。关于Legacy Deferred的原理可以查看RTR(Real-Time Rendering)网站的文章《Deferred lighting approaches》
Deferred Lighting从Unity 5.0起被视为传统特性,因为其无法支持诸如Stander Shader,Reflection Probes等特性。新工程可以考虑直接使用 Deferred Shading(不适用于移动平台)。
注意:当使用Orthographic projection时Deferred Rendering Path 不适用。当使用正交投影时会降至 Forward Rendering Path。
注意:Legacy Deferred Lighting Rendering Path 和 Deferred Shading Rendering Path 都是Deferred rendering。
Deferred Lighting对影响物体的光源数量没有限制,所有的光源都是Per-Pixel光照,即所有光源都可以正确的和法线贴图得到正确的计算结果。另外,所有的光源都可以有Light Cookie和Shadow。其性能开销与光源数量成正比,这意味着可以通过控制光照面积,减少单个物体受到光照影响的数量来获得性能方面的提升。Deferred Lighting的另一个优点是结果能够很方便的预测,被个光源都是逐像素光照,具有一致的光照计算过程。
其缺点在于不能真正的支持抗锯齿以及半透明物体(半透明物体采用 Forward Rendering 渲染路径)。同时也不支持Unity3D中的Mesh Renderer组件的Receive Shadows功能,对Culling Masks的支持也不完善,最多能使用四个Culling Mask。
要求
显卡应支持Shader Model 3.0(或更新的版本),Depth Render Textures,Two-sided Stencil Buffers。大多数产于2004年以后的PC显卡都支持本功能。
在手机端,所有支持OpenGL ES 3.0r GPU都支持Deferred Lighting. 部份OpenGL ES 2.0的GPU也能支持(因为支持Depth Textures)。
注意:当使用Orthographic projection(正交投影)时Deferred rendering不适用。当使用正交投影时会降至 Forward Rendering。
性能方面
性能方面的影响取决于物体受光源影响的数量,而不是场景的复杂度。小面积的点光源或聚光灯,或光源被部分或完全摭挡,可以在很好的降低性能开销。
有阴影的光源开销更大,在Deferred Rendering中,受到投影光源影响的,且可投影的物体依然是要对影响其的每个投影光源都进行计算。具有阴影的光照Shader也肯定比没有阴影的开销更大。
使用指南
使用Deferred Lighting, 渲染过程发生在三种Pass内。
- Base Pass:物体产生screen-space buffers, 包含depth, normals, specular power等信息。
- Lighting Pass:前一阶段生成的Scree-space buffers用来计算光照,并放入另一个screen-space buffers。
- Final Pass:物体再次被处理,取得前一阶段计算的光照信息,结合色彩纹理,并添加ambient/emissive Lighting。
如果物体使用了不适用于Deferred Lighting Rendering Path的Shader,会使用Forward rendering path
Base Pass
Base pass会对物体进行一次处理。View sapce normals(视野空间法线)和Specular Power(高光强度)被处理为一张ARGB32格式的[Render Texture](RGB值为normals, A为Specular Power)。如果目标平台和硬件允许Z buffer以纹理的形式读取,则不用再进行额外的渲染流程。反之,则要在另一个Pass使用Shader Replacement的Shader中进行处理。
Lighting Pass
lighting passs根据Depth,Normal和Specular power来计算光照。光照计算发生在Screen Space(屏幕空间)中,因此时间消耗取决与场景的复杂程度。Lighting Buffer是一张ARGB32的Render Texture,Diffuse Lighting使用其RGB通道,Specular Lighting使用其A通道。
Final Pass
处理纹理,自发光等其它内容,另外,光照贴图也在这里完成。
Legacy Vertex Lit Rendering Path
Shader中使用的 使用的LightMode Pass Tag: Vertex,VertexLMRGBM和VertexLM
效果最差,不支持实时阴影。属于Forward Rendering Path的子集。是性能最高,受支持度最多的Rendering Path(但是主机上不适用)。
所有的光照计算在Vertex层面完成,因此无法支持大多数的per-pixel效果,比如,阴影,法线贴图,Light Cookies,精细的高光效果。
LightMode Tags
光照模型 Tags
光照模型 tag定义了pass通道在光照计算管道的角色,看一下下列渲染管道的细节,这些tags很少手动调用,大多数情况下只需要把光照交互的着色器改为Surface Shaders,然后所有这些细节都会被自动处理掉。
LightMode tags:
Always: Always rendered; no lighting is applied.
ForwardBase: Used in Forward rendering, ambient, main directional light, vertex/SH lights and lightmaps are applied.
ForwardAdd: Used in Forward rendering; additive per-pixel lights are applied, one pass per light.
Deferred: Used in Deferred Shading; renders g-buffer.
ShadowCaster: Renders object depth into the shadowmap or a depth texture.
PrepassBase: Used in legacy Deferred Lighting, renders normals and specular exponent.
PrepassFinal: Used in legacy Deferred Lighting, renders final color by combining textures, lighting and emission.
Vertex: Used in legacy Vertex Lit rendering when object is not lightmapped; all vertex lights are applied.
VertexLMRGBM: Used in legacy Vertex Lit rendering when object is lightmapped; on platforms where lightmap is RGBM encoded (PC & console).
VertexLM: Used in legacy Vertex Lit rendering when object is lightmapped; on platforms where lightmap is double-LDR encoded (mobile platforms).
Rendering Paths Comparison
- | Deferred | Forward | Legacy Deferred | Vertex Lit |
---|---|---|---|---|
Features | ||||
Per-pixel lighting (normal maps, light cookies) | Yes | Yes | Yes | - |
Realtime shadows | Yes | With caveats | Yes | - |
Reflection Probes | Yes | Yes | - | - |
Depth&Normals Buffers | Yes | Additional render passes | Yes | - |
Soft Particles | Yes | - | Yes | - |
Semitransparent objects | - | Yes | - | Yes |
Anti-Aliasing | - | Yes | - | Yes |
Light Culling Masks | Limited | Yes | Limited | Yes |
Lighting Fidelity | All per-pixel | Some per-pixel | All per-pixel | All per-vertex |
Performance | ||||
Cost of a per-pixel Light | Number of pixels it illuminates | Number of pixels * Number of objects it illuminates | Number of pixels it illuminates | - |
Number of times objects are normally rendered | 1 | Number of per-pixel lights | 2 | 1 |
Overhead for simple scenes | High | None | Medium | None |
Platform Support | ||||
PC (Windows/Mac) | Shader Model 3.0+ & MRT | All | Shader Model 3.0+ | All |
Mobile (iOS/Android) | OpenGL ES 3.0 & MRT | All | OpenGL ES 2.0 | All |
Consoles | XB1, PS4 | All | XB1, PS4, 360 | - |