fixed4 frag(v2f i) : SV_Target
{
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(UnityWorldSpaceLighDir(i.worldPos));
fixed3 albedo = tex2D(_MainTex,i.uv).rgb *_Color.rgb;
float3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz *albedo;
fixed3 diffuse = _LightColor0.rgb*albedo*max(0,dot(worldNormal,worldLightDir));
fixed3 viewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
fixed3 halfDir = normalize(worldLightDir+viewDir);
fixed3 specular = _LightColor0.rgb*Specular.rgb*pow(max(0,dot(worldNormal,halfDir)),_Gloss);
return fixed4(ambient+diffuse+specular,1.0);
}
这是一个片元着色器的代码段,注意环境光ambient、漫反射diffuse、高光specular三个光照计算都是用颜色乘法计算的,但是最后返回的颜色值,确实把三个光照颜色相加,这是为什么呢?以下是我的理解:
加法是没有关系的颜色之间的叠加,而乘法是模拟光的照射过程
光照射到一个物体表面时,是光的颜色和物体的颜色属性共同决定了照射后物体看起来是什么颜色。
比如物体在阳光照射下是红色,就说明这个物体吸收了红颜色以外的其他颜色的光,反射了红光。
假如物体的基本颜色为(R:1.0,G:0.3,B:0.0),这个颜色的意思是任何光照射到这个物体上,红光部分被完全返回,绿光部分被吸收70%,返回30%,蓝光部分被完全吸收。所以这个时候使用乘法来模拟光的交互过程,就是计算光源的每个色光分量有多少被这个物体返回。
而在标准光照模型里,用了四个部分来模拟自然界的光照过程:
自发光(emissive),环境光(ambient),漫反射(diffuse),高光反射(specular)
这四个部分可以说是没有关系的,相互没有影响和交互,是四个独立的部分,所以最后使用加法来进行叠加。