unity实现透明水波纹扭曲
程序员文章站
2022-11-19 19:12:02
本文实例为大家分享了unity实现透明水波纹扭曲的具体代码,供大家参考,具体内容如下需要挂一个摄像机把脚本挂在一个物体上可随意在物体上面点击shader:shader "unlit/water"{ p...
本文实例为大家分享了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<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(); } }
效果图:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: Unity3D Shader实现镜子效果