Unity 简单的积雪Shader

在这里插入图片描述
在网上找的资源,先看看原始的效果。这个资源目前使用的是Unity默认的Standard。

在这里插入图片描述
在这里插入图片描述
效果还是比较明显的。
这个素材只是用于演示,并不是最合适的。应该是那种高低不平的石头或者是小山坡,丘陵形状的会好些。但由于临时找不到,只能用上这个了。。。

思路:用顶点的法向量与向上(0.0,1.0,0.0)做一个点积,让夹角越小的地方,融合到更多的白色(积雪的颜色)。

Shader "JackyShader/SnowCover" {
Properties {
	_MainTex ("Base (RGB)", 2D) = "white" {}
	_SnowStrength ("SnowStrength", Range (0.0, 1)) = 0.2
}

SubShader {
	Tags { "RenderType"="Opaque" }
	LOD 100
	
	Pass {  
		CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			
			#include "UnityCG.cginc"

			struct appdata_t {
				float4 vertex : POSITION;
				float2 texcoord : TEXCOORD0;
				float3 normal : NORMAL;
			};

			struct v2f {
				float4 vertex : SV_POSITION;
				half2 texcoord : TEXCOORD0;
				fixed3 normal : NORMAL;
			};
			//纹理
			sampler2D _MainTex;
			float4 _MainTex_ST;
			//积雪的强度
			float _SnowStrength;
			v2f vert (appdata_t v)
			{
				v2f o;
				//顶点转成世界坐标
				o.vertex = UnityObjectToClipPos(v.vertex);
				//转换UV
				o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
				//法线
				o.normal = v.normal;
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
				//将法线转换到世界坐标系,方便下面的计算
				float3 wn = UnityObjectToWorldNormal(i.normal);
				//默认一个向上的向量,与法向量做点积,让其取值范围在[0,1]之间。1-点积的数值 ,法向量与向上的向量夹角为0是值为0 ,90度为1.
				float flag = 1 - saturate(dot(float3(0.0,1.0,0.0),wn));
				//使用强度值用于指数运算,将提高数值的变化率。
				flag = saturate(pow(flag,_SnowStrength*3));
				fixed4 col = tex2D(_MainTex, i.texcoord);
				//默认积雪是白色,当然应用于其他,可以修改这个颜色或将其做成变量。
				fixed4 sc = fixed4(1.0,1.0,1.0,1.0);
				//使用lerp做差值运算 ==> sc*(1-flag)+col*flag
				col = lerp(sc,col,flag);
				UNITY_OPAQUE_ALPHA(col.a);
				return col;
			}
		ENDCG
	}
}

}

这是一个比较简单的shader,意图是为了描述积雪的实现思路。如果需要加入灯光计算,也可很方便的添加。


版权声明:本文为qq_36705579原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。