在開始之前,先看一下最終的動態效果。
一張水面的貼圖
如果想要更好的效果,可以自行準備一個水桶或者杯子的模型,用來更好的襯托我們的水面。
Shader "My Shader/Wave Water" { Properties { _MainTex("Base (RGB)", 2D) = "white" {} _MainColor("Main Coloe (RGBA)", Color) = (1,1,1,1) _WaveHeight("Wave Height",Range(0,0.1)) = 0.01 _WaveFrequency("Wave Frequency",Range(1,100)) = 50 _WaveSpeed("Wave Speed",Range(0,10)) = 1 }
SubShader { Tags{"Queue"="Transparent"}
Pass { ZWrite Off Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc"
因為我們想要水面透明顯示,所以把它的渲染序列放在Transparent里,關閉深度寫入,開啟混合模式。這屬於透明shader的標準設置。
定義頂點著色器和片段著色器,然後把Unity的內置文件包含進來。
struct v2f { float4 vertex:SV_POSITION; float2 uv:TEXCOORD0; };
sampler2D _MainTex; float4 _MainTex_ST; fixed4 _MainColor;
float _WaveHeight; float _WaveFrequency; float _WaveSpeed;
v2f vert (appdata_base v) { v2f o; o.uv = TRANSFORM_TEX(v.texcoord,_MainTex); o.vertex = UnityObjectToClipPos(v.vertex);
return o; }
在頂點著色器里我們進行了以下操作:
fixed4 frag(v2f IN) : SV_Target { float2 uvCoord = _MainTex_ST.xy*0.5;
fixed2 uvDir = normalize(IN.uv-uvCoord); fixed uvDis = distance(IN.uv,uvCoord);
clip(uvCoord-uvDis);
fixed2 uv = IN.uv+sin(uvDis*_WaveFrequency - _Time.y*_WaveSpeed)*_WaveHeight*uvDir;
fixed4 color; color.rgb = tex2D(_MainTex, uv)*_MainColor; color.a = _MainColor.a; return color; } ENDCG } } FallBack "Transparent" }
片段著色器是本shader里最重要的部分,在這裡我們進行了以下操作:
最後的材質面板以及變數的參數如下: