【游戏开发实战】教你在Unity中实现模型消融化为灰烬飘散的效果(ShaderGraph | 消融 | 粒子系统 | 特效)

一、前言

嗨,大家好,我是新发。
有小伙伴在提问区给我提了这个问题,想要做一个模型消融化作灰烬飘散的效果,
在这里插入图片描述
我之前写过一篇ShaderGraph的教程:《ShaderGraph使用教程与各种特效案例》
里面实现了多种常见的特效效果,也包括消融的效果,不过没有实现灰烬飘散的效果,今天,我就尝试使用ShaderGraph来实现这个效果吧~

本文我实现了两种效果,最终如下:
请添加图片描述

话不多说,我们开始吧~

二、ShaderGraph环境准备

因为本文我使用的是UnityShaderGraph来实现上面的效果的,需要先安装ShaderGraph相关插件,并做一些基础设置。
可以查看我之前这篇博客《ShaderGraph使用教程与各种特效案例》的环境准备部分,这里我就不赘述具体操作了。
在这里插入图片描述

三、模型准备:原神角色模型

本文我使用的是原神的角色模型,我之前写过一篇文章讲如何从原神官网下载角色模型并制作成FBX格式导入Unity的教程,感兴趣的同学可以看下:《【游戏开发实战】下载原神模型,PMX转FBX,导入到Unity中,卡通渲染,绑定人形动画(附Demo工程)》
请添加图片描述

四、实现思路

在讲具体操作之前,我先说一下实现思路,本文我实现了两种效果,这里分别讲一下。

1、效果一的实现思路

效果一
请添加图片描述
思路:使用Alpha Clip对模型进行裁切,切口处做一层随机噪声来控制Alpha Clip,并使用随机噪声对消融的顶点做坐标扰动,最后混合一个颜色即可。

画个思维图,
在这里插入图片描述

2、效果二的实现思路

效果二
请添加图片描述
思路:依然是使用Alpha Clip对模型进行消融控制,在此基础上,再添加一个粒子效果,粒子的喷射Shape使用角色的网格,粒子加一些噪声扰动,达到风吹的效果,再根据滑块的值分别控制消融进度和粒子的喷射属性即可。

注:这个效果并不是那些消融的碎片作为灰烬飘散,而是粒子单独去喷射一个灰烬的效果,其实有点障眼法,这是我想到的一个取巧的办法,如果你有更好更逼真的办法,欢迎交流。

画个思维图,分两个,一个是模型的,如下
在这里插入图片描述
还有一个是粒子的,粒子的稍微简单一点,就是贴图采样,然后混合顶点颜色,再使用贴图采用的Alhpa通道来控制Alpha
在这里插入图片描述

五、ShaderGraph具体实现

1、效果一

1.1、创建Unlit Shader Graph

这里我不考虑光照效果,所以创建UnlitShader,在Project窗口右键点击菜单Create / Shader / Universal Render Pipeline / Unlit Shader Graph,如下
在这里插入图片描述
双击创建的文件即可打开Shader Graph编辑器。

1.2、获取顶点坐标的y轴坐标

我们先通过Position节点拿到顶点坐标(注意我这里取的是Object空间下的坐标),再通过Split拿到G分量,也就是顶点坐标的y坐标,
在这里插入图片描述

1.3、滑块控制

创建一个float节点,命名为disolve,并转为属性,类型选择Slider(即滑块),用它与刚刚的顶点坐标的y分量做一次平滑阶跃,得到的这个输出可以作为后面颜色混合和顶点扰动的输入,
在这里插入图片描述

1.4、边缘噪声

接着我们创建一个噪声节点Simple Noise,通过定时器控制UV偏移,如下,这个噪声用于对边缘进行扰动,
在这里插入图片描述

1.5、AlhpaClip控制

我们把噪声与滑块值相加,再与定点坐标的y分量做一个Step阶跃,得到颗粒感的边界,最后反一下,作为AlphaClip的输入,
在这里插入图片描述
需要注意AlphaAlpha Clip的关系:当Alpha Clip的值比Alpha大的时候,像素颜色就会被丢弃,一般我会把Alpha设置为0.5
在这里插入图片描述

1.6、边缘渐变色

把步骤1.3的输出拿过来,与一个颜色混合,再进行加强,得到一个边缘渐变色,
在这里插入图片描述

1.7、输出基础色

对贴图进行采样,与边缘渐变色混合,作为基础色输出到片元着色器的Base Color
在这里插入图片描述

1.8、顶点坐标扰动

我想要消融的地方的顶点有一个坐标扰动的效果,我构造了一个坐标扰动的噪声,如下,这里的扰动规则可自行发挥,我是采用Simple Noisexy轴进行扰动,使用Gradient Noisey轴进行扰动,
在这里插入图片描述

1.9、插值计算顶点坐标

我们把噪声与顶点坐标相加,再通过滑块控制线性插值,得到最终顶点坐标,输出给顶点着色器的Position
在这里插入图片描述

1.10、完整节点图

最终完整的节点图如下,肯定看不清,只是给大家看下整体结构,想要看细节的同学可下载本文的工程源码进行查看,
在这里插入图片描述

2、效果二

2.1、创建Unlit Shader Graph

同理是先创建一个Unlit Shader Graph,双击打开。

2.2、双噪声叠加扰动

消融效果需要一个噪声,我这里采用了双噪声叠加的方式,分别对噪声一噪声二的UVV分量做相反反向的偏移,最终混合出一个双噪声混合的效果,
在这里插入图片描述

2.2、计算AlphaClip

我们创建一个float节点,作为滑块,与刚刚的噪声做一个阶跃,输出结果作为AlphaClip
在这里插入图片描述
片元着色器的Alpha设置为0.5
在这里插入图片描述

2.3、计算描边

滑块与噪声做一个阶跃,再与刚刚计算的AlphaClip相减,就可以得到噪声的描边了,再混合一个颜色即可,
在这里插入图片描述

2.4、基础色

对贴图进行采样,然后与描边色混合,最终输出到片元着色器的Base Color
在这里插入图片描述

2.5、完整节点图

最终完整的节点图如下,肯定看不清,只是给大家看下整体结构,想要看细节的同学可下载本文的工程源码进行查看,
在这里插入图片描述

2.6、粒子的节点图

粒子的ShaderGraph比较简单,主要控制在粒子系统的参数本身,Shader Graph节点图如下,
在这里插入图片描述

六、材质球设置

本文的角色的材质球分了多个,比如头发、衣服、表情等,
在这里插入图片描述
我们分别给每个材质球设置对应的shader,设置贴图等,
在这里插入图片描述
因为消融的时候要统一控制disolve属性,下文我们就是用C#代码来对齐进行统一控制好了。

七、粒子系统设置

效果二需要一个粒子效果,贴图我自己画了一个,作为灰烬的贴图,如下
在这里插入图片描述
粒子的设置关键的一步就是设置Shape,是用角色的网格作为Mesh,如下,
在这里插入图片描述
这样粒子喷射的时候就是以网格的形状来喷射了,
请添加图片描述
还有就是粒子的噪声扰动,可以对粒子运动轨迹、旋转、大小进行扰动,
在这里插入图片描述
另外是一些生命周期内的属性控制,比如作用力、颜色、大小等,
在这里插入图片描述
关于粒子系统的教程,我之前写过几篇文章,感兴趣的同学可以看下:
《【游戏开发实战】Unity使用ParticleSystem粒子系统模拟药水在血管中流动(粒子碰撞)》
《【游戏开发实战】手把手教你使用Unity制作一个飞机喷射火焰尾气的粒子效果》
《【学Unity的猫】第十五章:Unity粒子系统ParticleSystem,下雪啦下雪啦》
《【游戏开发实战】Unity使用ShaderGraph配合粒子系统,制作子弹拖尾特效(Fate/stay night金闪闪的大招效果)》
《【游戏开发实战】Unity ShaderGraph溶解效果运用到粒子系统中(利用顶点色的alpha通道控制)》
《【游戏开发实战】权游红袍女在火中看到了什么,我看到了…(Unity | 粒子系统 | 火焰特效 | ParticleSystem | 手把手制作)》

八、C#代码控制材质球属性

我们做一下简单的UI界面,弄一个Slider滑块,如下,
在这里插入图片描述
创建一个PlayerMaterialCtrler.cs脚本,用于控制角色材质球属性,
代码很简单,如下

using UnityEngine;
using UnityEngine.UI;

public class PlayerMaterialCtrler : MonoBehaviour
{
    
    
    [SerializeField]
    private Slider disolveSlider;
    private Material[] materials;
    private int disolveId;

    void Start()
    {
    
    
        var renderer = gameObject.GetComponentInChildren<Renderer>();
        materials = renderer.materials;
        disolveId = Shader.PropertyToID("disolve");
        disolveSlider.onValueChanged.AddListener((v) =>
        {
    
    
            for (int i = 0, len = materials.Length; i < len; ++i)
            {
    
    
                materials[i].SetFloat(disolveId, v);
            }
        });
    }
}

我们再创建一个ParticleSystem.cs脚本,用于控制粒子的喷射,代码如下,

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class ParticleCtrler : MonoBehaviour
{
    
    
    [SerializeField]
    private Slider slider;

    [SerializeField]
    private ParticleSystem ptc;

    void Start()
    {
    
    
        var emission = ptc.emission;
        var ptcMain = ptc.main;
        emission.rateOverTime = 0;
        slider.onValueChanged.AddListener((v) =>
        {
    
    
            if (v > 0.7f)
            {
    
    
                emission.rateOverTime = 0;
            }
            else if (v < 0.35f)
            {
    
    
                emission.rateOverTime = (int)(v * 1000);
                ptcMain.startSize = 0.07f * v;
            }
            else
            {
    
    
                emission.rateOverTime = (int)((0.7f - v) * 2000);
                ptcMain.startSize = 0.07f * v;
            }
        });
    }
}

PlayerMaterialCtrler.cs脚本挂到角色根节点上,并赋值Slider对象,
在这里插入图片描述
SparkParticle.cs脚本挂到粒子节点上,并赋值成员对象,如下
在这里插入图片描述

九、最终运行效果

运行Unity,最终效果如下,
请添加图片描述

十、工程源码

本文工程源码我已上传到GitCode,感兴趣的同学可自行下载学习。
地址:https://codechina.csdn.net/linxinfa/UnityDissolveAshEffect
注意:我使用的Unity版本是2021.1.7f1c1,使用的ShaderGraph版本是11.0.0,如果你使用的版本与我不同,可能会有兼容问题。
在这里插入图片描述

十一、完毕

好啦,就到这里吧~
我是林新发:https://blog.csdn.net/linxinfa
原创不易,若转载请注明出处,感谢大家~
喜欢我的可以点赞、关注、收藏,如果有什么技术上的疑问,欢迎留言或私信~

猜你喜欢

转载自blog.csdn.net/linxinfa/article/details/121932326