欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Unity 雪着色器

最编程 2024-04-01 12:50:58
...
1 Shader "Custom/XueDiShader" { 2 Properties{ 3 //岩石贴图 4 _MainTex("基本材质", 2D) = "white" {} 5 //法线贴图 6 _Bump("法线图", 2D) = "bump" {} 7 //表示覆盖在岩石上雪的数量,范围从0~1 8 _Snow("积雪等级", Range(0,1)) = 0 9 //积雪颜色 默认白色 10 _SnowColor("积雪颜色", Color) = (1.0,1.0,1.0,1.0) 11 //积雪方向 12 _SnowDirection("积雪方向", Vector) = (0,1,0) 13 //积雪厚度 14 _SnowDepth("积雪深度", Range(0,0.2)) = 0.1 15 //湿润度,如果该值越大,则混色中积雪颜色所占比例越低,这表明积雪越湿润,则雪的颜色越少,都化成水了 16 _Wetness("水润度", Range(0, 0.5)) = 0.3 17 } 18 SubShader{ 19 Tags{ "RenderType" = "Opaque" } 20 LOD 200 21 22 CGPROGRAM 23 #pragma surface surf Lambert vertex:vert 24 25 //获取属性的具体值 26 sampler2D _MainTex; 27 sampler2D _Bump; 28 float _Snow; 29 float4 _SnowColor; 30 float4 _SnowDirection; 31 float _SnowDepth; 32 float _Wetness; 33 34 //输入结构体 35 struct Input { 36 //获取岩石贴图的uv坐标 37 float2 uv_MainTex; 38 //获取法线贴图的uv坐标 39 float2 uv_Bump; 40 //如果SurfaceOutput中设定了Normal值的话,通过worldNormal可以获取当前点在世界中的法线值 41 float3 worldNormal; INTERNAL_DATA 42 }; 43 44 //顶点着色程序入口 45 void vert(inout appdata_full v) 46 { 47 //将_SnowDirection转化到模型局部坐标系下 48 float4 sn = mul(UNITY_MATRIX_IT_MV, _SnowDirection); 49 50 if (dot(v.normal, sn.xyz) >= lerp(1,-1, (_Snow * 2) / 3)) 51 { 52 v.vertex.xyz += (sn.xyz + v.normal) * _SnowDepth * _Snow; 53 } 54 } 55 56 void surf(Input IN, inout SurfaceOutput o) { 57 half4 c = tex2D(_MainTex, IN.uv_MainTex); 58 o.Normal = UnpackNormal(tex2D(_Bump, IN.uv_Bump)); 59 60 //WorldNormalVector通过输入的点及这个点的法线值,来计算它在世界坐标中的方向 61 //然后用输入点在世界坐标中的方向和 积雪的方向 做点积运算 并减去 _Snow插值 62 half difference = dot(WorldNormalVector(IN, o.Normal), _SnowDirection.xyz) - lerp(1,-1,_Snow); 63 64 //saturate(x)函数 如果 x 小于 0 ,返回 0 ;如果 x 大于 1 ,返回 1 ;否则,返回 x 65 difference = saturate(difference / _Wetness); 66 67 //对光源的反射率。 68 o.Albedo = difference*_SnowColor.rgb + (1 - difference) *c; 69 o.Alpha = c.a; 70 } 71 ENDCG 72 } 73 FallBack "Diffuse" 74 }