我们每要实现一个效果,就如这个系列开头所说,先分析效果需要用什么模式来实现。
我们发现,水流动的效果跟uv有关,所以我们需要去控制uv。
控制uv一般有三种方式:
1.time
2.采样其他图
3.C#输入参数
然后根据这些参数,用某个公式实现
这个shader,使用了time + 采样其他图 +C#输入参数
使用time,是为了达成两个目的,
第一个目的是time参数平滑递增,
第二个目的是uv本身的特点,是随着超出uv的范围后,又会回到uv起始位置。
所以使用了time,我们就可以让水流动起来了。
我们采样了另一张图:
一般这张图叫做扰乱图,顾名思义,是为了让uv采样不规律。(实际上,也是有规律的,根据这个扰动图的rgb通道来的规律)
这就是我们对水需要的第二个效果,不太规律的流动。
为什么要使用扰动图,大家可以把扰动图当作编程时候的配置表,读取这张预先做好的配置表,这样我们的shader效率更高,不用即时运算。
上源码。
Shader "effect/water" {
Properties {
_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5) //颜色值,我们暴露出来,可以控制水根据天气的变化,比如夕阳的时候,水变红
_NoiseTex ("Distort Texture (RG)", 2D) = "white" {} //扰乱图
_MainTex ("Alpha (A)", 2D) = "white" {}
_HeatTime ("Heat Time", range (-0.2,1)) = 0
_ForceX ("Strength X", range (0,1)) = 0.1
_ForceY ("Strength Y", range (0,1)) = 0.1
}
Category {
Tags { "Queue"="Transparent+99" "RenderType"="Transparent" }
Blend SrcAlpha One
Cull Off Lighting Off ZWrite Off Fog { Color (0,0,0,0) }
BindChannels {
Bind "Color", color
Bind "Vertex", vertex
Bind "TexCoord", texcoord
}
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#pragma multi_compile_particles
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord: TEXCOORD0;
};
struct v2f {
float4 vertex : POSITION;
fixed4 color : COLOR;
float2 uvmain : TEXCOORD1;
};
fixed4 _TintColor;
fixed _ForceX;
fixed _ForceY;
fixed _HeatTime;
float4 _MainTex_ST;
float4 _NoiseTex_ST;
sampler2D _NoiseTex;
sampler2D _MainTex;
v2f vert (appdata_t v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uvmain = TRANSFORM_TEX( v.texcoord, _MainTex );
return o;
}
fixed4 frag( v2f i ) : COLOR
{
//noise effect
fixed offsetColor1 = tex2D(_NoiseTex, i.uvmain + _Time.yx*_HeatTime).r;
fixed offsetColor2 = tex2D(_NoiseTex, i.uvmain + _Time.xy*_HeatTime).g;
fixed off = offsetColor1+offsetColor2-1;
//fixed off = lerp(offsetColor1,offsetColor2,0.5f);
i.uvmain.x += off * _ForceX;
i.uvmain.y += off * _ForceY;
return 2.0f * _TintColor * tex2D( _MainTex, i.uvmain);
}
ENDCG
}
}
// ------------------------------------------------------------------
// Fallback for older cards and Unity non-Pro
SubShader {
Blend DstColor Zero
Pass {
Name "BASE"
SetTexture [_MainTex] { combine texture }
}
}
}
}