Unity Shader 2D水流效果

2020-03-19 15:43:11 浏览数 (1)

水流的模拟主要运用了顶点变换和纹理动画的结合;

顶点变换中,利用正弦函数模拟河流的大致形态,例如波长,振幅等。

纹理动画中,将纹理坐标朝某一方向持续滚动以形成流动的效果。

脚本如下:

代码语言:javascript复制
 1 Shader "MyUnlit/ScrollWater"
 2 {
 3     Properties
 4     {
 5         _MainTex ("Texture", 2D) = "white" {}
 6         _Color("Color Tint",color)=(1,1,1,1)
 7         //控制水流波动的幅度,也就是三角函数中的振幅(值域范围)
 8         _Magnitude("Distortion Magnitude",float)=0.3
 9         //控制周期的长度,值越大,周期越短,频率越高
10         _InvWaveLength("Distortion Inserve Wave Length",float)=1
11         //流动速度,用于纹理变换
12         _Speed("Speed",float)=0.1
13     }
14     SubShader
15     {
16         //顶点动画需要禁用合P处理
17         Tags {"Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="true" "DisableBatching"="True"}
18 
19         Pass
20         {
21             //透明度混合:关闭深度写入 设置混合状态 禁用剔除(双面渲染)
22             Tags{"lightmode"="forwardbase"}
23             ZWrite off
24             Blend SrcAlpha OneMinusSrcAlpha
25             Cull off
26 
27             CGPROGRAM
28             #pragma vertex vert
29             #pragma fragment frag
30             #pragma multi_compile_fog
31 
32             #include "UnityCG.cginc"
33             struct appdata
34             {
35                 float4 vertex : POSITION;
36                 float2 uv : TEXCOORD0;
37             };
38 
39             struct v2f
40             {
41                 float2 uv : TEXCOORD0;
42                 UNITY_FOG_COORDS(1)
43                 float4 vertex : SV_POSITION;
44             };
45 
46             sampler2D _MainTex;
47             float4 _MainTex_ST;
48             fixed4 _Color;
49             float _Magnitude;
50             float _InvWaveLength;
51             float _Speed;
52 
53             v2f vert (appdata v)
54             {
55                 v2f o;
56                 float4 offset;
57                 //这里的方向可以自己选择,这里选择偏移x方向,其他方向的偏移保持不变
58                 offset.yzw = float3(0, 0, 0);
59                 //利用正弦函数模拟河流整体的形状,最后乘以振幅
60                 offset.x = sin((v.vertex.x   v.vertex.y   v.vertex.z)*_InvWaveLength)*_Magnitude;
61                 o.vertex = UnityObjectToClipPos(v.vertex offset);
62                 //对uv进行某一方向的滚动以模拟水流,这里选择v向
63                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
64                 o.uv  = float2(0.0, _Time.y*_Speed);
65 
66                 UNITY_TRANSFER_FOG(o,o.vertex);
67                 return o;
68             }
69 
70             fixed4 frag (v2f i) : SV_Target
71             {
72                 fixed4 col = tex2D(_MainTex, i.uv);
73                 col.rgb *= _Color.rgb;
74                 UNITY_APPLY_FOG(i.fogCoord, col);
75                 return col;
76             }
77             ENDCG
78         }
79     }
80     FallBack "Transparent/VertexLit"
81 }

P.S.需要把纹理的导入设置改为Repeat(重复)

效果如下:

0 人点赞