【Unity3D】水波特效
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】水波特效相关推荐
- Construct2 水波特效
Construct2 水波特效 最近在上移动游戏开发 第一个作业就是用Construct2 做捕鱼达人 搜了挺多资料都没有发现教怎么做水波特效,于是自己瞎摸索了一下,没想到居然成功了. 1.首先可以背 ...
- (2356)忙里偷闲-封装汇编编写的水波特效供C++调用
忙里偷闲-封装汇编编写的水波特效供C++调用 ---汇编语言与C++语言联编 考研复习呀!时间好紧张!很久没碰编程了,心痒难搔!呵呵 业余时间在看罗云彬的windows 32位汇编语言程序设计,苦于没 ...
- Unity3D屏幕特效合成
Unity3D可以使用屏幕合成效果,估计很多人都知道,因为自带的屏幕特效包里面有很多这样的例子. 比如原来摄像机渲染出来的效果是这样的: 通过合成,你可以把它做颜色的偏移或者反转: 或者可以在上面合成 ...
- Unity3d 屏幕特效实现类似死亡之后的全屏黑白效果
全屏特效 黑白(对于<着色器和屏幕特效开发秘籍>的学习) 可实现死亡效果或需要黑白特效的效果 原理是通过OnRenderImage()函数在摄像机渲染的时候,改变颜色(饱和度) 新建一个c ...
- Unity3d 游戏特效制作实战教程 第二部
本套教程是由多年特效制作经验的作者录制,通过多个案例, 演示了xffect粒子系统与unitu3d粒子系统的特效制作的全部流程 包含xffect基础教程,并附送全部项目文件打包和素材. 本教学适合于U ...
- unity3d布料特效的简单使用
布料是柔软变形的,比如说随风飘扬的旗子,或者是窗帘,下面我就先讲讲怎么创建一个简单的布料使用. 一,创建一个Plane,删除collider组件. 二,点击Plane,AddComponent添加Cl ...
- Unity3D粒子特效
第一次粒子特效制作,边做边记录吧 首先 要拿到粒子的图片 爱心\雪花等 然后 在Assets下创建一个材质球 材质球Shader 选择particles\Additive 将你要设置的 ...
- 罗云彬:实现水波特效的代码例子
_=_ _=_ Part 001 of 001 of file Ripper.zip _=_ begin 666 Ripper.zip M4$L#!!0````(`)BM5#&=/#HXK(H ...
- CSS3实现的4种水波特效
(一)第一种方法 (1)HTML结构 <body> <div class="animate wave"><div class="w1&quo ...
最新文章
- Redis 击穿、穿透、雪崩产生原因以及解决思路
- 430亿晶体管,1020万逻辑单元,英特尔发布全球最大容量FPGA,用全新硬件加速AI开发...
- selenium 获取href find_element_by_xpath
- html读取文本框变量,Html和文本框元件上变量
- jQuery源码 Ajax模块分析
- java数组子类型_[改善Java代码]数组的真实类型必须是泛型类型的子类型
- 改变照片分辨率的软件_AI黑科技竟如此强大,模糊照片无损放大600%变得更清晰!...
- Attachment rename issue in Faas
- div水平垂直居中的六种方法
- 使用phpmyadmin管理远程sql_CentOS7系统配置phpMyAdmin
- 网络编程技术-----windows网络编程
- 学java要学哪些_想学好Java要学哪些东西
- NoClassDefFoundError: ch/qos/logback/classic/spi/ThrowableProxy
- 斗图?教你用Python制作表情包
- 金融科技之交易:动量效应选股策略
- 九龙证券|主力出逃大热门互联网股近13亿元!尾盘两股获加仓超亿元
- 18篇文章系统解读:中台规划如何撬动企业IT基础设施转型升级
- 美国达高特DAKOTA超声波测厚仪检测仪维修
- Android AOSP和Android-X86源码下载编译终极普法
- Unity Steam_VR 开发工具插件 VRTK自带案例分析(第一部分)
热门文章
- 又一篇Android Recovery的文章
- html 标准通用标记语言下,HTML超文本标记语言常用的一些标签
- recovery之刷机脚本自定义(解决刷zip文件时出现Status 6错误)
- nyoj 1099 Lan Xiang's Square (水题)
- MATLAB---读取STL文件并解析
- 【电机控制】Arduino mega 2560控制42步进电机接线
- SQL注入靶场 RedTiger通关教程(level1~level10)
- 微信发个原图,居然隐私曝光这么多…可怕
- DDD的模式与实践案例
- 又有2名博士入选华为“天才少年”!学霸日常科研计划表曝光