找回密码
 立即注册
查看: 429|回复: 0

简单溶解效果ASE实现

[复制链接]
发表于 2021-12-16 13:18 | 显示全部楼层 |阅读模式
简单溶解效果ASE实现

提要:使用溶解纹理制作透明度遮罩,并使用One Minus节点实现遮罩翻转和叠加;最终使用世界位置坐标修正遮罩,实现方向渐次溶解。




目录


  • 着色器部分
  • 编写准备

    • Unity安装
    • ASE插件安装
    • 工程文件创建

  • 着色器设置
  • Albedo&Normal(反射和法线部分)
  • Opacity & Opacity Mask(透明度遮罩和渐变部分)

    • Opacity(透明度原始遮罩)
    • Opacity Mask(透明度渐变遮罩)


  • Emission(自发光部分)

    • 溶解自发光

<hr/>着色器部分

着色器部分包括了主要的透明度遮罩和渐变效果。这里主要使用ASE实现,重在讲解思路,降低学习成本。
编写准备

开始正式编写之前,我们需要首先完成基本开发环境的部署。无需从头开始的小伙伴可以直接越过这部分内容,从工程文件创建开始浏览。
Unity安装

从Unity官方网站上下载Unity Hub并按照自己需求安装一个版本。推荐安装不低于2018的任一LTS版本,就本工程来说,社区版本也是完全足够的。
具体步骤较为简单,网络上教程也比较丰富,这里就不做进一步展开。
ASE插件安装

如前所说,我们需要安装ASE插件来创建ASE着色器,以获得图形界面支持。Unity的Asset Store里面上架了ASE插件,可以直接从里面获取。与通常Package的下载相同,点击Download并下载完成后,点击Import自动导入即可。
如果是从非Asset Store途径获取的ASE,双击ASE.unitypackage即可在安装了Unity的前提下自动导入插件。
ASE插件安装完成后会弹出ASE初始化界面,关闭即可。
工程文件创建

与创建普通着色器类似,我们依然是在Asset界面使用右键菜单创建ASE Shader,ASE插件通过编辑器脚本为我们在右键菜单中添加了额外的选项:



选择Surface来以表面着色器为模板,来创建一个ASE Shader。
创建完毕后将文件名改为ASE_Dissolve(或者是你喜欢的其他名字),我们就完成了工程的准备工作,可以开始正式编写着色器了。
着色器设置

创建着色器后,我们需要对着色器进行进一步的设置。
在着色器设置中,选择Blend Mode(渲染模式):



首先,将Blend Mode(渲染模式)设为Masked(遮罩的);
然后,打开Blend Mode(渲染模式)的下拉菜单:
   将Render Type(渲染类型)设为Transparent Cutout(透明镂空);
   将Render Queue(渲染队列)设为Alpha Test(透明度测试);
   将Mask Clip Value(遮罩裁剪参数)设为0.5。
裁剪参数可以根据自己的需要进行调节,这里提供的仅是一个参考值。
Albedo&Normal(反射和法线部分)

对于Albedo和Normal,我们不做过多处理,简单地留出接口并输入shader即可。如果有需要,可以自行改写。



Opacity & Opacity Mask(透明度遮罩和渐变部分)

在这一部分,我们将为溶解效果制作最基本的透明度遮罩,并为其赋予基于顶点物体/世界位置的渐变。
Opacity(透明度原始遮罩)

我们首先创建一个Sampler2D(在ASE中被归入Texture Sample),用于接收输入的溶解遮罩原始图案。



然后,我们需要引入参数对其进行控制。创建一个浮点参数,命名为Dissolve Amount,取值范围设置为[0,1]。



我们使用一个Add节点将两者叠加,输出到命名为Opacity的本地变量中。



这个参数为遮罩图增加了一个统一的值,就好像潮水漫过高低起伏的山谷,随着涨潮(参数增加),整个地区(采样)的等高线开始收缩,直到所有点高度与最高点(1)齐平;而落潮(参数减少)时则逐渐由高到低露出被淹没的地形。
读者可以自行修改参数的取值范围,观察不同取值范围变化对最终输出遮罩图的影响。事实上,负值范围正好是正值的取反,参数绝对值增加时,整个采样的非0值开始向0靠拢,表现为黑色区域的扩散;反之则是收缩。
如果读者尝试过更换溶解采样纹理,会发现同样的采样范围在不同的采样纹理下,表现也不尽相同。这是由于不同纹理图的直方图分布不同,固定且斜率均匀的参数区间并不能很好的贴合所导致的。



相对理想的分布



相对集中的分布



相对离散的分布

我们当然可以每一次更换纹理图时都先打开PS查看灰阶直方图,然后再打开ASE面板花时间反复测试,调整好对应的取值范围;但出于易用性和便捷性考虑,我们将参数进行拆分,使我们能方便地对单项表现进行微调。
重新将Dissolve Amount的取值范围调整为[0,1],我们希望将这个参数抽象为溶解程度的百分比,并尽可能符合直观印象:当参数取0时,物体应当正好完好无缺;当参数取1时,物体应当正好完全溶解。
为了达成这一目标,我们引入第二个浮点参数Power,并使用Multiply节点接收这两个参数的输入;Power将决定我们参数的斜率,从而间接控制我们的参数所覆盖的范围,以便通过对Power的调整确保参数范围正好完全覆盖纹理的灰阶直方图分布。



此外,由于我们的Opacity事实上是透明度遮罩,因此如果想要达到我们上面所提到的效果,那么我们实际上应当对获得的参数进行取反。引入One Minus节点,并对Multiply的结果进行处理。



One Minus
One Minus 节点将输入值输出为 1-输入值的结果。颜色和UV坐标常用One Minus节点进行反转操作。


值得注意的是,One Minus 节点在处理多通道值时,是逐通道执行One Minus操作,而非整体处理。
最后,我们需要对参数进行Remap(重映射)处理,以便符合RGBA通道[0,1]的取值范围。由于我们的参数模型是一条均匀的直线,因此我们在Remap的新旧区间上不做额外处理,相当于直接截取了这条直线的[0,1]部分。将输出导入之前的Add节点即可。
Remap
重映射节点将输入值由[Min Old,Max Old]区间重映射至[Min New,Max New]。


参数在未连接输入时将可视化显示。
如果一切顺利,读者应当能通过对Power的简单调整,使Dissolve Amount能够完整输出物体从完好到完全溶解的整个过程中的透明度遮罩。



将Opacity直接连接到Shader的Opacity接口,调整Dissolve Amount,读者应当能看到整个材质从溶解开始到完全溶解的整个过程。
Opacity Mask(透明度渐变遮罩)

在Opacity部分中,我们完成了基本的透明度遮罩部分。接下来我们要为透明度遮罩增加渐变部分,以实现带方向的溶解效果。
前面我们将透明度纹理图比喻为潮水面前的山丘,我们这里的工作则是为这个山丘叠加一个额外的高度,使溶解效果能够以特定的方向渐变。



首先,注册一个新的本地变量,并命名为Opacity Mask。
然后,我们引入World Position节点,并使用Remap节点将位置信息处理为符合纹理参数要求的值,并将输出的值与前面得到的Opacity相加,输出到Opacity Mask。



值得注意的是,这里取y值是为了直观地表现渐变叠加位置信息后出现的方向性渐变,而非唯一选择。读者可自行尝试切换为取X、Z值,观察遮罩的变化。同样地,将World Position改为Vertex Position也会改变遮罩最终的表现,使位置信息变化基于顶点坐标而不是纹理坐标。
将输出赋值给我们注册的本地变量Opacity Mask,并改为使用该变量的值输出到Opacity接口。
如果一切顺利,我们应该能看到溶解效果基于世界坐标发生渐变。
接下来,我们依样画葫芦,实现基于世界坐标的反向、双向溶解,并实现基于参数控制的方向切换。这里给出关键思路和最终结果,读者可以自行尝试思考如何实现。
提示:使用Compare节点的组合实现分歧条件,使用参数作为判断依据。





Emission(自发光部分)

在这一部分,我们将在我们前面得到的Opacity Mask(透明度遮罩)基础上制作自发光效果。
溶解自发光

绘制自发光遮罩的过程其实与地图等高线的绘制类似,我们使用衰减速率,遮罩透明极大、极小值来描述自发光遮罩的状态。
我们首先获取之前的Opacity Mask(透明度遮罩),并对其进行Remap(重映射)和Clamp(夹紧)处理。



Clamp
Clamp节点对输入值进行夹紧处理。

若输入值为矢量则对其各分量依次进行夹紧处理。

若各输入端口分量(通道)数不一致,则进行强制匹配转换以匹配分量最多的端口。
端口描述类型
Input待处理输入值。当Alpha=0时,Input值将被完全输出Float
Min小于该值的所有输入值都将输出该值Float
Max大于该值的所有输入值都将输出该值Float
这里Remap节点决定了Opacity Mask在用于Emission时的变形程度。
相对更窄的新区间会让Opacity Mask的灰阶更加陡峭,反之则更加平缓;
区间之间的位移则控制Opacity Mask整体的灰阶分布情况。
新旧区间可以根据工程的实际需要进行调整,这里由于我没有相关需求,故不做任何额外处理,原样输出。
接下来,为了更加多样的遮罩梯度变化,我们引入一张额外的纹理指导我们的自发光遮罩。
使用One Minus节点对遮罩进行取反,作为UV信息输入到Sampler2D之中,再与取反纹理进行叠加,使得遮罩的整体过渡更加平滑自然。



如果一切顺利,我们应该能够得到如上的输出。通过将输出赋值给Emission变量,我们就能将制作好的遮罩传输给Emission接口。
完成后,我们应该就能得到最终的效果。



读者同样可以尝试切换Dissolve Guide纹理,观察效果的改变。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-9 07:29 , Processed in 0.092356 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表