Unity ShaderGraph实现模型消融为灰烬飘散效果
Unity ShaderGraph实现模型消融为灰烬飘散效果
本文将详细介绍如何在Unity中使用ShaderGraph实现模型消融效果。通过两种不同的实现方案,结合粒子系统和C#代码控制,可以制作出逼真的模型消融为灰烬飘散的效果。
一、前言
有小伙伴在提问区提出了想要制作一个模型消融化作灰烬飘散的效果的需求。虽然之前已经写过一篇关于ShaderGraph的教程,但没有实现灰烬飘散的效果。今天,我们就尝试使用ShaderGraph来实现这个效果。
本文将实现两种效果:
- 效果一:使用Alpha Clip对模型进行裁切,切口处添加随机噪声控制Alpha Clip,并使用随机噪声对消融的顶点做坐标扰动,最后混合一个颜色。
- 效果二:在效果一的基础上,添加粒子效果,粒子的喷射Shape使用角色的网格,粒子加一些噪声扰动,达到风吹的效果。
二、ShaderGraph环境准备
因为本文使用的是Unity的ShaderGraph来实现上面的效果,需要先安装ShaderGraph相关插件,并做一些基础设置。可以查看之前关于ShaderGraph使用教程的博客,这里就不赘述具体操作了。
三、模型准备:原神角色模型
本文使用的是原神的角色模型。如果对如何从原神官网下载角色模型并制作成FBX格式导入Unity感兴趣,可以参考之前的相关教程。
四、实现思路
在讲具体操作之前,先说一下实现思路。
1. 效果一的实现思路
- 思路:使用Alpha Clip对模型进行裁切,切口处做一层随机噪声来控制Alpha Clip,并使用随机噪声对消融的顶点做坐标扰动,最后混合一个颜色即可。
2. 效果二的实现思路
- 思路:依然是使用Alpha Clip对模型进行消融控制,在此基础上,再添加一个粒子效果,粒子的喷射Shape使用角色的网格,粒子加一些噪声扰动,达到风吹的效果,再根据滑块的值分别控制消融进度和粒子的喷射属性即可。
五、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 AlphaClip控制
把噪声与滑块值相加,再与定点坐标的y分量做一个Step阶跃,得到颗粒感的边界,最后反一下,作为AlphaClip的输入。
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.3 计算AlphaClip
创建一个float节点,作为滑块,与刚刚的噪声做一个阶跃,输出结果作为AlphaClip,片元着色器的Alpha设置为0.5。
2.4 计算描边
滑块与噪声做一个阶跃,再与刚刚计算的AlphaClip相减,就可以得到噪声的描边了,再混合一个颜色即可。
2.5 基础色
对贴图进行采样,然后与描边色混合,最终输出到片元着色器的Base Color。
2.6 粒子的节点图
粒子的ShaderGraph比较简单,主要控制在粒子系统的参数本身,节点图如下:
六、材质球设置
角色的材质球分了多个,比如头发、衣服、表情等,分别给每个材质球设置对应的shader,设置贴图等。因为消融的时候要统一控制disolve属性,下文就是用C#代码来对齐进行统一控制。
七、粒子系统设置
效果二需要一个粒子效果,贴图作为灰烬的贴图。粒子的设置关键的一步就是设置Shape,是用角色的网格作为Mesh,这样粒子喷射的时候就是以网格的形状来喷射了,还有就是粒子的噪声扰动,可以对粒子运动轨迹、旋转、大小进行扰动。
另外是一些生命周期内的属性控制,比如作用力、颜色、大小等。
八、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;
}
});
}
}
九、最终运行效果
运行Unity,最终效果如下:
十、工程源码
本文工程源码已上传到GitCode,感兴趣的同学可自行下载学习。
地址:https://gitcode.net/linxinfa/UnityDissolveAshEffect
注意:使用的Unity版本是2021.1.7f1c1,使用的ShaderGraph版本是11.0.0,如果使用的版本不同,可能会有兼容问题。
十一、完毕
希望这篇文章能帮助大家掌握在Unity中实现模型消融效果的技术。如果在技术上有任何疑问,欢迎留言或私信交流。