Unity Shader实现水波纹效果

所属分类: 软件编程 / C#教程 阅读数: 85
收藏 0 赞 0 分享

本文实例为大家分享了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,并赋值给这个脚本,点击屏幕即可看到效果

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

更多精彩内容其他人还在看

WPF仿三星手机充电界面实现代码

这篇文章主要为大家详细介绍了WPF仿三星手机充电界面实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

浅谈C#各种数组直接的数据复制/转换

下面小编就为大家带来一篇浅谈C#各种数组直接的数据复制/转换。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

C#访问SQLServer增删改查代码实例

这篇文章主要为大家详细介绍了C#访问SQLServer增删改查代码实例,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

C#根据身份证号码判断出生日期和性别

这篇文章主要为大家详细介绍了C#根据身份证号码判断出生日期和性别的方法,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

C# 向Word中设置/更改文本方向的方法(两种)

在一般情况下word中输入的文字都是横向的,今天小编给大家带来两种方法来设置更改文本方向的方法,非常不错,对c# word 更改文本方向的知识感兴趣的朋友一起看看吧
收藏 0 赞 0 分享

让C# Excel导入导出 支持不同版本Office

让C# Excel导入导出,支持不同版本的Office,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

C#设置自定义文件图标实现双击启动(修改注册表)

这篇文章介绍的是利用C#设置自定义文件图标,然后实现双击启动的功能,文章给出了示例代码,介绍的很详细,有需要的可以参考借鉴。
收藏 0 赞 0 分享

C#两个相同属性的类赋值方法

这篇文章主要介绍了C#两个相同属性的类赋值方法的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

C#中ListView控件实现窗体代码

这篇文章主要介绍了C#中ListView控件实现窗体的核心代码,非常不错,具有参考借鉴价值,对c#listview相关知识感兴趣的朋友一起学习吧
收藏 0 赞 0 分享

浅谈C# 序列化与反序列化几种格式的转换

下面小编就为大家带来一篇浅谈C# 序列化与反序列化几种格式的转换。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多