Shader-更复杂的光照-渲染路径

渲染路径

前向渲染路径、延迟渲染路径和顶点照明渲染路径

1.前向渲染路径原理

前向渲染需要渲染该对象的渲染图元,并计算两个缓冲区的信息:一个是颜色缓冲区、一个是深度缓冲区。用深度缓冲来决定片元是否可见,如果可见更新颜色缓冲区的颜色值。

2.Unity中的前向渲染

三种处理光照的方式:逐顶点处理、逐像素处理、球谐函数处理。
使用哪种处理模式取决于光源的类型和渲染模式。
其中渲染模式指该光源是否重要(important)。

2.延迟渲染原理

在场景中存在大量的实时光源的时候,前向渲染会执行多个Pass,再将这些结果混合起来得到最终的光照。
而延迟渲染是使用额外的缓冲区(G缓冲:G-buffer),其中存储了我们关心的表面信息。
延迟渲染包含两个Pass,一个不进行任何光照的计算,仅仅计算那些片元可见,第二个Pass进行真正的光照计算。

Unity光源类型

1.平行光
2.点光源
3.聚光灯
4.面光源

实践

在我们计算点光源的光照的时候
1.将Pass的Tags的LightMode设置为ForwardAdd,我们要使用Blend开启和设置混合模式,因为我们不希望Pass覆盖掉之前的光照结果,还需要使用#pragma multi_compile_fwdadd指令,此指令保证我们在Shader中使用光照衰减等光照变量可以被正确的赋值。

Tags{ "LightMode" = "ForwardAdd" }
Blend One One
CGPROGRAM

        // Apparently need to add this declaration
#pragma multi_compile_fwdadd

2.在计算光源方向的时候,如果是平行光,直接使用_WorldSpaceLightPos0.xyz得到光源位置,如果是点光源或者聚光灯,我们使用_WorldSpaceLightPos0.xyz减去世界空间下的顶点位置。

#ifdef USING_DIRECTIONAL_LIGHT
    fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
#else
    fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz);
#endif

3.最后我们计算不同光源的衰减
这里Unity使用一张纹理表作为查找表,以在片元着色器中得到光源的衰减。

#ifdef USING_DIRECTIONAL_LIGHT
    fixed atten = 1.0;
#else
#if defined (POINT)
    float3 lightCoord = mul(_LightMatrix0, float4(i.worldPos, 1)).xyz;
    fixed atten = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;
#elif defined (SPOT)
    float4 lightCoord = mul(_LightMatrix0, float4(i.worldPos, 1));
    fixed atten = (lightCoord.z > 0) * tex2D(_LightTexture0, lightCoord.xy / lightCoord.w + 0.5).w * tex2D(_LightTextureB0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;
#else
    fixed atten = 1.0;
#endif
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值