肖泽群
北方工业大学 信息学院 北京 100144
Unity3D作为当前应用最广泛的游戏制作引擎,其实现三维人体模型变形的方法仍然具备一定的研究价值,本文通过研究Unity中人体动画变形的方法,仿照其原理使用OpenGL结合Kinect实现了一个实时的三维人体动画展示系统。
三维动画作为计算机图形学里的一个重要的研究领域,从本质上讲,它是一系列连续的图形按一定的速率显示后,给人以动画的感觉[1]。人体动画根据角色控制方式不同可以分为两种:基于传统计算机动画技术的方法[2]和基于动作捕获系统进行数据驱动的方法[3]。
本文通过对Unity引擎实现三维人体动画方法的研究,依靠深度相机Kinect获得实时人体的骨骼点坐标,然后通过OpenGL库使用C++语言实现动画功能。
FBX储存模型的全部信息依靠的是一种多叉树的结构。一个 FBX 文件中的信息起始于一个属性为空的场景节点,这个节点作为根节点而存在,在这个根节点中的每一个子节点都包含了一种或多种模型信息,我们可以根据这种子节点去寻找父节点,也可以从父节点开始,遍历寻找子节点。FBX模型还对每个节点都添加了一个标签用来标记这个节点属于什么类,通过这个标签,FBX模型可以快速判断子节点的类型,并且降低遍历寻找节点信息时的耗时。
FBX文件是通过二进制来储存数据的,所以我们在读取的时候需要使用FBX SDK。在使用FBX SDK 进行FBX的处理操作之前需要进行必要对象的初始化:
2.1.1 KFbxSdkManager:管理所有的FBX对象的加载与释放。
2.1.2 KFbxScene:场景的入口。初始化完成后,我们从根结点开始,遍历所有结点,如果当前的结点属性为 Mesh,就记录下它的空间坐标、纹理信息、影响的骨骼点个数,以及这些骨骼点的索引和影响因子。我们通过位置和纹理坐标等信息可以生成人体模型的几何网络,此外,如果这个结点中包含 skin 信息,就可以获得其中每个相关联的 cluster,而一个 cluster 事实上也代表了骨骼点。然后我们使用FBX SDK中的Get Transform Matrix和Get Transform Link Matrix函数,获取到Transform矩阵和Bindpose矩阵,Bindpose矩阵是给模型绑定骨骼时将顶点由Mesh的局部空间变换到Bone的局部空间的变换矩阵。最后通过如下公式,可以计算出每个骨骼点的世界坐标,进而可以使用OpenGL进行模型的渲染,加载得到具有骨骼蒙皮信息的FBX模型。
需要注意的是,为了便于后续变形步骤的计算,读取的人体模型需要置成T-Pose,即展臂直立的姿态,如图所示。
图1 T-Pose姿态图
本文通过Kinect深度相机,进行人体关节点信息的实时采集。为了获得我们需要的骨骼数据,就需要通过Kinect for Windows SDK 中的Nui Skeleton Get Next Frame函数,该函数能够直接从NUI_SKELETON_FRAME 类中获得骨骼点的全部信息[4],这个结构体中包含了时间标记的字段,骨架上的数据字段等,其中骨骼数据字段中储存了当前骨骼的状态,当前骨骼的编号,所有骨骼中间点的坐标,所有骨骼的空间坐标等信息。当前骨骼的状态指的是该骨架有没有被检测到,检测到的骨架有没有被激活。
最后我们可以利用函数 Nuitransformsmooth(&skeletonfra me,null)对我们获得的人体骨骼点的坐标数据进行平滑化的处理。在对一副骨架的骨骼进行运动跟踪的工作过程中,有些特殊的情况一旦发生,很有可能甚至会直接导致一个骨骼的内部动作幅度呈现跳跃式的变化。比如检测到游戏中玩家的肢体动作节奏不够连贯,Kinect 硬件的机能限制等。相邻帧之间的同一个骨骼关节点的相对坐标如果产生大幅度不合理的变动,就可能对应用程序的展示效果产生致命的影响。比如说这会对用户的操作体验产生不良影响以及给控制系统带来意外。而这个标准函数也正是为了有效解决这个复杂问题的,它对于每个骨骼上的数据运动进行平滑,通过将每一帧的每个骨骼运动关节点及其位置上的坐标数据进行精确的标准化,从而大大减少帧与帧之间的骨骼关节点之间位置坐标差异。
得到了深度相机Kinect采集到的人体实时关节点信息后,我们通过lookrotation(vector3 forward, vector3 upward) 函数,得到让Z轴对齐forward,让y轴对齐upward 所需要的旋转四元数。forward和upward是叉积,通过Vector3Cross(Vector3 lhs,Vector3 rhs)计算得到,其中的lhs和rhs由于骨骼点不同,其计算方法也略有不同。
然后,我们将得到的四元数转化成旋转矩阵的形式。一个标准的单位四元数可以写作 ,其中:
根据相关数学公式[5],可以构建旋转矩阵
最后,遍历所有骨骼点及其对应的蒙皮顶点与旋转矩阵进行加权计算,得到全部顶点的位置,随后使用OpenGL对模型进行渲染。
本文通过一台在8G 内存,CPU 为 Intel i5-8265U,512G PCIe固态硬盘,搭载 NVIDIA GeForce MX250 显卡的 Widows10 操作系统的电脑上进行效果的展示。本文整体系统流程图如下。
图2 系统流程图
本文展示了一段奔跑的动作及实时的动画,效果如图3所示。
图3 效果展示
虽然动画引擎系统不断更新换代,但是OpenGL在一些特殊场景的应用中依然具有无法替代的地位,相信随着数学、计算机图形学以及相关动作捕捉设备的发展,结合了OpenGl和Unity等引擎的三维人体实时动画技术能够获得更加光明的前景。