【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教程:2D游戏技能特效

    在我们的2D图形游戏中不可缺少大量的光影、技能特效,像Diablo II中的魔法效果的实现,幸好我们拥有强大的CPU来为我们实现Alpha混合与色彩饱和混合,接下来让我们来讨论一下如何用这些方法来实现我们游戏中所需要的技能特效。     一、Alpha混合特效     Alpha混合可以让我

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

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

    2024年02月02日
    浏览(44)
  • Unity3D粒子系统之制作烟雾特效

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    2024年02月05日
    浏览(62)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包