【系统学习Shader与后处理】第2篇:uv控制之water

我们每要实现一个效果,就如这个系列开头所说,先分析效果需要用什么模式来实现。

我们发现,水流动的效果跟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 }
}
}
}
}

相关推荐