【实现100个unity特效之12】Unity中的冲击波 ——如何使用ShaderGraph制作一个冲击波着色器

news2024/11/16 5:52:40

最终效果

在这里插入图片描述

文章目录

  • 最终效果
  • 新增LitShaderGraph
  • 圆环扭曲效果
  • 优化冲击波效果
  • 屏幕全屏冲击波
  • 圆形冲击波
  • 最终连线图
  • 代码控制
  • 补充
  • 源码
  • 完结

新增LitShaderGraph

在这里插入图片描述

圆环扭曲效果

让我们从一个UV节点开始
在这里插入图片描述

创建一个Vector2变量RingSpawnPosition表示冲击波生成位置,在X和Y上将其默认值设置为0.5,因为我们正在使用范围从零到一的UV坐标,所以0.5是中心
在这里插入图片描述

将生成位置减去UV,重新定向UV,以生成环形效果
在这里插入图片描述

现在让我们拖动它进入一个Length节点,你可以把长度想象成大小,可以看到,现在围绕它的生成位置生成了圆环
在这里插入图片描述
接下来,创建一个Size大小浮点数,我们将使用它来控制影响的大小
在这里插入图片描述

把它拖到一个ADD加法和一个Subtract减法节点中,然后将它们组合回一个带有长度节点的Smoothstep平滑步长节点作为我们的输入,这为我们提供了圆环的基础
在这里插入图片描述
新增变量,我们需要它从-0.1开始,因为这里的大小不同,我们将其默认为0.5
在这里插入图片描述
将它挂钩到我们的加减节点
在这里插入图片描述

它还不是个圆环,因为我们需要首先通过将它插入一个减节点然后乘以反转这个平滑的步骤,所以我们现在终于有了我们的圆环效果
在这里插入图片描述

如果我们添加另一个UV节点,并将它添加到我们的圆环上
在这里插入图片描述
让我们将它插入我们的Sample Texture 2D主图UV输入样本节点并测试它
Sample Texture 2D节点,接收一个Texture2d类型的输入,输出这个Texture2d的RGBA,Unity它会自动根据这个reference上的值,从我们的精灵中尝试找到对应的纹理,而我们的主纹理里名称就是这个MainTex,就会自动找到主纹理
在这里插入图片描述
新增材质,放在一个背景图片上
在这里插入图片描述
通过修改修改WaveDistanceFromCenter查看冲击波效果
在这里插入图片描述

优化冲击波效果

可以看到它现在是以某种方式扭曲并不是我们想要的效果,回到我们的着色器,并回到我们开始的减法节点在这里,我们对其进行归一化(Normalize节点)
在这里插入图片描述

这里也是添加强度控制的好地方,所以让我们创建一个名为ShockWaveStrength的暴露浮动并将其默认为负0.1,如果您希望它看起来凸起,则必须为负值,让我们将其设为-5和5之间的滑块。
在这里插入图片描述

现在让我们将我们的强度乘以我们的Normalize节点
在这里插入图片描述

我们要将这两个节点相乘,重新连接输出
在这里插入图片描述
效果
在这里插入图片描述

屏幕全屏冲击波

要实现屏幕全屏冲击波,首先就要想办法获取相机渲染的内容

新增变量2D纹理称为CameraSortingLayerTexture,命名一定不能错,它和我们的主纹理MainTex命名一样,unity会按名称自己去查找获取相机渲染的纹理

重点:还有重点记得取消勾选Exposed,不然后续不会生效
在这里插入图片描述
替换之前的MainTex主纹理连线并输出效果
在这里插入图片描述
新建CameraSortingLayer排序层,无论你的游戏有多少层,它都是得排最高,这实际上意味着它将被渲染在其他所有东西之上现在
在这里插入图片描述

修改冲击波排序图层
在这里插入图片描述
不要忘记添加此层到你的2D灯光
在这里插入图片描述

修改URP配置,在这里看到一个相机排序层纹理选项,它通常默认设置为禁用,让我们将其更改为除冲击波层外的最上面的排序层,我这里是Player层
注意:如果选了CameraSortingLayer,会一直会自己渲染自己,且应该会很卡,影响性能,所以切记不要选错了
在这里插入图片描述
在这样做之后,你应该立即看到我们的冲击波层渲染了一些东西,但这不是我们想要的,他基本上只是把我们场景视图内容放在Sprite之上的快照,而我们要显示相机显示的内容
在这里插入图片描述

我们要的是显示当前的屏幕位置到底是什么,用屏幕位置节点(Screen Position)替换之前的UV节点
在这里插入图片描述

将冲击波尺寸大概贴合屏幕即可
在这里插入图片描述
查看效果
在这里插入图片描述

圆形冲击波

目前可以看到,冲击波不是一个完美的圆圈,这是因为我们的屏幕尺寸
比如我在1920x1080尺寸上播放,通过计算比例
在这里插入图片描述
也就是说,x拉伸了1.777,但是如果我们直接y轴剩余这个拉伸量,肯定不合理,因为我们屏幕的尺寸是会变化的
这里可以通过Screen节点,获取屏幕宽高值,使用Divide节点,屏幕宽除以屏幕高

将UV通过Split切割,其中R就是x坐标,g就是y坐标,R乘以这个比例
在这里插入图片描述
效果
在这里插入图片描述

最终连线图

在这里插入图片描述

代码控制

将冲击波挂载在相机下
在这里插入图片描述

新增脚本,注意:如果你让它在那里一直处于开启状态,因为它会渲染两次,浪费性能,所以我们控制在需要时实际禁用和启用它

/// <summary>
/// 冲击波
/// </summary>
public class RippleEffect : MonoBehaviour
{
    [SerializeField] private float _shockWaveTime = 0.75f; // 冲击波持续时间
    private Coroutine _shockWaveCoroutine; // 冲击波效果的协程引用

    private Material _material;
    private static int _waveDistanceFromCenter = Shader.PropertyToID("_WaveDistanceFromCenter"); // 波从中心点的距离的Shader属性ID
    private static int _ringSpawnPosition = Shader.PropertyToID("_RingSpawnPosition");

    private void Awake()
    {
        _material = GetComponent<SpriteRenderer>().material;
    }

    // 公共方法,用于触发冲击波效果
    public void CallShockWave(Vector2 pos)
    {
        if (_shockWaveCoroutine != null)
        {
            StopCoroutine(_shockWaveCoroutine); // 如果已有协程在运行,先停止它
        }

        // 将世界坐标转换为视口坐标(UV坐标) 视口坐标是一个单位矩形,左下角是(0,0),右上角是(1,1)
        Vector3 viewportPos = Camera.main.WorldToViewportPoint(pos);
        Vector2 uvPos = new Vector2(viewportPos.x, viewportPos.y);

        _material.SetVector(_ringSpawnPosition, uvPos); // 设置位置

        _shockWaveCoroutine = StartCoroutine(ShockWaveAction(-0.1f, 1f)); // 启动新的协程来实现冲击波效果
    }

    // 冲击波效果的协程方法
    private IEnumerator ShockWaveAction(float startPos, float endPos)
    {
        Debug.Log(111);
        _material.SetFloat(_waveDistanceFromCenter, startPos); // 设置初始值

        float elapsedTime = 0f; // 初始化经过时间
        while (elapsedTime < _shockWaveTime)
        {
            elapsedTime += Time.deltaTime; // 累加经过时间
            float lerpedAmount = Mathf.Lerp(startPos, endPos, elapsedTime / _shockWaveTime); // 计算插值量
            _material.SetFloat(_waveDistanceFromCenter, lerpedAmount); // 设置材质属性
            yield return null; // 等待下一帧
        }
        gameObject.SetActive(false);
    }
}

调用

public RippleEffect rippleEffect;

//触发冲击波
public void PlayRippleEffect(Vector2 pos)
{
    rippleEffect.gameObject.SetActive(true);
    rippleEffect.CallShockWave(pos);
}

配置
在这里插入图片描述
通常你可以选择在二段跳调用它,比如我们实现在人物冲刺时启动它,pos传入的就是人物世界坐标,效果
在这里插入图片描述

补充

输出圆环其实有更加方便的方式
我们可以用极坐标的特性,直接分离出一个从中间开始的渐变,R就是中间黑,四周白的渐变
在这里插入图片描述

源码

整理好了会分享出来

完结

赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注,以便我第一时间收到反馈,你的每一次支持都是我不断创作的最大动力。当然如果你发现了文章中存在错误或者有更好的解决方法,也欢迎评论私信告诉我哦!

好了,我是向宇,https://xiangyu.blog.csdn.net

一位在小公司默默奋斗的开发者,出于兴趣爱好,最近开始自学unity,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!php是工作,unity是生活!如果你遇到任何问题,也欢迎你评论私信找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1975603.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

springboot实现前后端调用axios异步请求(后端单体服务器static部分)

目的&#xff1a;让页面调用controller&#xff0c;将数据加载到页面中&#xff08;只不过这个前端页面我们直接就是放到了static里面了&#xff09;。 第一步&#xff1a;导入文件 所需要的文件见本文最后“文件获取”&#xff1a; &#xff08;1&#xff09;文件如下&…

汇昌联信拼多多运营怎么样?

汇昌联信拼多多运营怎么样?在探讨汇昌联信在拼多多平台的运营情况时&#xff0c;首先需要明确的回答是&#xff1a;汇昌联信在拼多多的运营表现是积极的&#xff0c;并取得了一定的成效。接下来&#xff0c;我们将从五个不同的角度深入分析其运营策略及效果。 一、产品多样性与…

Centos7挂载数据盘

查看当前服务器有哪些磁盘 fdisk -l 2.格式化 mke2fs -t ext4 /dev/vdc 3.挂载数据盘 mkdir /sdxinfang mount /dev/vdc /sdxinfang/ 为了避免每次开机都要重新挂载&#xff0c;直接设置系统挂载信息&#xff0c;这样开机会自动挂载 vim /etc/fstab 在文件末尾增加以下内容&…

Axure八大优质Web端系统框架模版

在当今数字化转型的浪潮中&#xff0c;Axure作为一款强大的原型设计工具&#xff0c;以其快速、直观和易用的特点&#xff0c;成为了众多设计师和产品经理的首选。本文将详细介绍六套基于Axure制作的智慧系统原型框架模版&#xff0c;包括智慧园区、智慧社区、智慧乡村、智慧驾…

4个好用的 CSS 伪类 :not()、:has()、 :is()、:where()

文章目录 &#xff08;1&#xff09;:not()&#xff08;2&#xff09;:has()&#xff08;3&#xff09;:is()&#xff08;4&#xff09;:where()&#xff08;5&#xff09;:where()与:is() 的区别 &#xff08;1&#xff09;:not() :not 伪类&#xff1a;用于选择不满足给定条…

微信小程序开发费用一览表,不同开发方式的费用对比

微信小程序作为当前移动互联网领域的重要入口之一&#xff0c;其开发费用因开发方式、功能需求、设计复杂度及开发团队的不同而有所差异。本文将详细梳理微信小程序开发的几种主要方式&#xff0c;并对比各方式的费用情况&#xff0c;以便企业和个人在选择时能够有更清晰的了解…

PHP 打印 V 和倒 V 图案的程序(Program to print V and inverted-V pattern)

倒 V 型模式&#xff1a;给定 n 的值&#xff0c;打印倒 V 型模式。示例&#xff1a; 输入&#xff1a;n 5 输出 &#xff1a; E D D C C B B A A 输入&#xff1a;n 7 输出 &#xff1a; G F F E E D D C C B B A…

pycharm中安装、使用扩展工具,以QT Designer为例

pycharm中安装、使用扩展工具&#xff0c;以QT Designer为例 第一步&#xff0c;下载QT Designer安装包。找到QT Designer.exe所在位置&#xff0c;复制路径 第二步&#xff0c;打开Pycharm&#xff0c;选择Setting&#xff0c;找到扩展工具&#xff08;External Tools&#xf…

git回退未commit、回退已commit、回退已push、合并某一次commit到另一个分支

文章目录 1、git回退未commit2、git回退已commit3、git回退已push的代码3.1 直接丢弃某一次的push3.2 撤销push后&#xff0c;不丢弃改动&#xff0c;重新修改后要再次push 4、合并某一次commit到另一个分支 整理几个工作上遇到的git问题。 1、git回退未commit git回退未comm…

【C++】STL-哈希表封装unorder_set和unordered_map

目录 1、实现哈希表的泛型 2、unordered_set和unordered_map的插入 3、迭代器 3.1 operator 3.2 const迭代器 4、find 5、unordered_map的operator[] 6、对于无法取模的类型 7、介绍unordered_set的几个函数 7.1 bucket_count 7.2 bucket_size 7.3 bucket 7.4 rese…

Gcc/G++编译C/C++文件(主要以C++语言为主,C语言就做阐述 用法一样 就是将G++换成GCC)

首先&#xff0c;我们在Linux中创建一个helloc.cc文件(C文件) vim helloc.cc 直接用g裸编译 g helloc.cc 生成的a.out就是二进制可执行文件 如果要产生 自定义可执行文件 就需要下面的编译步骤 繁琐操作 g -c helloc.cc 会生成目标文件 g -o hello helloc.o 此时hell…

仿SOUL社交友附近人婚恋约仿陌陌APP系统源码

专门为单身男女打造的恋爱交友社区&#xff0c;就是一个由千千万万单身男女组建的大家庭。他们来自全国各地&#xff0c;或许有着不同的人生经历&#xff0c;却有着共同的对恋爱交友的渴望。他们可以通过文字、语音、视频聊天的方式&#xff0c;和镜头前的彼此诉说自己工作中发…

95页PPT丨IBM-IT应用规划

一、IBM针对IT应用规划项目核心内容IBM在IT应用规划项目中的核心内容&#xff0c;旨在帮助企业实现数字化转型&#xff0c;优化IT资源配置&#xff0c;并确保IT战略与业务目标的一致性。以下是IBM IT应用规划项目的详细核心内容&#xff1a; 资料下载方式&#xff0c;请看每张…

LabVIEW与CANopen实现自动化生产线的设备控制与数据采集

在某工厂的自动化生产线上&#xff0c;多个设备通过CANopen网络进行通信和控制。这些设备包括传感器、执行器和PLC&#xff0c;它们共同负责监测和控制生产过程中的关键参数&#xff0c;如温度、压力、速度等。为了实现对整个生产线的集中监控和管理&#xff0c;工厂决定使用La…

深入理解同城代驾系统源码:技术架构与实现细节

今天&#xff0c;小编将深入讲解同城代驾系统的技术架构与实现细节。 一、同城代驾系统的基本功能模块 一个完整的同城代驾系统通常包括以下核心功能模块&#xff1a; 1.用户端应用 2.司机端应用 3.后台管理系统 4.消息推送与通知 二、技术架构设计 同城代驾系统的技术架…

程序设计基础(c语言)_补充_1

1、编程应用双层循环输出九九乘法表 #include <stdio.h> #include <stdlib.h> int main() {int i,j;for(i1;i<9;i){for(j1;j<i;j)if(ji)printf("%d*%d%d",j,i,j*i);elseprintf("%d*%d%-2d ",j,i,j*i);printf("\n");}return 0…

DNS处理模块 dnspython

DNS处理模块 dnspython 标题介绍安装dnspython 模块常用方法介绍实践&#xff1a;DNS域名轮询业务监控 标题介绍 Dnspython 是 Python 的 DNS 工具包。它可用于查询、区域传输、动态更新、名称服务器测试和许多其他事情。 dnspython 模块提供了大量的 DNS 处理方法&#xff0c…

Flink 实时数仓(五)【DWD 层搭建(三)交易域事实表】

前言 今天开始交易域事实表的创建&#xff0c;上一节流量域中的表&#xff08;其实就是一个 kafka 主题&#xff09;数据来自于日志&#xff0c;而交易域的数据来自于业务系统&#xff0c;业务表之间是有关联性的。 我们之前在离线数仓中&#xff08;声明粒度&#xff08;最细粒…

oracle数据库监控数据库中某个表是否正常生成

事情经过&#xff1a; 公司某业务系统每月25日0点会自动生成下个月的表&#xff0c;表名字是tabname_202407的格式。由于7月25日0点做系统保养的时候重启了应用系统服务&#xff0c;导致8月份的表没有生成。最终操作业务影响&#xff0c;为此决定对这个表进行监控&#xff0c;…

Depth Anything——强大的单目深度估计模型

概述 单目深度估计&#xff08;Monocular Depth Estimation, MDE&#xff09;是一项在计算机视觉领域中非常重要的技术&#xff0c;它旨在从单张图像中恢复出场景的三维结构。这项技术对于机器人导航、自动驾驶汽车、增强现实&#xff08;AR&#xff09;和虚拟现实&#xff08…