效果如圖:
原理在代碼注釋中钝腺。
Shader代碼:
Shader"Custom/RealisticSnow"{
Properties{
_MainTex("Base(RGB)",2D)="white"{}
_Bump("Bump",2D)="bump"{}
_Snow("SnowLevel",Range(0,1))=0
_SnowColor("SnowColor",Color)=(1.0,1.0,1.0,1.0)
_SnowDirection("SnowDirection",Vector)=(0,1,0)
_SnowDepth("SnowDepth",Range(0,0.2))=0.1
_Wetness("Wetness",Range(0,0.5))=0.3
}
SubShader{
Tags{"RenderType"="Opaque"}
LOD200
CGPROGRAM
#pragmasurfacesurfLambertvertex:vert
sampler2D_MainTex;
sampler2D_Bump;
float_Snow;
float4_SnowColor;
float4_SnowDirection;
float_SnowDepth;
float_Wetness;
structInput{
float2uv_MainTex;
float2uv_Bump;
float3worldNormal;
INTERNAL_DATA
};
voidvert(inoutappdata_fullv){
//通過【模型到視角的逆轉(zhuǎn)置矩陣】將【積雪方向】轉(zhuǎn)換到【模型坐標(biāo)系】中
float4sn=mul(UNITY_MATRIX_IT_MV,_SnowDirection);
//計算當(dāng)前【點(diǎn)的法線方向】和【下雪反方向】的點(diǎn)乘[-1,1]
//如果頂點(diǎn)點(diǎn)乘大于設(shè)置的_Snow值梨州,那么該點(diǎn)就往【點(diǎn)的法線方向】和【下雪反方向】之和的方向擠出
//如果雪量_Snow為0.5氯檐,那么模型法線為up的點(diǎn)擠出最多
if(dot(v.normal,sn.xyz)>=lerp(1,-1,_Snow))
{
v.vertex.xyz+=(sn.xyz+v.normal)*_SnowDepth*_Snow;
}
}
voidsurf(InputIN,inoutSurfaceOutputo){
half4c=tex2D(_MainTex,IN.uv_MainTex);
o.Normal=UnpackNormal(tex2D(_Bump,IN.uv_Bump));
//_Snow為0.5時训挡,diff值域【-1,1】
halfdifference=dot(WorldNormalVector(IN,o.Normal),_SnowDirection.xyz)-lerp(1,-1,_Snow);
//當(dāng)_Wetness為0.3時,要控制diff的最終值域?yàn)椤?,1】赊舶,那么就有0
//可以得出【法線方向】和【積雪方向】夾角為73-90度之間時派任,就會有【雪】與【地面】材質(zhì)疊加的效果
//而小于73度的,都是積雪悉罕;大于90度的沒有積雪
difference=saturate(difference/_Wetness);
o.Albedo=difference*_SnowColor.rgb+(1-difference)*c;
o.Alpha=c.a;
}
ENDCG
}
FallBack"Diffuse"
}
來源:http://www.lxway.com/40250226.htm