当前位置: 移动技术网 > IT编程>开发语言>c# > Unity Shader实现水波纹效果

Unity Shader实现水波纹效果

2020年06月23日  | 移动技术网IT编程  | 我要评论
本文实例为大家分享了unity shader实现水波纹的具体代码,供大家参考,具体内容如下效果:shader代码:shader "custom/shuibowen"{ properties{ _mai

本文实例为大家分享了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,1)
 _maintex_texelsize("maintex_texelsize",vector)=(1,1,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), 0, 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, 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, 0);
   wavestarttime = time.time;
  }

 }
}

新建一个材质球,选择此shader,并赋值给这个脚本,点击屏幕即可看到效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持移动技术网。

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网