我假定你已经知道这些年游戏中三维人物动画背后的基本数学原理了, 如果你还不知道, 请查询skeletal animation, skin等关键字。这篇文章只涉及此类型动画,其他类型的动画不在本文范围内。
如果你能够基本理解以上内容,那你一定猜到了,游戏中人物的空闲,行走,跑,以及其它动作都是单独的动画序列。
本文要讨论的问题是,各个动作之间的过渡该怎么办?如果想系统的了解此主题,请先前往查询 Animation Blending,以及大概看一下“Realtime Character Animation Blending Using Weighted Skeleton Hierarchies”这篇paper。你还可以先看看“Character Animation With Direct3D"这本书的第五章。
如果你不愿意看到数学公式,矩阵等等这样的字眼,想让我用一句话概括我要说的,那么请阅读本段即可。本文末尾下载到的demo,使用了三段动画:idle, walk and run,这三段动画本质上是空间方位的在时间上的函数,回放此函数的过程就是动画序列播放的过程;所以,从一个动作过渡到另一个动作,实际上就是一个函数过渡到另一个函数。所以,这个demo主要做的事情,就是在这些函数间插值,达到动画间的平滑过渡。
如果你还在继续阅读,那么说明你不满足于高度抽象的描述,你也想自己实现。本文以下的描述以细节为主。这里所说的内容并不新鲜,你可以从很多开源游戏引擎获得源码或通过其它网上资源寻求帮助。我只从我在实现过程中遇到的问题角度来展开讲解,而这些内容也可能正是你在实现过程中一直忽略掉的细节,以致于结果始终都不正确。
首先,你要有三维模型和动画序列的原始文件。我是从网上下载了Rocketbox Libraries Complete Characters,这个貌似不是免费的,感谢盗版吧(好在我也只是因学习的目的使用);你获得到的原始文件一般都是3dsmax, blender or 其它三维建模软件的格式,你可能需要导出成为你需要的格式。我最终选择导出成为collada文件格式。
然后,你需要能够加载这些模型文件和动画文件。我使用了assimp库来帮助做这件事情。到这里的时候,请你停下来,确定下你导出的文件使用了左手坐标系还是右手坐标系,你导入的时候是否需要进行这两者之间的转换;确定Up方向使用的是哪一个轴,导入的时候是否需要转换。
Up方向使用哪一个轴问题好处理,一个坐标系的旋转就能搞定。坐标系的变换就比较麻烦了,无数人栽在这里,不愿意深究的人请直接使用assimp库。
以右手坐标系变换到左手坐标系为例,由于两种坐标系下投影轴Z轴的朝向不同,会导致投影的z值刚好正负相反(当然,保持两种坐标系下的Z轴朝向相同也不能解决问题,因为这样会使X和Y值的值正负颠倒);不止这样,旋转矩阵也要处理,想象沿着z轴正向的旋转矩阵吧,两种坐标系下,旋转方向刚好相反;还要考虑法线等的朝向问题;它还引入了三角形三个点投影之后在二维空间的正反向问题(culling)。我不在这里详细解释各种情况下的处理方法,不过我总结了一个通用原则,在进行左右坐标系变换时,请都把它看作一个常规的坐标系变换问题,请把任何空间数据,都过一遍这个变换矩阵,可能的话对结果再简化。有问题的同学请回帖提问吧。
接下来,你可以把动画序列渲染出来了,这里略过,网上资源一大堆;个人建议,先把骨骼动画自己渲染出来(见本文末尾的demo),再做蒙皮,这样理解更透彻。
最后,到了我们的主题,动画合成。怎样从walk过渡到run呢。简单的说,一开始,walk动画/函数的权重为1,run动画/函数权重为0,之后随时间线推进,walk的权重越来越小,run的权重越来越大。是的,高度抽象的概括就是这样的。
那么实现呢?实现的细节看起来就不是这么美好了。
第一,你需要在skeleton的每一个bone都进行这个加权和的计算,而且,是平移,缩放和旋转各自的加权和;其中旋转需要用四元数来表示,其它两个可以用三位向量来表示;如果你的skeleton果真有缩放的话,有没有考虑过其它的插值方式,比如s = sign(s0)*sign(s1)*pow(|s0|,1-w)*pow(|s1|,w)。最后把插值的结果转换为矩阵。
第二,动画序列还受到动画时间长短/周期的限制,walk和run的周期不同,或者说一个迈腿慢一个迈腿快,这个因素也要逐渐过渡。也就是说,动画周期时间也要逐渐过渡。
最后,动画序列之间需要保持一定的相近度再进行过渡,比如walk和run,请不要把walk的迈左腿和run的迈右腿进行融合过渡;请在他们都是迈同一条腿的时候过渡。
看最终的demo图吧,表示的是walk和run之间的过渡。
本文不能详尽的描述所有细节,希望耐心读完的同学能够自己先尝试实现;如果有问题,随时欢迎联系。
附上demo下载地址:
下载地址
https://files.cnblogs.com/mchz/Skeleton.rar
操作方法
默认idle,W键walk,SHIFT+W键run
运行环境要求
WinXP SP2 or Higher DirectX11 Runtime & DirectX10 Supported Video Card VS2012 Runtime(https://files.cnblogs.com/mchz/vcredist_x86.rar)