unity實(shí)現(xiàn)透明水波紋扭曲
本文實(shí)例為大家分享了unity實(shí)現(xiàn)透明水波紋扭曲的具體代碼,供大家參考,具體內(nèi)容如下
需要掛一個(gè)攝像機(jī)把腳本掛在一個(gè)物體上
可隨意在物體上面點(diǎn)擊
shader:
Shader "Unlit/Water"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_WaterUV("WaterUV",2D)="while"{}
_WaterIntensity("WaterIntensity",float)=500
}
SubShader
{
GrabPass{
Name "BASE"
Tags { "Mode" = "Always" }
}
Tags { "Queue"="Transparent+100" "RenderType"="Transparent" }
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
float3 normal:Normal;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 grabuv:TEXCOORD1;
float4 vertex : SV_POSITION;
float3 normal:Normal;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _GrabTexture;
sampler2D _WaterUV;
float4 _GrabTexture_TexelSize;
float _WaterIntensity;
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
o.grabuv=ComputeGrabScreenPos(o.vertex);
o.normal=v.normal;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
float2 uv=tex2D(_WaterUV,i.uv).xy;
uv= (uv-0.5)*2;
float2 offset_ =uv * _GrabTexture_TexelSize.xy*_WaterIntensity;
float4 grabuv=i.grabuv;
grabuv.xy+=sin(offset_);
fixed4 grabCol=tex2Dproj(_GrabTexture,UNITY_PROJ_COORD(grabuv));
return col*grabCol;
}
ENDCG
}
}
}
C#:
using UnityEngine;
using System.Collections;
using System.Threading;
public class Water : MonoBehaviour
{
public int m_texHeight = 512;
public int m_texWidth = 512;
public Texture2D m_waterTexture = null;
private Material m_waterMatrial;
private float[,] waveA;
private float[,] waveB;
public float decrement=0.025f;
public Camera m_waterCam;
private int time;
void Start()
{
m_waterTexture = new Texture2D(m_texWidth, m_texHeight, TextureFormat.RGBA32, false);
m_waterMatrial = GetComponent<MeshRenderer>().material;
waveA = new float[m_texWidth, m_texHeight];
waveB = new float[m_texWidth, m_texHeight];
m_waterMatrial.SetTexture("_WaterUV", m_waterTexture);
allColor = new Color[m_texWidth* m_texHeight];
Thread t = new Thread(new ThreadStart(ThreadWave));
t.Start();
// m_waterMatrial.SetTexture("_MainTex", m_waterTexture);
}
public void PopWater(Vector2 pos)
{
float x=pos.x;
float y=pos.y;
waveA[(int)(m_texWidth * x) , (int)(m_texHeight * y)] = 1;
//waveA[(int)(m_texWidth * x) - 1, (int)(m_texHeight * y) ] = 1;
//waveA[(int)(m_texWidth * x) + 1, (int)(m_texHeight * y) ] = 1;
//waveA[(int)(m_texWidth * x) , (int)(m_texHeight * y) - 1] = 1;
//waveA[(int)(m_texWidth * x), (int)(m_texHeight * y) + 1] = 1;
//waveA[(int)(m_texWidth * x) - 1, (int)(m_texHeight * y) - 1] = 1;
//waveA[(int)(m_texWidth * x) - 1, (int)(m_texHeight * y) + 1] = 1;
//waveA[(int)(m_texWidth * x) + 1, (int)(m_texHeight * y) - 1] = 1;
//waveA[(int)(m_texWidth * x) + 1, (int)(m_texHeight * y) + 1] = 1;
}
public void PopWater()
{
waveA[(int)(m_texWidth / 2), (int)(m_texHeight / 2)] = 1;
waveA[(int)(m_texWidth / 2) - 1, (int)(m_texHeight / 2)] = 1;
waveA[(int)(m_texWidth / 2) + 1, (int)(m_texHeight / 2)] = 1;
waveA[(int)(m_texWidth / 2), (int)(m_texHeight / 2) - 1] = 1;
waveA[(int)(m_texWidth / 2), (int)(m_texHeight / 2) + 1] = 1;
waveA[(int)(m_texWidth / 2) - 1, (int)(m_texHeight / 2) - 1] = 1;
waveA[(int)(m_texWidth / 2) - 1, (int)(m_texHeight / 2) + 1] = 1;
waveA[(int)(m_texWidth / 2) + 1, (int)(m_texHeight / 2) - 1] = 1;
waveA[(int)(m_texWidth / 2) + 1, (int)(m_texHeight / 2) + 1] = 1;
}
void Update()
{
ComputeWave();
if (Input.GetMouseButtonDown(0))
{
RaycastHit rh;
if (Physics.Raycast(m_waterCam.ScreenPointToRay(Input.mousePosition), out rh))
{
PopWater(rh.textureCoord);
}
}
time = (int)Time.deltaTime * 1000;
}
void OnDestroy()
{
f = false;
}
bool f = true;
void ThreadWave()
{
while (f)
{
Thread.Sleep(time);
for (int w = 1; w < m_texWidth - 1; w++)
{
for (int h = 1; h < m_texHeight - 1; h++)
{
waveB[w, h] =
(waveA[w - 1, h] +
waveA[w + 1, h] +
waveA[w, h - 1] +
waveA[w, h + 1] +
waveA[w - 1, h - 1] +
waveA[w + 1, h - 1] +
waveA[w - 1, h + 1] +
waveA[w + 1, h + 1]) / 4 - waveB[w, h];
float value = waveB[w, h];
if (value > 1)
{
waveB[w, h] = 1;
}
if (value < -1)
{
waveB[w, h] = -1;
}
if (value > -0.0001 && value < 0.0001)
{
waveB[w, h] = 0;
}
float offset_u = (waveB[w - 1, h] - waveB[w + 1, h]) / 2;
float offset_v = ((waveB[w, h - 1]) - waveB[w, h + 1]) / 2;
float r = offset_u / 2 + 0.5f;
float g = offset_v / 2 + 0.5f;
Color c = new Color(r, g, 0);
waveB[w, h] -= waveB[w, h] * decrement;
allColor[w + m_texWidth * h] = c;
}
}
float[,] temp;
temp = waveA;
waveA = waveB;
waveB = temp;
}
}
private Color[] allColor;
void ComputeWave()
{
m_waterTexture.SetPixels(allColor);
m_waterTexture.Apply();
}
}
效果圖:


以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Unity的BuildPlayerProcessor實(shí)用案例深入解析
這篇文章主要為大家介紹了Unity的BuildPlayerProcessor實(shí)用案例深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
Unity ScrollView實(shí)現(xiàn)自動(dòng)吸附效果
這篇文章主要為大家詳細(xì)介紹了Unity ScrollView實(shí)現(xiàn)自動(dòng)吸附效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07
.NET/C#實(shí)現(xiàn)識(shí)別用戶訪問設(shè)備的方法
這篇文章主要介紹了.NET/C#實(shí)現(xiàn)識(shí)別用戶訪問設(shè)備的方法,結(jié)合實(shí)例形式分析了C#識(shí)別用戶訪問設(shè)備的操作技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2017-02-02
如何用C#獲取計(jì)算機(jī)詳細(xì)的軟件和硬件信息
我們應(yīng)該都知道System.Management提供的類可以用于讀取本地計(jì)算機(jī)設(shè)備的各種數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于如何用C#獲取計(jì)算機(jī)詳細(xì)的軟件和硬件信息的相關(guān)資料,需要的朋友可以參考下2022-12-12
Unity實(shí)現(xiàn)物體沿自身的任意軸向旋轉(zhuǎn)
這篇文章主要為大家詳細(xì)介紹了Unity實(shí)現(xiàn)物體沿自身的任意軸向旋轉(zhuǎn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-01-01
C#配置log4net實(shí)現(xiàn)將日志分類記錄到不同的日志文件中
log4net是.Net下一個(gè)非常優(yōu)秀的開源日志記錄組件,log4net記錄日志的功能非常強(qiáng)大,它可以將日志分不同的等級(jí),以不同的格式,輸出到不同的媒介,下面我們就來看看C#如何配置log4net讓日志分類記錄到不同的日志文件吧2024-02-02

