深度解析3D骨骼系统中骨骼运动对几何体顶点运动的影响

前文中,我已经总结了3D骨骼系统的底层运作原理。现在我将更进一步解析骨骼的运动对几何体顶点运动的影响。three.js实现骨骼控制的代码中引用了一个bindMatrix变量,这个bindMatrix在很多应用的场景下,我们都不用管它,因为在默认的情况下,bindMatrix等于初始化时与之对应SkinnedMesh的matrixWrold。但其实bindMatrix对骨骼运动与几何顶点运动的影响是比较大的。我们可以看下一段glsl代码:

export default /* glsl */`     
#ifdef USE_SKINNING
                     
  vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
                            
  vec4 skinned = vec4( 0.0 );
  skinned += boneMatX * skinVertex * skinWeight.x;
  skinned += boneMatY * skinVertex * skinWeight.y;
  skinned += boneMatZ * skinVertex * skinWeight.z;
  skinned += boneMatW * skinVertex * skinWeight.w;
                                                        
  transformed = ( bindMatrixInverse * skinned ).xyz;
                                                                               
#endif
`;

在对几何顶点应用骨骼转移矩阵的时候,这里首先把顶点通过bindMatrix矩阵来转移。要解释这样做对结果的影响,我需要借助以下图来表达:

其中蓝色是骨骼bone,红点是没有通过bindMatrix转移的点,绿点是通过bindMatrix转移后的点。我们假设bone, 做了一个相对自己所在的点的旋转运动,并转过了alpha个角度。那么,按照图示,此运动对红点所的影响向量为a,对绿点影响向量为b。注意了,这里判断bone对几何点的影响方式可以看成这样:1.首先把几何点看成与bone的本地坐标系的相对位置是固定不变的。2. 当bone坐标系发生移动后,几何点做相同的运动。这里的相同是指相对全局坐标系的相同运动。例如bone绕自己转了alpha个角度,那么相对于全局坐标系,bone是做了绕bone所在坐标点做了alpha角度的转动。很显然,a和b是不一样的,bindMatrix直接影响了骨骼运动对几何顶点的影响值。

3D骨骼系统中,对几何顶点的变化顺序如下:

  1. 将所有顶点按照bindMatrix的矩阵数据做变化。
  2. 接着,顶点数据按照每个骨骼在全局坐标系下相对初始化是的变化矩阵做相应的权值变化。
  3. 随后,顶点按照bindMatrixInverse数据做变化。
  4. 最后顶点按照其自身SkinnedMesh的matrixWorld做变化

这里,需要特别注意的是,bindMatrixInverse不一定就是bindMatrix的逆。它由SkinnedMesh的bindMode来控制。bindMode为'attached'的时候,bindMatrixInverse是matrixWorld的逆,bindMode为'detached'的时候,bindMatrixInverse才是bindMatrix的逆。所以根据bindMode的不同值,上述的顺序可以简化表达如下:

bindMode等于'attached'时:

  1. 将所有顶点按照bindMatrix的矩阵数据做变化。
  2. 接着,顶点数据按照每个骨骼在全局坐标系下相对初始化是的变化矩阵做相应的权值变化。

这里的3,4步骤可以被省略掉,因为bindMatrixInverse一定是matrixWorld的逆,它们互相抵消。

bindMode等于'detached'时:

  1. 所有顶点做一个受bone权值影响的变化,相应bone对顶点的影响向量由顶点经过bindMatrix位置变化后,相对bone的位置所决定。
  2. 顶点按照其自身SkinnedMesh的matrixWorld做变化

这里,因为bindMatrixInverse与bindMatrix互逆,bindMatrixInverse能抵消掉顶点按照bindMatrix的移动,但时保留了顶点按照骨骼权值的运动影响。

发表评论

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