UnityShader入门精要-高级光照基础

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宏得到衰减纹理中衰减值所在的分量

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值