在网上找的资源,先看看原始的效果。这个资源目前使用的是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版权协议,转载请附上原文出处链接和本声明。