Shader "Custom/OfficialExam4_RimLighting"
{
Properties { _MainTex ("Base (RGB)", 2D) = "white" {}
_BumpMap("Bump (RGB)",2D) = "white"{}
_RimColor("Rim Color",Color) = (0.26,0.19,0.16,0.0)
_RimPower("Rim Power",Range(0.5,8.0)) = 3.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 200
CGPROGRAM #pragma surface surf Lambert
sampler2D _MainTex;
sampler2D _BumpMap;
float4 _RimColor;
float _RimPower;
struct Input
{
float2 uv_MainTex;
float2 uv_BumpMap;
float3 viewDir;
};
void surf (Input IN, inout SurfaceOutput o)
{
o.Albedo = tex2D(_MainTex,IN.uv_BumpMap).rgb;
o.Normal = UnpackNormal(tex2D(_BumpMap,IN.uv_BumpMap));
half rim = 1.0 - saturate(dot(normalize(IN.viewDir),o.Normal));
o.Emission = _RimColor.rgb * pow(rim,_RimPower);
}
ENDCG
}
FallBack "Diffuse"
}
最里层是Normalize函数,用于获取到的viewDir坐标转成一个单位向量且方向不变,外面再与点的法线做点积。最外层再用saturate算出一[0,1]之间的最靠近(最小值但大于所指的值)的值。这样算出一个rim边界。
=>这里o.Normal就是单位向量。外加Normalize了viewDir。因此求得的点积就是夹角的cos值。=>因为cos值越大,夹角越小,所以,这时取反来。这样,夹角越大,所反射上的颜色就越多。于是就得到的两边发光的效果。 当dot(...)<0时,saturate处理之后,就会等于0。这样处于背面的位置就不会有Emission效果。