文章目录
一、前言
嗨,大家好,我是新发。
有小伙伴在提问区给我提了这个问题,想要做一个模型消融化作灰烬飘散的效果,

我之前写过一篇ShaderGraph的教程:《ShaderGraph使用教程与各种特效案例》
里面实现了多种常见的特效效果,也包括消融的效果,不过没有实现灰烬飘散的效果,今天,我就尝试使用ShaderGraph来实现这个效果吧~
本文我实现了两种效果,最终如下:

话不多说,我们开始吧~
二、ShaderGraph环境准备
因为本文我使用的是Unity的ShaderGraph来实现上面的效果的,需要先安装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
这里我不考虑光照效果,所以创建Unlit的Shader,在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的输入,

需要注意Alpha与Alpha Clip的关系:当Alpha Clip的值比Alpha大的时候,像素颜色就会被丢弃,一般我会把Alpha设置为0.5,

1.6、边缘渐变色
把步骤1.3的输出拿过来,与一个颜色混合,再进行加强,得到一个边缘渐变色,

1.7、输出基础色
对贴图进行采样,与边缘渐变色混合,作为基础色输出到片元着色器的Base Color,

1.8、顶点坐标扰动
我想要消融的地方的顶点有一个坐标扰动的效果,我构造了一个坐标扰动的噪声,如下,这里的扰动规则可自行发挥,我是采用Simple Noise对x、y轴进行扰动,使用Gradient Noise对y轴进行扰动,

1.9、插值计算顶点坐标
我们把噪声与顶点坐标相加,再通过滑块控制线性插值,得到最终顶点坐标,输出给顶点着色器的Position,

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

2、效果二
2.1、创建Unlit Shader Graph
同理是先创建一个Unlit Shader Graph,双击打开。
2.2、双噪声叠加扰动
消融效果需要一个噪声,我这里采用了双噪声叠加的方式,分别对噪声一噪声二的UV的V分量做相反反向的偏移,最终混合出一个双噪声混合的效果,

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://gitcode.net/linxinfa/UnityDissolveAshEffect
注意:我使用的Unity版本是2021.1.7f1c1,使用的ShaderGraph版本是11.0.0,如果你使用的版本与我不同,可能会有兼容问题。

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

被折叠的 条评论
为什么被折叠?



