PivotPainter2反向解析
PivotPainter2反向解析

PivotPainter2反向解析

反向解析PivotPainter2

轴点动画的核心就一个

image.png

绕轴旋转。

所以我们要准备好需要的数据。

  • 需要绕哪个轴旋转?
  • 旋转的角度?
  • 轴点在哪个位置?
  • 当前顶点位置

最基础的绕轴旋转是这样的:

image.png

image.png

%E5%8A%A8%E7%94%BB.gif

所以回到PivotPainter,就是得到这几个数据。

需要绕哪个旋转轴?

旋转轴向(RotationAxis)数据主要是通过风向数据来控制主要方向,外加一个噪声做一些角度偏移。

旋转轴向为风向与当前轴点轴向的叉乘。

image.png

这里大家可能有点疑问为什么 风向要加上一个 (0,0,-0.2)*pow(dot(XAxis,WindDirectionXAxis),5)

其实这是模拟风与轴向完全水平的状况下,让风向稍微往下吹模拟植物收到重力被风吹的点头的效果。
外加一个扰动的噪声轴向

image.png

旋转的角度大小?

旋转的角度由好几个因素影响

  • 风力图的影响
  • 父物体旋转
  • 风向与轴向的角度(可选)
  • 当前点在轴向上与轴点的距离,占这个轴向总长度的多少。(相当与离根部越近,偏移越小)

image.png

轴点位置?

当前顶点的轴点位置烘焙到贴图(Pos&ID Tex)中,通过UV1直接采用即可获得

image.png

数据准备

现在知道旋转所需要的各个参数怎么得到的。刚好说到顶点的轴点位置烘焙在贴图(Pos&ID Tex)中,那么我们需要准备的数据共有哪些呢?分别有什么用处?

需要准备的数据一共有:

  • 轴点位置与ID贴图(RGB::Pos & A::ID)Tex
  • 轴向方向与轴长度贴图(RGB::XAxis & A::XExtent)Tex
  • 树Mesh UV1对应数据贴图采样。

这只是推荐数据格式,实际想怎么编码数据和用UV(N)采样都行。

这里比较重要的是ID数据,这关系到物体的层级结构,UE里面写的很绕。

ID数据主要是为了我们重构层级关系。

层级关系重构

通过贴图解析父级UV

在数据编码阶段,ID或者说Index 代表自身父物体在贴图中的位置。如果没有上一级父物体了那么ID就是自身ID(Current Id = Parent Id)

image.png

当前UV转换为当前Id

当前UV采样(Pos&ID)贴图,得到父物体Id,父物体Id转换得到父物体UV,并且通过判断(Current Id = Parent Id)来确定自身还有没有上一级(IsChild=0 or 1)。

因为最多UE最多支持的层级只有4级,重复寻找父物体操作三次即可。

image.png

因为输入UV的类型情况总共只有4种:主干、主分支、次分支、叶子

所以我们直接把每种情况对应的结果都展现出来

当输入为主干Mesh:

Level1UVs为主干UV、Level1Index为主干Index,因为主干上面没有父物体了,父物体Index就等于自身,所以

  • Level1Index=主干Index,Level1UV=主干UV
  • Level2Index=主干Index,Level2UV=主干UV,Level2Child=0;
  • Level3Index=主干Index,Level3UV=主干UV,Level3Child=0;
  • Level4Index=主干Index,Level4UV=主干UV,Level4Child=0;

当输入为主分支Mesh:

Level1UVs为主分支UV、Level1Index为主分支Index,主分支有一级父物体

  • Level1Index=主分支Index,Level1UV=主分支UV
  • Level2Index=主干Index,Level2UV=主干UV,Level2Child=1;
  • Level3Index=主干Index,Level3UV=主干UV,Level3Child=0;
  • Level4Index=主干Index,Level4UV=主干UV,Level4Child=0;

当输入为次分支Mesh:

Level1UVs为次分支UV、Level1Index为次分支Index,主分支有两级父物体

  • Level1Index=次分支Index,Level1UV=次分支UV
  • Level2Index=主分支Index,Level2UV=主分支UV,Level2Child=1;
  • Level3Index=主干Index,Level3UV=主干UV,Level3Child=1;
  • Level4Index=主干Index,Level4UV=主干UV,Level4Child=0;

当输入为树叶Mesh:

Level1UVs为次分支UV、Level1Index为次分支Index,主分支有两级父物体

  • Level1Index=树叶Index,Level1UV=树叶UV
  • Level2Index=次分支Index,Level2UV=次分支UV,Level2Child=1;
  • Level3Index=主分支Index,Level3UV=主分支UV,Level3Child=1;
  • Level4Index=主干Index,Level4UV=主干UV,Level4Child=1;

确认当前层级以及分配层级数据

通过判断Level2Child、Level3Child、Level4Child的总和(LevelDepth),我们就可以轻松的知道当前顶点处于哪一级层级。

image.png

这段逻辑便是通过当前LevelDepth来确定,当前层级需要运算哪些Level(LevelMask为0不运算),以及对应Level对应的UV。

Lerp_Multiple_Float2函数逻辑:

image.png

结合上面的通过贴图解析父级UV可得:

当输入为主干Mesh:

因为是主干Mesh,所以可以得知LevelDepth为0,那么

  • Level1PivotUVs=Level1UV ;Level1UV=主干UV
  • Level2PivotUVs=Level1UV,Level2Mask=0;
  • Level3PivotUVs=Level1UV,Level3Mask=0;
  • Level4PivotUVs=Level1UV,Level4Mask=0;

当输入为主分支Mesh:

LevelDepth为1

  • Level1PivotUVs=Level2UV;Level2UV=主干UV
  • Level2PivotUVs=Level1UV,Level2Mask=1;Level1UV=主分支UV
  • Level3PivotUVs=Level1UV,Level3Mask=0;
  • Level4PivotUVs=Level1UV,Level4Mask=0;

当输入为次分支Mesh:

LevelDepth为2

  • Level1PivotUVs=Level3UV;Level3UV=主干UV
  • Level2PivotUVs=Level2UV,Level2Mask=1;Level2UV=主分支UV
  • Level3PivotUVs=Level1UV,Level3Mask=1;Level1UV=次分支UV
  • Level4PivotUVs=Level1UV,Level4Mask=0;

当输入为树叶Mesh:

LevelDepth为3

  • Level1PivotUVs=Level4UV;Level4UV=主干UV
  • Level2PivotUVs=Level3UV,Level2Mask=1;Level3UV=主分支UV
  • Level3PivotUVs=Level2UV,Level3Mask=1;Level2UV=次分支UV
  • Level4PivotUVs=Level1UV,Level4Mask=1;Level1UV=树叶UV

这块逻辑挺绕的,前面是反着来,经过这步后就是正的顺序拉。

然后每个Level放入前面的绕轴旋转逻辑代码里面即可

image.png

image.png

image.png

image.png

这个MF_Ghis_PivotPainter2_Animation_SingleLevel里面最终要做的就是一开始说的绕轴旋转。

image.png

注意法线也需要绕轴旋转,只不过法线的的轴点为000而已,如果对应的LayerMask=0的话就不做任何操作。

image.png

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注