【Unity Shader例項】 水體WaterEffect(二) 用貼圖和uv動畫模擬水效
阿新 • • 發佈:2019-01-31
Unity Shader實現簡單水體效果
效果展示
原理
用貼圖和uv動畫模擬水效實現”假”水。
設計
找一張水波的貼圖,處理它的uv值,讓貼圖流動起來。這樣就用靜態紋理和uv動畫模擬出了動態水流動的效果。
實現要點
- 貼圖流動
貼圖流動的實質就是uv偏移,圖片各個部分的偏移程度有區別(可以藉助噪聲圖讓uv偏移程度具有隨機性的區別)就實現了扭曲效果。讓偏移程度與時間相關,就會有種貼圖隨著時間發生流動的感覺。 更多關於貼圖流動的實現和原理看這裡:貼圖流動。
具體實現
完整的shader程式碼
Shader "Water/Liudong"
{
Properties
{
_MainTex ("MainTex" , 2D) = "white" {}
_NoiseTex("NoiseTex", 2D) = "white" {}
_Intensity("intensity", float) = 0.1
_XSpeed("Flow Speed", float) = -0.2
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1 )
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _NoiseTex;
float _Intensity;
float _XSpeed;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 noise_col = tex2D(_NoiseTex, i.uv + fixed2(_Time.y*_XSpeed, 0));
fixed uOffset = noise_col.r;
fixed vOffset = noise_col.r;
fixed4 col = tex2D(_MainTex, i.uv +_Intensity*fixed2(uOffset, vOffset));
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
效果
總結
我們已經實現了一個最簡單的水體效果,但是這樣做出來的水特別假,它既沒有對周圍環境的反射也沒有對水下物體的折射,也沒有真實水面的起伏波浪,當水中有物體時也不會在水與物體交界處產生浪花等等。這些效果,我們會來後續的文章中繼續討論。