渲染路径(Rendering Path)
渲染路径决定了光照如何应用到Shader中,决定了把光源信息和处理后的光照信息放到那些数据中。


四种渲染路径设置 :
- Deferred(延迟渲染)
- Forward(前向渲染)
- Legacy Vertex Lit(遗留顶点照明渲染)
- Legacy Deferred(light prepass)(遗留延迟渲染)
Unity会优先执行Shader中符合当前渲染路径的Pass,例如设置了Deferred(延迟渲染)。
- 优先执行Shader中Pass的LightMode为Deferred(延迟渲染)路径的Pass。
- 如果没有符合条件的Pass,寻找低一级Shader中Pass的LightMode为Forward(前向渲染)路径的Pass。
- 如果没有符合条件的Pass,寻找低一级Shader中Pass的LightMode为Legacy Vertex Lit(遗留顶点照明渲染)路径的Pass。
Shader在同一时间内,只会执行一个渲染路径下的Pass。
Shader指定某个Pass使用什么渲染路径,通过标签LightMode设置。
标签 | 描述 |
Always | 不管使用什么渲染路径,该Pass都会被渲染,但不会计算任何光照 |
ForwardBase | 用于前向渲染,该Pass会计算环境光,最重要的平行光,逐顶点/SH光源和Lightmaps |
ForwardAdd | 用于前向渲染,该Pass会计算额外的逐像素光源,每个Pass对应一个光源 |
Deferred | 用于延迟渲染,该Pass会渲染G缓冲(G-buffer) |
ShadowCaster | 把物体的深度信息渲染到阴影映射纹理或一张深度纹理中 |
PrepassBase | 用于遗留的延迟渲染,该Pass会渲染法线和高光反射的指数部分 |
PrepassFinal | 用于遗留的延迟渲染,该Pass通过合并纹理,光照和自发光来渲染得到最后的颜色 |
Vertex,VertexLMRGBM,VertexLM | 用于遗留的顶点照明渲染 |
当Shader中有"LightMode" = "Always"时:
- 当Shader中只有 "LightMode" = "Always"的Pass时,Shader中所有Pass无论在什么渲染路径下都按先后顺序执行。
- 当Shader处于Deferred(延迟渲染)路径下时候,Shader中的"LightMode" = "Always"的Pass不被执行。
- 当Shader处于Forward(前向渲染),和Legacy Vertex Lit(遗留顶点照明渲染)渲染路径下时,含有"LightMode" = "Always"的Pass的Shader,会根据Shader中其他Pass是否能在当前渲染路径下执行来决定"LightMode" = "Always"的Pass是否能被执行。如果其他Pass有能够执行的,"LightMode" = "Always"的Pass也能被执行。如果其他所有Pass不能被执行, "LightMode" = "Always"的Pass也不能被执行。 所有能执行的Pass会根据前后顺序执行,Shader中"LightMode" = "Always"的Pass之外的所有Pass都不执行,那"LightMode" = "Always"的Pass也不被执行。
Unity5.x后如果设置了前向渲染路径,Pass没有设置LightMode标签,就会被当做Legacy Vertex Lit(遗留顶点照明渲染)等同的Pass。
前向渲染路径
1.前向渲染路径原理
每进行一次完成的前向渲染,需要在一个Pass中渲染图元,并计算两个缓冲区。深度缓冲区决定片元是否可见,可见就更新颜色缓冲区颜色值。
对于每个逐像素光源,都需要一个Pass计算光照。一个物体如果受M个光源影响,就需要执行M个Pass,然后在帧缓冲中把这些光照结果混合得到最终颜色。如果一个场景有N个模型,每个模型受到M个光源影响,渲染这个场景需要 N * M 个Pass。因此渲染引擎会限制每个物体的逐像素光照数目。
2.Unity中的前向渲染
Unity中前向渲染有3中处理光照的方式:
- 逐顶点处理
- 逐像素处理
- 球谐函数处理
光源的类型和渲染模式决定了它被怎么处理。
- 光源类型是指该光源是平行光还是其他类型光源。
- 光源渲染模式是指该光源Render Mode属性
Pixel Light Count数量(Quality Setting)的光源会按逐像素处理,然后最多四个光源按逐顶点处理,剩下的按SH方式处理。
- 场景中最亮的平行光总是按逐像素处理
- Render Mode被设置成Not Important的光源,按逐顶点或SH处理。
- Render Mode被设置成Important的光源,按逐像素处理。
- 根据以上规则,逐像素光源大于Pixel Light Count数量(Quality Setting),光源会被当做逐顶点或SH方式处理。
- 最亮的平行光Render Mode被设置为Not Important一样会被当做逐顶点或SH方式处理。
前向渲染有两种Pass:
- Base Pass(LightMode = "ForwardBase")
- AdditionPass(LightMode = "ForwardAdd")
Unity前向渲染(LightMode = ForwardBase/ForwardAdd)内置光照变量和函数 :
变量名称 | 类型 | 描述 |
_LightColor0 | float4 | 该Pass处理的逐像素光源的颜色 |
_WorldSpaceLightPos0 | float4 | 该Pass处理的逐像素光照位置。如果_WorldSpaceLightPos0.w = 0,表示该光源是平行光,_WorldSpaceLightPos0.xyz是平行光的方向向量,反之表示光源为点光源,_WorldSpaceLightPos0.xyz为光源的世界坐标 |
_LightMatrix0 | float4x4 | 从世界空间到光源空间的变换矩阵,可以用于采样cookie和光强衰减纹理 |
unity_4LightPosX0 unity_4LightPosY0 unity_4LightPosZ0 |
float4 | 仅用于Base Pass,前4个非重要的点光源在世界空间中的位置 |
unity_4LightAtten0 | float4 | 仅用于Base Pass,存储了前4个非重要的点光源的衰减因子 |
unity_LightColor | half[4] | 仅用于Base Pass,存储了前4个非重要的点光源的颜色 |
函数名 | 描述 |
float3 WorldSpaceLightDir(float4 v) | 仅可用于前向渲染,输入一个模型空间的顶点位置,返回世界空间中从该点到光源的光照方向。内部实现使用了UnityWorldSpaceLightDir函数,没有归一化。 |
float3 UnityWorldSpaceLightDir(float4 v) | 仅可用于前向渲染,输入一个世界空间下的顶点位置,返回世界空间中从该点到光源的光照方向,没有被归一化。 |
float3 ObjSpaceLightDir(float4 v) | 仅可用于前向渲染,输入一个模型空间下的顶点位置,返回模型空间中从该点到光源的光源方向,没有被归一化。 |
float3 Shade4PointLights(...) | 仅可用于前向渲染,计算四个点光源的光照。它的参数是已经内置的光照数据。通常就像上表的 unity_4LightPosX0, unity_4LightPosY0 unity_4LightPosZ0,unity_4LightAtten0,unity_LightColor等等。 通常使用这个函数计算逐顶点的光照。 |
顶点照明渲染路径
通常只使用一个Pass(LightMode = Vertex),进行逐顶点光照计算。
顶点照明渲染中,最多可以计算8个逐顶点光源的光照。
顶点照明渲染路径中可用的内置变量和函数
变量名称 | 类型 | 描述 |