1 水波特效原理

水波特效属于 Unity3D 后处理特效,其原理是:对渲染后的纹理进行局部挤压和拉升变换,即对局部 uv 坐标进行周期性的偏移运动,实现波纹效果。

1)波形方程

为简化水波模型,我们假设水波以机械波(正弦或余弦)传播,并且 0 时刻的水面波形函数为:

其中,r 是质点距离水波中心的半径长度,w1 是波形角频率(值越大,波纹越密),A 是质点水平振动的振幅,offset 是质点的水平偏移量。

2)振动方程

t 时刻,半径为 r 的质点水平偏移量为:

其中,w2 是质点水平振动的角频率(值越大,质点振动越快)。

2 代码实现

WaterWaveEffect.cs

using UnityEngine;[RequireComponent(typeof(Camera))]  // 屏幕后处理特效一般都需要绑定在像机上
public class WaterWaveEffect : MonoBehaviour {public float A = 0.01f; // 水面质点水平波动振幅public float w1 = 60; // 水波截面波形角频率(值越大, 波纹越密)public float w2 = 30; // 水面质点水平波动角频率(值越大, 水波质点振动越快)public float waveWidth = 0.3f; // 水波宽度(水波在扩散时, 后波会消失)public float waveSpeed = 0.3f; // 水波传播的速度private float waveTime; // 水波传播时间private Vector4 waveCenter; // 水波中心private Material waveMaterial; // 水波材质private bool enabledWave = false; // 水波开关private void Awake() {waveMaterial = new Material(Shader.Find("Custom/WaterWave"));waveMaterial.hideFlags = HideFlags.DontSave;}private void Update() {if (Input.GetMouseButton(0)) {waveCenter = new Vector2(Input.mousePosition.x / Screen.width, Input.mousePosition.y / Screen.height); // 屏幕坐标归一化enabledWave = true;waveTime = 0;}}void OnRenderImage (RenderTexture source, RenderTexture destination) {if (enabledWave) {SetWaveMaterialParams();Graphics.Blit (source, destination, waveMaterial);waveTime += Time.deltaTime;if (waveTime > 2 / waveSpeed) { // 水波传播到屏幕外面, 结束水波特效enabledWave = false;}} else {Graphics.Blit (source, destination);}}private void SetWaveMaterialParams() { // 设置水波材质参数waveMaterial.SetFloat("_A", A); // 水面质点水平波动振幅waveMaterial.SetFloat("_w1", w1); // 水波截面波形角频率(值越大, 波纹越密)waveMaterial.SetFloat("_w2", w2); // 水面质点水平波动角频率(值越大, 水波质点振动越快)waveMaterial.SetFloat("_t", waveTime); // 水波传播时间waveMaterial.SetVector("_o", waveCenter); // 水波中心waveMaterial.SetFloat("_waveDist", waveTime * waveSpeed); // 水波传播距离waveMaterial.SetFloat("_waveWidth", waveWidth); // 水波宽度(水波在传播时, 后波会消失)}
}

说明:WaterWaveEffect 脚本组件需要挂在相机下。

WaveShader.shader

Shader "Custom/WaterWave"
{Properties {_MainTex ("mainTex", 2D) = "white" {}}SubShader {Pass{ZTest AlwaysCull OffZWrite OffFog { Mode off }CGPROGRAM#pragma vertex vert_img // UnityCG.cginc中定义了vert_img方法, 对vertex和texcoord进行了处理, 输出v2f_img中的pos和uv#pragma fragment frag#pragma fragmentoption ARB_precision_hint_fastest#include "UnityCG.cginc"sampler2D _MainTex;float _A; // 水面质点水平波动振幅float _w1; // 水波截面波形角频率(值越大, 波纹越密)float _w2; // 水面质点水平波动角频率(值越大, 水波质点振动越快)float _t; // 水波传播时间float2 _o; // 水波中心坐标float _waveDist; // 水波传播距离float _waveWidth; // 水波宽度(水波在传播时, 后波会消失)fixed4 frag(v2f_img i) : SV_Target // 水波uv坐标的计算不能在顶点着色器中进行, 因为屏后处理的顶点只有屏幕的4个角顶点{float2 vec = i.uv - _o.xy;vec.x *= _ScreenParams.x / _ScreenParams.y; // 按照屏幕长宽比进行缩放float radius = length(vec); // 距离波中心的半径长度float leng = abs(radius - _waveDist);float offset = 0;if (leng < _waveWidth){offset = _A * sin(_w1 * radius - _w2 * _t) * (1 - leng / _waveWidth);}return tex2D(_MainTex, i.uv + offset * 0.707); // offset是一维的, uv是二维的, 需要除以根号2, 即乘以0.707}ENDCG}}Fallback off
}

3 运行效果

点击屏幕任意位置,出现水波如下,注意观察地面和天空交界的直线,可以明显看到正弦波形。

4 推荐阅读

  • 渲染管线
  • 固定管线着色器一
  • 固定管线着色器二
  • 表面着色器
  • 顶点和片段着色器
  • 选中物体描边特效
  • 基于模板测试和顶点膨胀的描边方法
  • 半球卷屏特效
  • 卷轴特效

【Unity3D】水波特效相关推荐

  1. Construct2 水波特效

    Construct2 水波特效 最近在上移动游戏开发 第一个作业就是用Construct2 做捕鱼达人 搜了挺多资料都没有发现教怎么做水波特效,于是自己瞎摸索了一下,没想到居然成功了. 1.首先可以背 ...

  2. (2356)忙里偷闲-封装汇编编写的水波特效供C++调用

    忙里偷闲-封装汇编编写的水波特效供C++调用 ---汇编语言与C++语言联编 考研复习呀!时间好紧张!很久没碰编程了,心痒难搔!呵呵 业余时间在看罗云彬的windows 32位汇编语言程序设计,苦于没 ...

  3. Unity3D屏幕特效合成

    Unity3D可以使用屏幕合成效果,估计很多人都知道,因为自带的屏幕特效包里面有很多这样的例子. 比如原来摄像机渲染出来的效果是这样的: 通过合成,你可以把它做颜色的偏移或者反转: 或者可以在上面合成 ...

  4. Unity3d 屏幕特效实现类似死亡之后的全屏黑白效果

    全屏特效 黑白(对于<着色器和屏幕特效开发秘籍>的学习) 可实现死亡效果或需要黑白特效的效果 原理是通过OnRenderImage()函数在摄像机渲染的时候,改变颜色(饱和度) 新建一个c ...

  5. Unity3d 游戏特效制作实战教程 第二部

    本套教程是由多年特效制作经验的作者录制,通过多个案例, 演示了xffect粒子系统与unitu3d粒子系统的特效制作的全部流程 包含xffect基础教程,并附送全部项目文件打包和素材. 本教学适合于U ...

  6. unity3d布料特效的简单使用

    布料是柔软变形的,比如说随风飘扬的旗子,或者是窗帘,下面我就先讲讲怎么创建一个简单的布料使用. 一,创建一个Plane,删除collider组件. 二,点击Plane,AddComponent添加Cl ...

  7. Unity3D粒子特效

    第一次粒子特效制作,边做边记录吧 首先 要拿到粒子的图片  爱心\雪花等 然后  在Assets下创建一个材质球     材质球Shader 选择particles\Additive   将你要设置的 ...

  8. 罗云彬:实现水波特效的代码例子

    _=_ _=_ Part 001 of 001 of file Ripper.zip _=_ begin 666 Ripper.zip M4$L#!!0````(`)BM5#&=/#HXK(H ...

  9. CSS3实现的4种水波特效

    (一)第一种方法 (1)HTML结构 <body> <div class="animate wave"><div class="w1&quo ...

最新文章

  1. Redis 击穿、穿透、雪崩产生原因以及解决思路
  2. 430亿晶体管,1020万逻辑单元,英特尔发布全球最大容量FPGA,用全新硬件加速AI开发...
  3. selenium 获取href find_element_by_xpath
  4. html读取文本框变量,Html和文本框元件上变量
  5. jQuery源码 Ajax模块分析
  6. java数组子类型_[改善Java代码]数组的真实类型必须是泛型类型的子类型
  7. 改变照片分辨率的软件_AI黑科技竟如此强大,模糊照片无损放大600%变得更清晰!...
  8. Attachment rename issue in Faas
  9. div水平垂直居中的六种方法
  10. 使用phpmyadmin管理远程sql_CentOS7系统配置phpMyAdmin
  11. 网络编程技术-----windows网络编程
  12. 学java要学哪些_想学好Java要学哪些东西
  13. NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy
  14. 斗图?教你用Python制作表情包
  15. 金融科技之交易:动量效应选股策略
  16. 九龙证券|主力出逃大热门互联网股近13亿元!尾盘两股获加仓超亿元
  17. 18篇文章系统解读:中台规划如何撬动企业IT基础设施转型升级
  18. 美国达高特DAKOTA超声波测厚仪检测仪维修
  19. Android AOSP和Android-X86源码下载编译终极普法
  20. Unity Steam_VR 开发工具插件 VRTK自带案例分析(第一部分)

热门文章

  1. 又一篇Android Recovery的文章
  2. html 标准通用标记语言下,HTML超文本标记语言常用的一些标签
  3. recovery之刷机脚本自定义(解决刷zip文件时出现Status 6错误)
  4. nyoj 1099 Lan Xiang's Square (水题)
  5. MATLAB---读取STL文件并解析
  6. 【电机控制】Arduino mega 2560控制42步进电机接线
  7. SQL注入靶场 RedTiger通关教程(level1~level10)
  8. 微信发个原图,居然隐私曝光这么多…可怕
  9. DDD的模式与实践案例
  10. 又有2名博士入选华为“天才少年”!学霸日常科研计划表曝光