本文实例为大家分享了unity实现透明水波纹扭曲的具体代码,供大家参考,具体内容如下
需要挂一个摄像机把脚本挂在一个物体上
可随意在物体上面点击
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().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(); } }
效果图: