积雪效果是比较简单的,只需要计算顶点法线方向和世界向上方向之间的点乘,将得到的值与预设的阀值比较,小于阀值为0,用这个值进行插值就OK了
代码:
1 Shader "MyShader/SnowShader" { 2 Properties{ 3 _MainTex("MainTex",2D)="white"{}//纹理 4 _SnowNum("Snow Num",Range(-1,1))=0//点乘阀值 5 _SnowIntensity("Snow Intensity",Range(0,20))=1//积雪强度 6 _SnowColor("Snow Color",Color)=(1.0,1.0,1.0,1.0)//积雪颜色 7 } 8 9 SubShader{ 10 Pass{ 11 Tags{"LightMode"="ForwardBase"} 12 CGPROGRAM 13 #pragma vertex vert 14 #pragma fragment frag 15 #include "UnityCG.cginc" 16 17 sampler2D _MainTex; 18 float4 _MainTex_ST; 19 fixed _SnowNum; 20 fixed _SnowIntensity; 21 fixed4 _SnowColor; 22 23 struct a2v{ 24 float4 vertex:POSITION; 25 float3 normal:NORMAL; 26 float2 texcoord:TEXCOORD0; 27 }; 28 29 struct v2f{ 30 float4 pos:SV_POSITION; 31 float3 worldNormal:TEXCOORD0; 32 float2 uv:TEXCOORD1; 33 }; 34 35 v2f vert(a2v v){ 36 v2f o; 37 o.pos=mul(UNITY_MATRIX_MVP,v.vertex); 38 o.worldNormal=UnityObjectToWorldNormal(v.normal); 39 o.uv=v.texcoord*_MainTex_ST.xy+_MainTex_ST.zw; 40 return o; 41 } 42 43 fixed4 frag(v2f i):SV_TARGET{ 44 fixed3 tex=tex2D(_MainTex,i.uv).rgb; 45 fixed3 worldNormalDir=normalize(i.worldNormal); 46 fixed3 worldUpDir=fixed3(0,1,0); 47 //用smoothstep是为了使得积雪边缘过渡更平滑 48 fixed colNum=smoothstep(_SnowNum,1,dot(worldNormalDir,worldUpDir))*_SnowIntensity; 49 //fixed colNum=step(dot(worldNormalDir,worldUpDir),_SnowNum); 50 fixed3 finalCol=lerp(tex,_SnowColor,colNum); 51 return fixed4(finalCol,1); 52 } 53 ENDCG 54 } 55 } 56 FallBack "Diffuse" 57 }
效果图:
调整这几个值也可以做出其它效果,比如放置已久积满灰尘的物体