【Unity3D】水波特效

这篇具有很好参考价值的文章主要介绍了【Unity3D】水波特效。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1 水波特效原理

        水面特效 中基于 Shader Graph 实现了模拟水面特效,包含波纹、起伏、折射、泡沫等细节,本文将基于屏幕后处理实现环形水波特效。

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

        1)波形方程

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

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

        2)振动方程

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

【Unity3D】水波特效

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

        本文代码资源见:Unity3D水波特效。

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 Always
            Cull Off
            ZWrite Off
            Fog { 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 运行效果

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

【Unity3D】水波特效文章来源地址https://www.toymoban.com/news/detail-415472.html

4 推荐阅读

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

到了这里,关于【Unity3D】水波特效的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Unity3D】激光灯、碰撞特效

    1 需求描述         本文将模拟激光灯(或碰撞)特效,详细需求如下: 从鼠标位置发射屏幕射线,检测是否与物体发生碰撞 当与物体发生碰撞时,在物体表面覆盖一层激光灯(或碰撞)特效         本文代码见→激光灯、碰撞特效 2 原理         获取屏幕射线与物体

    2023年04月25日
    浏览(37)
  • Unity3D粒子系统之制作烟雾特效

    本文将会介绍如何使用Unity内的粒子系统制作烟雾效果。 如果想了解Unity粒子系统中的基础属性,可以看这篇博客:Unity3D 粒子系统之基础属性介绍 先附上预览图: 材质贴图 首先我们需要一张烟雾材质用的材质贴图,我是自己画的,可以参考下图自己画一张或者去网上找素材

    2024年02月02日
    浏览(42)
  • Unity3D粒子系统之制作火焰特效

    本文将会介绍如何使用Unity内的粒子系统制作烟雾效果。 如果想了解Unity粒子系统中的基础属性,可以看这篇博客:Unity3D粒子系统之基础属性介绍 先上预览图吧 用自己熟悉的绘画工具画一张类似这样的图片(相似即可,白灰色部分边缘不规则),注意一定要黑底。 将画好的

    2024年02月02日
    浏览(35)
  • 【Unity3D赛车游戏优化篇】【十】汽车粒子特效和引擎咆哮打造极速漂移

    👨‍💻个人主页 :@元宇宙-秩沅 👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 👨‍💻 本文由 秩沅 原创 👨‍💻 收录于专栏 :Unity游戏demo – 😶‍🌫️版本: Unity2021 😶‍🌫️适合人群:Unity初学者进阶 😶‍🌫️学习目标:3D赛车游戏的基础制作 😶‍🌫️技能

    2024年02月09日
    浏览(45)
  • 【Unity3d】【原理】【实践】协程的原理和实践

    原理 协程,需要从迭代器说起。 协程的执行,可以归结为,每帧执行一次迭代,直到迭代结束,返回。 迭代器,IEnumerator接口的实现。其中的核心迭代功能,在 bool MoveNext() 中,若返回为true,则表明当前未结束;若返回false,则表明当前迭代结束。 若迭代未结束,则需是的迭代

    2023年04月09日
    浏览(67)
  • Unity3D中的C#协程(概念、使用方法、底层原理)

             Unity3D 中的协程是针对 Unity3D 框架和 C# 编程语言定制的 ,具有便捷的使用方式和良好的效率。其他语言Python、Lua等也支持协程,但是底层实现的细节可能不同。在 Unity3D 引擎中, 协程被 Unity3D 引擎的主循环所驱动 。         协程(Coroutine)是一种编程概念

    2024年02月08日
    浏览(42)
  • Unity3D TCP网络通讯核心意涵与基本原理详解

    在Unity3D中,TCP网络通讯是一种常用的通讯方式,它可以实现可靠的数据传输和连接。 对惹,这里有一 个游戏开发交流小组 ,希望大家可以点击进来一起交流一下开发经验呀 本文将详细介绍Unity3D TCP网络通讯的核心意涵与基本原理,包括技术详解和代码实现。 一、TCP网络通

    2024年03月12日
    浏览(36)
  • Unity3D 实现基于物理引擎的绳子关节解析详解

    在游戏开发中,有时候我们需要实现绳子关节效果,比如在射击游戏中射击绳子,或者在平衡游戏中使用绳子作为支撑。本文将详细介绍如何使用Unity3D的物理引擎实现绳子关节效果。 对惹,这里有一 个游戏开发交流小组 ,希望大家可以点击进来一起交流一下开发经验呀 首

    2024年02月21日
    浏览(68)
  • 论文解析-基于 Unity3D 游戏人工智能的研究与应用

    这段代码是一个重写了 AgentAction 方法的方法。以下是对每行代码解释: ①public override void AgentAction(float[] vectorAction) 这行代码声明了一个公共的、重写了父类的 AgentAction 方法的方法。它 接受一个 float 类型的数组作为参数。 ② float newAction0 = Mathf.Clamp(vectorAction[0], -1, 1); 这行代

    2024年02月03日
    浏览(40)
  • 【毕业论文】| 基于Unity3D引擎的冒险游戏的设计与实现

    📢博客主页:肩匣与橘 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正! 📢本文由 肩匣与橘 编写,首发于 CSDN 🙉 📢生活依旧是美好而又温柔的,你也是✨  基于Unity3D引擎的冒险游戏的设计与实现 📢前言 摘要 Abstract 1 绪论 1.1 选题背景 1.2 研究目的及意义 2 开发工具

    2024年02月05日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包