Ozz-Animation 3D骨骼动画系统

2025年6月29日 250点热度 4人点赞 0条评论

Ozz-Animation 是一款基于MIT协议开源的C++ 3D骨骼动画库及工具集,专注于为游戏和实时渲染应用提供高效的3D骨骼动画的播放功能(包括加载、采样和混合等)。通过其数据导向的设计,ozz-animation在性能和内存使用上表现出色,适用于各种游戏引擎和渲染器。其高度可移植性和跨平台特性使得在不同开发环境中使用非常方便。

Ozz-Animation的Github地址是:

https://github.com/guillaumeblanc/ozz-animation

Ozz-Animation包括runtime和offline两个部分:

  • runtime 提供了运行时动画播放的核心功能,runtime代码只依赖于C++11,可以在Windows,Linux,MacOSX这些常见操作系统,以及ARM平台下运行。
  • offline 包含了一套完整的预处理工具链,用于将主流的数字内容创作格式(如glTF 、FBX等)转换为Ozz-Animation优化的运行时结构。

Ozz-Animation和常见的3D骨骼动画库一样,由以下基本功能组成:

  • 骨骼系统(Skeleton): 角色的关节及之间的连接关系;
  • 蒙皮系统(Skinning): 角色模型网格的每个顶点与骨骼关节的映射关系以及权重(模型顶点受哪些关节运动的影响,影响的程度是多少);
  • 动画系统(Animation): 每个关节移动和旋转的动画数据,以及多个动画之间的过渡、叠加关系的实现;
  • 其它功能: IK系统(反向运动学),武器绑定系统,分部融合系统等。

预处理工具链

如果我们编译Ozz-Animation时,设置了FBX SDK,我们会得到fbx2ozz.exe、gltf2ozz.exe两个工具,和一个样例工具sample_fbx2mesh.exe。

fbx2ozz.exe和gltf2ozz.exe两个工具是为fbx、gltf等模型文件生成骨骼数据、动画数据。

fbx2ozz.exe --file=Tpose.fbx

sample_fbx2mesh.exe是根据模型的骨骼数据,生成模型蒙皮的mesh数据。mesh数据包括位置、法线、纹理坐标、切线、颜色等。

sample_fbx2mesh.exe --file=Tpose.fbx –skeleton=Tpose.skeleton.ozz --mesh=Tpose.mesh.ozz

这样我们就得到了ozz运行所需要的骨骼数据、动画数据、蒙皮的Mesh数据等。

Ozz-Animation的更新流程

Ozz-Animation的动画更新流程主要分为下面四个步骤:

  • 动画数据的采样: 即根据上一帧到这一帧的时间间隔,计算动画应该经过的时间,进而从关键帧插值解算出每个关节点的局部坐标。
  • 多个动画的融合: 将多个动画采样的结果按照独立的权重,融合在一起,得到最终叠加后每个关节点的局部坐标。这个步骤对于角色动画的过渡效果实现是至关重要的。
  • 骨骼数据的更新: 将之前解算得到的角色动画关节点的局部坐标,匹配到实际角色的骨骼上,并计算得到骨骼坐标系(“世界”坐标系)下每个关节的实际位置矩阵。
  • 蒙皮和模型网格的更新: 根据每个关节位置的变化,以及关节与模型各顶点之间的权重关系(即蒙皮),计算每个顶点更新后的位置坐标、法线等结果,更新模型网格。

Ozz-Animation将这套流程中的每个步骤都封装成独立的工作线程(Job)并负责负责每个Job的并行执行和效率效果,各个步骤之间输入和输出的中间数据,我们随时都可以介入修改或者替换,这也使得Ozz-Animation成为了一个非常灵活而且强大的中间件工具。

%title插图%num

以上就是Ozz更新过程的工作流程(其中,SoA的含义是“Struct of Array”,可以理解为一组关节数据)。

举个例子

假设我们有一个人物角色,有两个动画,分别为“站立”(idle)和“走路”(walking),我们的人物角色从站立姿态切换到走路姿态。如果直接切换,那么骨骼关节会从当前的姿态突变到一个新的姿态。这个过程显得比较突兀,有必要加入一个合理的过渡过程。这个过渡过程就是动画融合的过程。

假设从站立姿态切换到走路姿态,过渡时间为0.5s。那么这个过渡实质上就是:idle采样器的权重值从1到0,而walking采样器的权重值从0到1。每个时刻t的动画融合结果应该是:

sampler[idle] x (1.0 - t / 0.5) + sampler[walking] x (t / 0.5),其中t∈[0, 0.5]

结合Ozz-Animation的工作流程大致过程为,我们为idle和walking建立两个独立的Sampling Job进行采样(每个动画设置不同的权重值,所有动画的权重之和不超过1.0,值得一提的是,Ozz-Animation不仅支持设置动画的权重,还支持设置动画中各个关节的权重,以实现精准的动画融合策略),将采样得到的动画数据在时间线上选择一个时刻,并计算该时刻对应的各关节位置姿态数据。每个采样器输出一组位置姿态数据,合并到Blending Job中,按照权重混合后,得到介于两个动画效果之间的一组新的位置姿态数据,经过坐标变换后,进行蒙皮计算,输出最终显示的模型网格数据。

StackSnow

追风赶月莫停留,平芜尽处是春山。

文章评论