Unity的渲染路径
渲染路径决定了光照如何应用到shader中,要和光源交互就需要为每个pass指定渲染路径,多数情况下一个项目只使用一种渲染路径,通常默认为前向。
edit-project settings-player-other settings-rendering
在pass中使用标签来指定该pass使用的渲染路径:
Pass{
Tags{"LightMode"="ForwardBase"}
}
前向渲染路径
1.前向渲染路径的原理
每进行一次完整的前向渲染,完成对对象的渲染图元渲染,需要利用深度缓冲来决定一个片元是否可见,如果可见就更新颜色缓冲中的颜色值,对于每个逐像素光影,都需要完成一个这样的完整渲染流程,如果一个物体在多个逐像素光源的影响区域内,就需要多个Pass分别计算各个逐像素光源的光照结果,并将这些结果混合得到最终的颜色值。N个物体,M个光源--N*M个pass。引擎通常会限制每个物体逐像素光源的数目。
在unity中,前向渲染路径有三种处理光照的方式:逐顶点、逐像素、球谐函数(SH)处理,选择那种处理模式取决于它的类型(光源类型是指该光源是平行光还是其他类型)和渲染模式(指该光源的模式是否设置为Important)。
最亮的平行光:逐像素
not important:逐顶点或SH处理
Important:逐像素
要得到一些正确的光照变量如光照衰减值等,需要对BassPass和Additional Pass 使用这两个编译指令。
#pragma multi_compile_fwdbase //forward base
#pragma multi_compile_fwdadd // forward add
对于前向渲染来说,一个unity shader 通常会定义一个base pass 以及一个additional pass,basepass仅执行一次,而additionnalpass会根据影响该物体的其他逐像素光源的数目被多次调用,每个逐像素光源执行一次additionalpass。
_LightColor() 该pass处理的逐像素光源的颜色
_LightMatrix(()从世界空间到光源空间的变换矩阵,可用于采样cookie和光强衰减纹理
顶点照明渲染路径
不支持逐像素才能得到的效果(如阴影、法线映射、高精度的高光反射),通常一个pass解决问题,一个顶点照明的pass最多访问到8个逐顶点光源。
unity_LightAtten 光源衰减因子
延迟渲染路径
当场景中包含大量实时光源时,前向渲染性能会下降,重叠区域造成很大的重复,延迟渲染除了颜色缓冲与深度缓冲外,利用额外的G-buffer,储存表面的其他信息如法线位置材质等。
原理:包含两个pass,第一个pass用于计算哪些片元可见(深度缓冲),当发现该片元可见时将其信息存储到G缓冲区中,然后在第二个pass中利用G缓存的信息进行计算。
缺点:不支持真正的抗锯齿,不能处理半透明物体。
默认的G缓冲区包含下面几个渲染纹理RT:RT0存储漫反射颜色,RT1存储高光反射颜色,A通道为指数部分、RT2 存储法线, RT3 存储自发光 lightmao 反射探针
Unity的光源类型
一共支持四种:平行光、点光源、聚光灯、面光源
1.平行光:几何属性只有方向,可以放在任意位置,光不会衰减
2.点光源:照亮空间有限,会衰减,衰减值可以由一个函数定义
3.聚光灯:衰减值同样由函数定义,需要判断一个点是否在锥体的范围内
attend可以编写函数用来表示衰减
fixed atten = 1.0;
return fixed4(ambient + (diffuse + specular) * atten, 1.0);
使用frame debugger 可以看出渲染的过程,以及每个渲染事件的结果,将点光源设置为not important,渲染事件将减少,不在点光源、聚光灯范围内,也将减少渲染事件。
Unity的光照衰减
unity使用一张纹理作为查找表来在片元着色器中计算逐像素光照的衰减,使其不依赖于数学公式,而这样做需要预处理得到采样纹理且纹理大小影响衰减精度,且无法用其他数学公式计算,但一定程度上可以提升性能。
用于光照衰减的纹理
unity使用一张_LightTexture0的纹理计算光源衰减,为了对该纹理采样得到给定点到该光源的衰减值,需要得到该点在光源空间中的位置,由_LightMatrix0变换矩阵得到(世界-光源)。
float3 lightCoord = mul(_LightMatrix0,float4(i.worldPostion,1)).xyz;
//得到光源空间中的相应位置
fixed atten= tex2D(_LightTexture0,dot(lightCoord,lightCoord).rr).UNITY_ATTEN_CHANNEL;
//光源空间中定点距离的平方,unity_atten_channel宏得到衰减纹理中衰减值所在的分量