再议骨骼动画和蒙皮
之前写了一篇关于骨骼动画的文章。今日阅读三维模型变形算法,发现还是有很多需要写的,现在趁着有机会补充一下。
骨骼动画
骨骼动画分为两部分,骨骼本身的动作和蒙皮。蒙皮指的是把三维模型的点和骨骼一一对应起来,也就是每隔顶点对应一根骨头或者多跟骨头。在骨骼动画中,一根骨头或者一个关节只是一组顶点的一个控制点。当骨头运动时,每个附在它上的顶点也跟着运动,同时某个骨头自身的运动也会导致其他骨头的运动。
骨骼动画中的动作一般使用两种方法获得,一种是手工调节,也就是调整每个关节或骨骼的位置和方向,从而得到某个姿势。另一种方法是通过动作捕捉设备对真事的人物于东进行捕捉,得到骨骼动画。
BVH文件
BVH(Biovision Hierarchical Data)是一种骨骼动画数据的文件存储格式。BVH文件分为两个部分:骨架信息和数据块。骨架信息按照层级关系,定义了各个关节的位置和旋转分量,从而形成一个完整的骨架。数据块部分对应骨架的各部位,标出每帧的数据信息。
骨骼以标准型大字型为起点。整个骨骼存储节点与节点之间的相对位移,并以树形结构进行文件存储,由跟节点开始,依次按照其孩子节点,按照深度优先遍历方式进行存储。对于一个BVH文件来说,动作的数据要和关节数据相匹配,必能用另一种BVH的动作数据去驱动不同定义的BVH骨骼。
蒙皮
在骨骼的动作文件加载到内存后,这些动作不仅仅可以驱动骨骼本身的变化和运动,还可以通过骨骼驱动和骨骼相连的三维模型进行变化和动作。用骨骼的动作改变三维模型的动作,就需要把三维模型和骨骼关联起来。这种关联技术就是蒙皮。蒙皮把三维模型上的顶点和骨骼进行对应,每个顶点随着特定骨骼的位移、旋转进行相应的位移和旋转,骨骼的动作就改变了模型的形状。
三维模型和骨骼的关联需要用到三维软件,在三维模型和骨骼关联之后,这些数据就可以保存到一个文件。
一般来说,这些数据保存为三个文件:
- 动作文件
- 三维模型文件
- 使三维模型和骨骼相对应的蒙皮数据文件
不过实际上使用更多的情况还是将三种数据全部包含在同一个文件中。比如collada、fbx、glTF、pmx、SMD/mdl、MD5等。
经过蒙皮的三维模型除了原来三维模型包含的顶点、面信息之外,还有每个顶点和骨骼对应的信息。一个顶点可以对应若干个骨骼,每个骨骼对同一个顶点影响不同,就是说具有不同的权重(weights)。
在权重确定之后,需要根据权重的数值,以及关节点的旋转唯一改变与这个关节点相连的顶点的位置。有两种算法可以实现这个过程,分别是线性混合算法(Linear Blend Skinning,LBS)和对偶四元数算法(Dual Quaternion Skinning,DQS)
线性混合算法LBS
线性混合方法采用线性的方法从骨骼上关节的变换矩阵求得顶点的变换矩阵,然后把每个顶点的位置变换由对应关节的变换矩阵加权求得。
实际最常使用的算法
对偶四元数算法DQS
对偶四元数算法也需要计算关节的变换矩阵,但是不是采用线性混合的方法来求得每个顶点的最终变换矩阵,而是先把关节上的变换矩阵变为对偶四元数,再把每个顶点对应的各个关节上的对偶四元数进行加权求和。然后再把求和的对偶四元数变换到矩阵,最后用得到的矩阵对顶点进行变换。
DQS算法利用对偶四元数相加时选择部分直接相加,从而可以解决LBS算法在关节运动时模型体积减小的问题,相比LBS算法能够获得更好的变形效果
SMD蒙皮文件
SMD文件把蒙皮数据和骨骼的动作数据分为两个文件,其中蒙皮数据文件包含三维模型、骨骼层次、权重信息。动作数据文件只包含动作的所以帧的数据。蒙皮文件中的Skeleton模块只有一帧的数据,用来初始化骨骼的位置。动作文件不包含三维模型信息,需要把动作通过骨骼名与模型文件绑定。这样就可以灵活的吧同样的动作应用到不同的三维模型,以及对同一个三维模型应用不同的动作。