unity shader学习笔记(十三)——Unity中的复杂光照之渲染路径
2017-12-04 23:06
429 查看
Unity的渲染路径
渲染路径(Rendering Path)决定了光照是如何应用到shader中的。因此在shader中需要计算光照时就需要为每个Pass指定它使用的渲染路径。Unity中支持多种渲染路径,Unity5.0之前主要有3种:前向渲染路径(Forward Rendering Path)、延迟渲染路径(Deferred Rendering Path)和顶点照明渲染路径(Vertex Lit Rendering Path)。Unity5.0之后的版本中,顶点照明渲染路径被Unity抛弃,也用新的延迟渲染路径代替了原来的延迟渲染路径。在Unity中,可以在项目设置中选择渲染路径,也可以在摄像机中设置渲染路径,完成设置之后还可以在每个Pass中设置渲染路径,通过Pass的LightMode标签来实现。以下是Pass中的LightMode标签支持的渲染路径选项:
标签名 | 描述 |
---|---|
Always | 不管使用哪种渲染路径,总是会被渲染,但不计算任何光照 |
ForwardBase | 用于前向渲染,会计算光照、最重要的平行光、逐顶点/SH光源和LightMaps |
ForwardAdd | 用于前向渲染,会计算额外的逐像素光源、每个Pass对应一个光源 |
Deferred | 用于延迟渲染,会渲染G缓冲(G-buffer) |
ShadowCaster | 把物体的深度信息渲染到阴影映射纹理(shadowmap)或一张深度纹理中 |
PrepassBase | 用于遗留的延迟渲染,会渲染法线和高光反射的指数部分 |
PrepassFinal | 用于遗留的延迟渲染会通过合并纹理、光照和自发光来渲染得到最后的颜色 |
Vertex、VertexLMRGBM和VertexLM | 用于遗留的顶点照明渲染 |
前向渲染路径是传统的渲染方式,每进行一次前向渲染,需要渲染对应的渲染图元,计算两个缓冲区的信息,一个是颜色缓冲区,一个是深度缓冲区,利用深度缓冲来决定片元是否可见。对每个逐像素的光源都会进行这样的计算,如果有N逐像素光源,M个物体,那就需要N*M个Pass来执行,每个物体要使用多个Pass对应多个光源。那么,如果有大量光源,需要执行的Pass数目会非常大。因此,渲染引擎通常会限制每个物体的逐像素光源数目。
Unity中的前向渲染路径有三种处理光照方式:逐顶点处理、逐像素处理、球谐函数(Spherical Harmonics, SH)处理。而具体使用哪种模式是由光源的类型和渲染模式决定的。光源类型指的是平行光还是其他类型的光,而渲染模式是值该光源是否是重要的(Important)。在渲染物体时,Unity会跟根据各个光源的设置以及光源对物体的影响程度(如距离物体的距离、光源强度等)对光源进行重要度排序。一定数目的Important光源会按照逐像素处理,剩下的可以按SH方式处理。具体规则如下:
场景中最亮的平行光总是按照逐像素处理;
渲染模式被设置成Not Important的光源按照逐顶点或者SH处理;
渲染模式被设置成Important的光源,会按照逐像素处理;
如果以上得到的逐像素光源数量小于Quality Setting中设置的逐像素光源数量,会有更多的光源按照逐像素的方式处理。
前向渲染有两种Pass:Base Pase 和 Additional Pass。它们的设置及计算如下:
渲染方式 | 标签 | 光照计算 | 可实现的光照效果 |
---|---|---|---|
Base Pass | Tags{“LightMode”=”ForwardBase”} #pragma multi_complie_fwdbase | 一个逐像素的平行光以及所有的逐顶点和SH光源 | 光照纹理、环境光、自发光、阴影(平行光的阴影) |
Additional Pase | Tags{“LightMode”=”ForwardAdd”} Blend One One #pragma multi_complie_fwdadd | 其他影响该物体的逐像素光源每个光源执行一次Pass | 默认情况不支持阴影,但可以通过使用#pragma multi_complie_fwdadd |
#pragma multi_complie_fwdbase和#pragma multi_complie_fwdadd在官方文档中没有说明,但只有使用这俩个编译指令,才可以在相关的Pass中得到一些正确的光照变量,如光照衰减值。
Base Pass中可以访问光照纹理(lightmap)。
Base Pass中渲染的平行光是默认支持阴影的,而Additional Pass中默认是没有阴影效果的,可以使用#pragma multi_complie_fwdadd_fullshadows代替#pragma multi_complie_fwdadd编译指令,为点光源和聚光灯开启阴影效果,但这需要在Unity内部使用更多的Shader变种。
环境光和自发光在Base Pass中是计算的,如果咋Additional Pass中也计算,就会造成叠加多次的计算。
在Additional Pass中,需要开启和设置混合模式,因为Additional Pass的渲染结果会覆盖掉之前的渲染效果,看起来该物体只收该光源的影响,通常设置为Blend One One。
对于前向渲染,一个Unity Shader通常定义一个Base Pass以及一个Additional Pass。通常一个Base Pass只执行一次(定义了多个Base Pass除外,如双面渲染),而一个Additional Pass会根据影响该物体的逐像素光源数目被多次调用。
下面给出了在Unity中对于前向渲染可以在shader中访问到的光照变量:
名称 | 类型 | 描述 |
---|---|---|
_LightColor0 | float4 | 该Pass处理的逐像素光源颜色 |
_WorldSpaceLightPos0 | float4 | _WorldSpaceLightPos0.xyz是该Pass处理的逐像素光源的位置,如果是平行光,那_WorldSpaceLightPos0.w为0,其他光源为1 |
_LightMatrix0 | float4X4 | 从世界空间到光源空间的变换矩阵。可以用于采样cookie和光强衰减纹理 |
unity_4LightPosX0, unity_4LightPosY0,unity_4LightPosZ0 | float4 | 仅用于Base Pase。前4个非重要的点光源在世界空间中的位置 |
unity_4LightAtten0 | float4 | 仅用于Base Pase。存储了前4个非重要的点光源的衰减因子 |
unity_LightColor | half4[4] | 仅用于Base Pase。存储了前4个非重要的点光源的颜色 |
函数名 | 描述 |
---|---|
float3 WorldSpaceLightDir(float4 V) | 仅用于前向渲染中,输入一个模型空间中的顶点位置,返回世界空间中从该点到光源的光照方向。内部实现使用了UnityWolrdSpaceLightDir函数,没有归一。 |
float3 UnityWorldSpaceLightDir(float4 V) | 仅用于前向渲染中,输入一个世界空间中的顶点位置,返回世界空间中从该点到光源的光照方向。没有归一。 |
float3 ObjSpaceLightDir(float4 V) | 仅用于前向渲染中,输入一个模型空间中的顶点位置,返回模型空间中从该点到光源的光照方向。没有归一。 |
float3 Shade4PointLights(…) | 仅用于前向渲染中,计算四个点光源的光照,它的参数是已经打包进矢量的光照数据。如unity_4LightPosX0、unity_4LightPosY0、unity_4LightPosZ0、unity_lightColor和unity_4LightAtten0等。前向渲染通常会使用这个函数来计算逐顶点关照 |
顶点照明渲染路径要求少,性能高,但是效果差,它不支持逐像素才能实现的效果,如阴影、法线映射、高精度的高光反射等。而且它能实现的功能在前向渲染路径中都能完成。它只是用逐顶点的方式计算光照。
Unity中顶点照明渲染路径通常在一个Pass中完成。在这个Pass中所有的光源对该物体的照明都按照逐顶点处理,是最快速的渲染路径。在Unity中,我们在一个顶点照明的Pass中最多可以访问8个逐顶点光照,如果影响该物体的光源数目小于8,那么数组中剩下的光源颜色会设置为黑色。下面是顶点照明渲染路径在Unity中可以使用的内置变量:
名称 | 类型 | 描述 |
---|---|---|
unity_LightColor | hald[4] | 光源颜色 |
unity_LightPosition | float[4] | xyz分量是视角空间中的光源位置。如果光源是平行光,那么z分量为0.其他光源类型z分量值为1 |
untiy_LightAtten | half[4] | 光衰减因子,如果光源是聚光灯,x分量是cos(spotAngle/2),y分量是1/cos(spotAngle/4);如果是其他类型的光源,x分量是-1,y分量是1。z分量是衰减的平方,w分量是光源范围开根号的结果 |
unity_SpotDirection | float4[8] | 如果光源是聚光灯,值为视角空间的聚光灯的位置,否则,值为(0,0,1,0) |
函数名 | 描述 |
---|---|
float3 ShadeVertexLights(float4 vertex,float3 normal) | 输入模型空间中的顶点位置和法线,计算四个逐顶点光源的光照和环境光。背部调用了ShadeVertexLightsFull |
float3 ShadeVertexLightsFull(float4 vertex,float3 normal,int lightColor,bool spotLight) | 输入模型空间中的顶点位置和法线,计算lightCount个光源的光照以及环境光。如果spotLight值为true,那么这些光源会被当成聚光灯处理,更精确,但更加耗时,否则,按照点光源处理 |
当场景中包含大量光源时,前向渲染会对场景中的每个物体执行多个Pass来计算不同光源对物体的光照,因此会造成性能的急速下降。并且很多计算都是重复的。
而延迟渲染是一种更加古老的渲染方式,除了会使用颜色缓冲和深度缓冲之外,还会利用额外的缓冲区,就是G缓冲(G-Buffer),G缓冲存储了离蛇形迹最近的表面的信息,如该表面的法线、位置、用于光照计算的材质属性等。
延迟渲染路径主要包含两个Pass,在第一个Pass中,不进行光照计算,只计算哪些片元是可见的,主要通过深度缓冲来实现,对于可见的片元会将相关的信息存储到G缓冲中,然后在第二个Pass中利用G缓冲中的信息进行光照计算。
延迟渲染的好处就是,渲染使用的Pass就两个,和场景中的光源数目没有关系。
在Unity中有两种延迟渲染路径,是旧的延迟渲染路径,一种是Unity5中使用的延迟渲染路径,它们之间的差别很小,如旧的延迟渲染不支持Unity5基于物理的Standard Shader。
一般当游戏中使用了大量的实时光照时,会选择延迟渲染路径。就是说,当场景中光源数目较多,使用前向渲染会造成性能瓶颈的情况下会使用。而且延迟渲染中的每个光源都可以按逐像素的方式处理。但延迟渲染也有一些确定:
不支持真正的抗锯齿功能;
不能处理半透明物体;
对显卡有一定的要求,必须支持MRT(Multiple Render Tragets)、Shader Mode3.0及以上、深度渲染纹理以及双面的模版缓冲。
在Untiy中使用延迟渲染时,需要两个Pass:
第一个Pass用于渲染G缓冲。这个Pass中,我们把物体的漫反射颜色、高光反射颜色、平滑度、法线、自发光和深度等信息渲染到屏幕空间中的G缓冲中,对每个物体这个Pass只执行一次;
第二Pass用于计算真正的光照模型。使用上一个Pass中渲染的数据来计算最终光照,再存储到帧缓冲中。
默认的G缓冲包含以下几个渲染纹理:
RT0:格式是ARGB32,RGB通道用于存储漫反射颜色,A通道没有被使用;
RT1:格式是ARGB32,RGB通道用于存储高光反射颜色,A通道用于存储高光反射的指数部分;
RT2:格式是ARGB2101010,RGB用于存储法线,A通道没有被使用;
RT3:格式是ARGB32(非HDR)或ARGBHalf(HDR),用于存储自发光+lightmap+反射探针;
深度缓冲和模版缓冲。
当在第二个Pass中计算光照时,默认情况下仅可以使用Unity内置的Standard光照模型,如果要使用其它光照模型,要替换掉原有的Internal-DeferredShading.shader文件。下面是延迟渲染路径中可以使用的内置变量:
名称 | 类型 | 描述 |
---|---|---|
_LightColor | float4 | 光源颜色 |
_LightMatrix0 | float4x4 | 从世界空间到光源空间的变换矩阵。可用于采样cookie和光强度衰减纹理 |
相关文章推荐
- Unity旧延迟光照渲染路径( Legacy Deferred Lighting Rendering Path)
- Unity渲染路径 Rendering Paths_1_Deferred Lighting 延时光照
- Unity渲染路径 Rendering Paths_3_Vertex Lit 顶点光照
- Unity延迟渲染路径(Deferred shading rendering path)
- [Unity基础]从“漫反射光照模型”了解Unity Shader渲染原理
- Unity&Shader高级篇-渲染路径(Rendering Paths)
- unity shader学习笔记(十五)——Unity中的复杂光照之光照衰减
- Unity渲染路径 Rendering Paths介绍
- 渲染路径-Deferred Lighting 延时光照
- Unity渲染路径
- Unity顶点光照路径细节(Vertex Lit Rendering Path Details)
- Unity&Shader高级篇-渲染路径(Rendering Paths)
- unity3d 渲染路径(延迟光照,正向渲染,顶点光照)
- unity的几种渲染路径比较
- 学习UnityShader入门精要笔记3——更复杂的光照
- 光照渲染[Unity]
- Unity Shader入门精要学习笔记 - 第9章 更复杂的光照
- Unity Shader渲染顺序 坐标系 和光照模型
- 渲染路径-surface shader 光照函数与渲染路径
- Shader 什么是Unity中的渲染路径