StarWink UV顶点动画制作详解
我们先来看最终效果
实现原理:
1.利用算法得到圆形差值的UV坐标(中间为0)去采样纹理,得到圆形扩散的循环纹理动画。
2.利用算法得到循环的圆形扩散遮罩,并作为顶点偏移遮罩控制顶点动画。
3.模型顶点UV做了同一块模型上的UV顶点坐标一致性的处理,使得同一块模型上的所有点偏移量一致。
此次制作使用ASE来做算法说明(代码不直观)。
算法实现:
1. 利用UV的取值范围映射到指定的取值范围,并求模(Remap和Length)
第一个算法是Remap方法:
将某个区间的取值范围([Min Old, Max Old])映射到指定区间范围([Min New, Max New])。
算法为:如要将Val从[a, b]映射到[A, B],则公式为 Val = A + Val * (B - A) / (b - a)
第二个算法是length方法,意思是求取向量模长。公式:Sqrt ( Dot ( Iput, Iput ) )。此处将
[-1, 1]的取值范围的二维坐标取模,因为中间点(0, 0)的模长为0,边界处模长为1,所以得到一个[0, 1]灰度渐变的圆(这里的渐变为线性的)。
2. 两向量间的距离,(Distance)
当B向量TimeSpeed = 0时,Distance如下图所示。
公式:Sqrt (dot ( ( B-A ), ( B-A ) ) ),即为两向量距离公式。
这里将公式拆开分析,此处为两个模长的点积,即标量点积(理论上是不成立的,但是unity在底层还是做了计算规则)。先来看下图:
0.6点积0.6 近似= 1
所以我猜测可能是将一维的值自动填充为了三维向量,三个分量都是一维的那个值。然后两个三维向量进行点乘。例举几个值,测试结果均吻合!下图是其中一个测试:
下图中的a是Length的值,即模长为1的圆,根据上面推测的算法,a和a点积并开方后,边界值为根号3,即约等于1.732,并做了减法验证,说明推测无误(但是从0到1.732是非线性渐变的),所以看起来黑色圆缩小了。
Sqrt为开根号运算。
当B向量TimeSpeed != 0时,Distance如下图所示为一个从Time*Speed 到(上限值X(此处X为1.732)TimeSpeed) 范围的取值。并且随着时间增长,整个区间的值也随着增长。
3.UV坐标值随着时间线性增长并实时采样贴图
(彩虹纹理图)
用Distance的值去采样彩虹纹理图,得到循环圆的彩虹纹理。
作为UV坐标的distance遮罩的(0, 0)点在中心,采样贴图颜色为彩虹纹理图的左下角(0, 0)点的颜色(橙色),所以最终中心点颜色为橙色,并随着坐标的增大,不断采样靠上的颜色,黄,绿,蓝,紫,红。当坐标超过1时,即循环从橙色开始采样。所以最终效果是一个循环的圆扩散动画。
4. Fract(取小数位)
如上面所分析,Distance的取值范围在[ TimeSpeed, X * TimeSpeed ],差值为2左右,这样就有了两个小数循环,如图Fract所示。由于从0.9999到0是突然跳转(因为1的小数位是0),所以有硬边,而0到1是渐变的。但是这里发现了个问题,那就是如果Distance上限为1.732,那取小数后就是0.732,不可能为上图Fract的样式,应该是下图这样的:
而我们用点乘开方的算法算出来正是上面的形状,请看:
所以我觉得Distance算法并不像官方所说的仅仅是Sqrt (dot ( ( B-A ), ( B-A ) ) ),应该还加了一个压缩到整数位的操作,这样取小数时才能取满。
所以我们使用Remap将取值范围从(0, 1.737)映射到(0, 2),如下图所,结果和Distance结果一致。
5.Step节点
Step节点具体算法是,如果B>A,则返回1(白色),如果B<=A,则返回0(黑色)。
将Fract的值做Step就得到了黑白遮罩,这个遮罩是为了最终影响顶点偏移(黑色不偏移,白色完全偏移,因为模型顶点UV做了同一块模型上的UV顶点坐标一致性的处理)而做的。
6. 构建顶点偏移量(Append)
将顶点坐标的每个分量分别做偏移处理,最后利用Append节点重新构建。最后和Step混合得到最终的顶点动画。
来源:CSDN
作者:0卡卡0
链接:https://blog.csdn.net/qq_42650859/article/details/103946235