Amplify Shader Editor 案例解析系列——(4)ForceShield

前言

该篇分析第四个案例,ForceShield。

正文

由于该案例中shader使用了大量的局部变量,按照效果分析时,会有变量还“未定义”,不知道其含义的情况存在,从而导致过于杂乱,所以这个案例我们按照Comment从左上顺序开始分析,分析各个变量的输出意义。不过首先我们看一下该案例的效果。

 发现效果有以下几处:

1.球体表面在不规则的像水波纹一样在浮动

2.球体表面的六边形在缓缓向下平移

3.球体与立方体相交的位置,显示不同,如被切开

4.图2中,被子弹击中的位置,呈现白色

然后我们分析Comment:

1.Animation Speed Comment

 输出Time parameters节点,与一个常量相乘,结果注册为一个变量ShieldSpeed,其中Time parameters输出的思维向量,值分别为(t/20, t, t*2, t*3),即节点下面的时间值的不同倍率。

记录当前comment输出的变量:

       a.  ShieldSpeed,意义为时间节点与常量相乘。

2.Shield Main Pattern Comment

 注册属性Shield Pattern Color值到变量ShieldPatternColor,注册属性Shield Pattern Power值到变量ShieldPower。将属性Shield Pattern Size的输出通过Append节点,合并成一个二维向量Vec1,将常量vector 0 (1,0)的X通道输出,即1 ,然后与变量ShieldSpeed的输出通过Append节点合并成一个二维向量Vec2,ShieldSpeed是一个四维向量,但是这里Append已经设定为二维向量,同时X已经有输入,所以将ShieldSpeed值输出到Append节点Y值时,只取ShieldSpeed 第一个通道,即X通道的值。这里将Vec1输入到Texture Coordinates的Tilling,将Vec2输入到Offest,然后将UV输出作为贴图Shield Pattern的UV值,注册贴图输出结果ShieldPattern。Texture Coordinates节点的Tilling值为贴图XY方向的缩放比,意义为在XY方向,分别对贴图缩放XY倍,初始值为1,即缩放值为1,Offest值为贴图的UV偏移,即将贴图沿U/V方向偏移值X/Y,这里Vec2的X值为常量1,即该贴图U方向偏移1,Y值跟随时间变化,即V方向在一直偏移,实现贴图滚动效果,如果需要贴图循环出现的话,那么贴图的Wrap Mode要设置为Repeat,当Wrap Mode 为Clamp时会剪裁掉多余的信息,具体效果可以实验观察。总结该模块的意义,将贴图Shield Pattern进行缩放与偏移操作,实现贴图滚动后,注册给变量ShieldPattern。

记录当前Comment输出的变量:

       a.  ShieldPatternColor,意义为属性Shield Pattern Color值

       b.  ShieldPower,意义为属性Shield Pattern Power值

       c.  ShieldPattern,意义为贴图Shield Pattern进行UV变换(缩放,偏移)后的结果

3.Shield Wave Effect Comment

 这个与2中流程基本相同,变量ShieldSpeed除以常量Float 0进行缩放之后,再对X通道进行One Minus操作之后,再进行合并输出,实现贴图Shield Pattern Waves的UV变换,将变换结果注册到变量waves,不再赘述。

记录当前Comment输出的变量:

       a.  waves,意义为贴图Shield Pattern Waves进行UV变换(缩放,偏移)后的结果

4.Shield RIM Comment

 注册属性Shield Rim Power值到变量ShieldRimPower,将变量ShieldRimPower值,进行Remap(值依次为0,10,10,0)操作,然后输出到Fresnel节点的Power入口,将Fresnel节点的输出注册到变量ShieldRim。这里Remap的节点,根据案例1的解析文章中的公式,我们可以推算出Out = 10 - In(所以搞个Remap这么麻烦也不晓得是为什么,毕竟Remap的值也是常量定义的...),Fresnel节点,是Amplify Shader Editor已经封装好的一个菲涅耳外发光节点,将该节点直接输出到Shader的Emission节点,就可以看到物体表面的外发光效果(可以自行实验),Power值控制了外发光的强度(其他值没有研究,感兴趣的可以看研究下)。

记录下当前Comment输出的变量:

       a.  ShieldRim,意义为物体表面的菲涅耳外发光效果

5.Impact Effect Comment

吐槽一下.真够乱的~ 

注册属性Hit Size值到变量HitSize(可以理解为碰撞后显示特效的范围),注册属性Hit Color值到变量HitColor。Vertex Position为顶点位置,Distance节点意义为计算两个输入的点之间的距离,这里即计算输出对象各个顶点到Hit Position点的距离(Hit Position点是代码中赋值的,为碰撞点,后面有分析),我们记Distance节点输出为Dis1,那么当对象的某个顶点位置距离Hit Position越近时,Dis1值越小(但不小于0),反之越大,  Dis1有两个输出,首先分析下面的输出,Divide节点,用变量HitSize去除以Dis1(被除数不变,除数越大,商越小),然后与Hit Color相乘,根据Dis1值的意义,我们可以得到,当顶点距离Hit Position越近时,Dis1越小,商越大,Multiply对Hit Color的各个通道缩放值越大,反之距离越远,缩放值越小,这里就实现了上述效果4中,被击中的位置,显示为白色(击中位置与Hit Position的转换在代码中),这里结果为白色,并不完全是因为Hit Color值为白色,后面再进行分析,Multiply结果记作Mul1,Mul1作为Lerp节点的B,而Lerp节点的A输入的是变量ShieldPatternColor,Lerp节点的Alpha为Hit Time(击中后特效的剩余时间,代码中赋值,递减)Remap(参数依次为0,100,0,1)的结果,推算出Out = In / 100,此时Lerp节点的输出我们可以总结为随着Hit Time值的递减,输出结果越趋近于ShieldPatternColor,反之趋近于Mul1,记该Lerp结果为Lerp1。然后继续分析Dis1上面的输出,可以看到是输出到Compare(A < B)节点,该节点是比较节点,可以发现该Comment有两个这样的节点,区别是  “括号里 ” 不同的判断条件,节点有四个输入,A,B,True,False,节点意义为,当输入的AB,满足括号里的条件时,那么将该节点的Ture输入作为输出,反之将该节点的False输入作为输出。这里A输入为Dis1,B输入为Hit Size,True 为 Lerp1,False 为ShieldPatternColor,那么该节点的意义为,当Dis1 < Hit Size时, 输出Lerp1,否则输出ShieldPatternColor,转化成白话文,即在顶点距离碰撞点小于HitSize的范围内输出Lerp1,范围外则输出ShieldPatternColor,然后将该结果输出到下一个Compare(B 输入为常量0) 节点的True ,分析这个Compare可得,当Hit Time > 0 时,即在碰撞特效有效时间内, 输出碰撞特效,超过该时间后不输出碰撞特效,输出结果注册为变量hit。

该Comment看起来节点很多,但是都是些基础节点,一个个看,很容易就能理通其中的逻辑。

一定要注意!!!

这里的输出变量hit,不能理解为颜色值,而应作为一个四维向量看待,因为该Comment没有对hit值进行Clamp或者Remap操作进行限制范围,所以hit的各个通道值范围不在是0~1,举个例子,假设Dis1足够小,Hit Size不为0,那么Divide结果就足够大,同时若HitColor各个通道值又不为0.那么Multiply结果,就是各个通道值足够大,试问给0.0001乘以一亿之后,值还小吗?这个是必须要理清楚的,不然会阻碍对下文的变量结果混合的理解。

记录下当前Comment输出的变量:

        a.  HitSize,意义为属性Hit Size值,碰撞特效的范围

        b.  HitColor,意义为属性Hit Color值,碰撞特效的颜色

        c.  hit,意义为当特效时间Hit Time 大于0,且顶点距离碰撞点Hit Position 小于特效范围Hit Size的地方,用不同的缩放值对Hit Color各个通道进行缩放,随着距离的缩小,缩放值越大,范围外,或Hit Time不大于0时,则输出ShieldPatternColor值。

6.Shield Distortion Comment

 变量ShieldSpeed除以常量Float 1 (即将时间节点进行缩放)之后与Vertex Normal节点的输出通过Add节点相加,输出到Noise Gnerator节点。其中Vertex Normal节点意义为顶点的法线,对法线的Add操作,即对法线进行变向,根据ShieldSpeed的值,我们可以知道在z方向Add值最大,y方向次之,x方向最小。Noise Gnerator节点是对输入的参数进行噪音处理,返回 -1 ~ 1 内的值,含-1,1,需要注意的是,该节点中,相同的输入必定得到相同的输出,由于这里要使用三维效果,所以Type选择Simplex3D,将结果进行Remap(参数依次为0,1),再注册为变量VertexOffset,这里可以看到Remap的Min New与Max New分别为Shield Distortion 值multiply(B参数为-1)结果和Shield Distortion值,而Shield Distortion取值范围为0~0.03,即这里Remap的意义为缩小噪音处理后的值。

记录下当前Comment输出的变量:

        a.  VertexOffset,意义为先将顶点法线变向,再进行噪音处理与缩小范围,同时该值随着时间不断变化

7.Shield Mix for Emission Comment

 将变量ShieldRim与变量ShieldPattern进行Add操作,结果变量意义可得这一步意义为给外发光加上流动的纹理,可在shader中给贴图节点选择对应贴图,然后打开预览按钮进行结果预览,这里由于图片尺寸受限就没有打开预览结果。Add结果与变量waves进行Multiply操作,即把处理后的外发光与waves中流动的纹理进行混合,记结果为Mul1。至于这里为什么第一个混合为Add,第二个为Multiply,在4中,我们可以看到Fresnel节点,外发光中心为黑色,值为0,趋于外圈方向,值趋近于1,如果对变量ShieldRim与变量ShieldPattern进行Multiply操作,根据黑色*任意颜色 = 黑色 ,白色 * 任意颜色 = 任意颜色,那么结果中,首先中心区域为黑色,纹理消失,外圈区域颜色为纹理颜色,外发光效果就不再存在,第二个Multiply为常用的明暗变换处理方式,将贴图Multiply一张目标贴图,实现目标贴图黑色区域,显示为黑色,白色区域显示为原贴图纹理,由于该shader中waves的流动速度过慢,效果不明显,可以修改Shield Wave Effect Comment的Float 0常量值,越趋近于0,流动效果越明显,负数则反向流动。

下面将变量hit与变量ShieldPatternColor进行Multiply操作,这里单独讲解,一定要注意,假如我们把hit的输出作为颜色理解,那么我们得到的结果是碰撞时间内,距离范围内,显示为碰撞色Hit Color,这里为白色,反之显示为ShieldPatternColor,然后Multiply,根据 白 * 任意 = 任意,那么可得,在碰撞范围内,应该显示为ShieldPatternColor,但是实际效果显示的为白色,所以为什么会显示白色呢?结合 5 中讲解的注意点,我们不能把hit的输出值作为颜色理解,而是一个四维向量,这个很容易搞混,所以一定要理清楚。那么再来分析,在碰撞范围内,距离足够近,那么hit 对应点的值就越大,然后将hit与ShieldPatternColor进行Multiply之后,得到的值就越大,举例,假如ShieldPatternColor值为(0.1,0.1,0.1),那么只要hit值大于(10,10,10),Multiply结果就大于(1,1,1),即显示为白色,而范围外的值为ShieldPatternColor各个通道取平方,所以这里的白色不是因为Hit Color为白色,而是距离足够近,导致各通道缩放值足够大,才得出白色,这里可以把Hit Color更换为其他颜色, 会发现,在碰撞中心,总是显示为白色,但是测试的时候需要注意的是,Hit Color的通道值不能为0,因为对0,无论缩放多少倍都是0。测试时可能会发现,当把Hit Color的各个通道值修改到足够小时(比如1/255),是不显示白色的,那是因为模型的顶点数有限,顶点间距离有一定的范围,所以导致缩放值不够大,Multiply之后也就得不到结果为1的输出,此时可以假象一下,假如我们在模型两个顶点之间又加了足够多的顶点,那么顶点间的距离就会足够小,从而使缩放值足够大,那么必定会显示白色。将该Multiply结果记作Mul2。

Mul2 与 Mul1 进行 Multiply操作,即给Mul2添加流动的有明暗纹理,且有外发光的效果,记该Multiply结果为Mul3。Mul3作为后面Lerp节点的B,A为一个属性颜色值Intersect Color,重点在Alpha。Depth Fade节点常用于两个对象相交处的过渡特效,意义为输出物体表面与其相交的对象的距离,然后在Distance输入范围内,根据距离进行渐变,举个例子,假如一个球与一个立方体相交,Distance输入为0.1,那么在圆与立方体相交处,范围0.1内,输出距离的渐变值,相交点距离即为0,离相交点越近,距离越小,输出值越小。该节点有三个控制参数,Convert to Linear:将从深度缓冲区读取的深度值从对数刻度转换为线性刻度;Mirror:将结果取绝对值,保证非负;Saturate:结果限制在0~1之间,相当于Clamp(0,1)。使用该节点时,必须注意的是,Render Queue 必须设置为 Transparent  或者更大的值,Blend Mode 必须设置为Transparent or Translucent 。这里将结果Clamp(0,1)之后,输入到Lerp的Alpha,结合实际意义,即与其他物体相交时,距离相交越近的位置,结果越趋近于Intersect Color,越远则越趋近于Mul3,而过渡范围为属性Intersect Intensity,将结果缩放ShieldPower倍后,注册到变量Emission,后面看到是最终的外发光效果。

记录下当前Comment输出的变量:

        a.  Emission,意义为外发光效果,当与物体相交时,从相交点向外,效果从纯色Intersect Color趋近于带有明暗,流动,网状效果的纹理,即上面定义的Mul3

8.Textures Comment

略,这里没有用到。

9.最终结果输入

 Albedo,Normal略,Emission即外发光,将Shield Mix for Emission Comment的输出作为物体的外发光效果。Opacity为透明度。Local Vertex Offest ,顶点的偏移,输入变量为VertexOffest,结合其意义,即顶点沿着法线变向后的方向偏移,假如我们有没有对法线进行变向的话,那么沿法线方向的偏移其实就是放大或者缩小,而变向后不规则,所以产生了效果1,顶点进行不规则的浮动。

10.碰撞点与碰撞时间代码

 首先看碰撞监听事件OnCollisionEnter,产生碰撞时,遍历碰撞点,然后进行坐标转换后,通过SetVector传递给材质,那么参数名“_HitPosition”是哪里来的呢?在ase编辑器,选中一个属性,属性栏Property Name值即表示该属性在shader中的参数名,可以在代码中进行修改,Name只是Inspector视图显示用,如图:

该案例较复杂,文档解析起来比较受限,一步步去看的话,并不难。 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值