1. 程式人生 > >【Unity Shader例項】 水體WaterEffect(二) 用貼圖和uv動畫模擬水效

【Unity Shader例項】 水體WaterEffect(二) 用貼圖和uv動畫模擬水效

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 } } }

效果

這裡寫圖片描述

總結

我們已經實現了一個最簡單的水體效果,但是這樣做出來的水特別假,它既沒有對周圍環境的反射也沒有對水下物體的折射,也沒有真實水面的起伏波浪,當水中有物體時也不會在水與物體交界處產生浪花等等。這些效果,我們會來後續的文章中繼續討論。