Unity Shader實現水波紋效果
阿新 • • 發佈:2020-05-06
本文例項為大家分享了Unity Shader實現水波紋的具體程式碼,供大家參考,具體內容如下
效果:
Shader程式碼:
Shader "Custom/shuibowen"{ Properties{ _MainTex("Base (RGB)",2D)="white"{} _distanceFactor("Distancefactor",float)=1 _timeFactor("time factor",float)=2 _totalFactor("total factor",float)=3 _waveWidth("wave width",float)=4 _curWaveDis("curwave dis",float)=5 _startPos("star pos",Vector) = (1,1,1) _MainTex_TexelSize("Maintex_texelSize",vector)=(1,1) } CGINCLUDE #include "UnityCG.cginc" uniform sampler2D _MainTex; float4 _MainTex_TexelSize; uniform float _distanceFactor; uniform float _timeFactor; uniform float _totalFactor; uniform float _waveWidth; uniform float _curWaveDis; uniform float4 _startPos; fixed4 frag(v2f_img i) : SV_Target { //DX下紋理座標反向問題 #if UNITY_UV_STARTS_AT_TOP if (_MainTex_TexelSize.y < 0) _startPos.y = 1 - _startPos.y; #endif //計算uv到中間點的向量(向外擴,反過來就是向裡縮) float2 dv = _startPos.xy - i.uv; //按照螢幕長寬比進行縮放 dv = dv * float2(_ScreenParams.x / _ScreenParams.y,1); //計算畫素點距中點的距離 float dis = sqrt(dv.x * dv.x + dv.y * dv.y); //用sin函式計算出波形的偏移值factor //dis在這裡都是小於1的,所以我們需要乘以一個比較大的數,比如60,這樣就有多個波峰波谷 //sin函式是(-1,1)的值域,我們希望偏移值很小,所以這裡我們縮小100倍,據說乘法比較快,so... float sinFactor = sin(dis * _distanceFactor + _Time.y * _timeFactor) * _totalFactor * 0.01; //距離當前波紋運動點的距離,如果小於waveWidth才予以保留,否則已經出了波紋範圍,factor通過clamp設定為0 float discardFactor = clamp(_waveWidth - abs(_curWaveDis - dis),1) / _waveWidth; //歸一化 float2 dv1 = normalize(dv); //計算每個畫素uv的偏移值 float2 offset = dv1 * sinFactor * discardFactor; //畫素取樣時偏移offset float2 uv = offset + i.uv; return tex2D(_MainTex,uv); } ENDCG SubShader { Pass { ZTest Always Cull Off ZWrite Off Fog { Mode off } CGPROGRAM #pragma vertex vert_img #pragma fragment frag #pragma fragmentoption ARB_precision_hint_fastest ENDCG } } Fallback off }
C#程式碼:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class WaterWaveEffect : PostEffectsBase { //距離係數 public float distanceFactor = 60.0f; //時間係數 public float timeFactor = -30.0f; //sin函式結果係數 public float totalFactor = 1.0f; //波紋寬度 public float waveWidth = 0.3f; //波紋擴散的速度 public float waveSpeed = 0.3f; private float waveStartTime; private Vector4 startPos = new Vector4(0.5f,0.5f,0); public Material _Material; void OnRenderImage(RenderTexture source,RenderTexture destination) { //計算波紋移動的距離,根據enable到目前的時間*速度求解 float curWaveDistance = (Time.time - waveStartTime) * waveSpeed; //設定一系列引數 _Material.SetFloat("_distanceFactor",distanceFactor); _Material.SetFloat("_timeFactor",timeFactor); _Material.SetFloat("_totalFactor",totalFactor); _Material.SetFloat("_waveWidth",waveWidth); _Material.SetFloat("_curWaveDis",curWaveDistance); _Material.SetVector("_startPos",startPos); Graphics.Blit(source,destination,_Material); } void Update() { if (Input.GetMouseButton(0)) { Vector2 mousePos = Input.mousePosition; //將mousePos轉化為(0,1)區間 startPos = new Vector4(mousePos.x / Screen.width,mousePos.y / Screen.height,0); waveStartTime = Time.time; } } }
新建一個材質球,選擇此shader,並賦值給這個指令碼,點選螢幕即可看到效果
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。