动画系统
底层动画系统
- 2019-09-15
- 翟升富
Motivation:动画系统比较复杂,所以设计的时候需要分开底层动画系统和顶层动画系统.底层动画系统负责诸如动画压缩,曲线光滑等,顶层动画系统负责动作混合,叠加等.本次主要讲述底层动画系统的一些原则.文章收到诸如unreal, unity等动画系统启发.
底层动画系统任务
一句话总结就是:给定任意时刻的骨骼姿势.为了最大化性能,需要考虑
- 动画尽量压缩
- 缓存友好访问
我们采用曲线拟合和数据量化的方法来进行动画压缩.
曲线拟合
曲线拟合有很多方法,只要满足:
- 误差低于一定阈值
- 良好的压缩率
- 曲线足够光滑
- 时间复杂度不是很大
我们采用埃尔米特曲线 Hermite Spline.\(t\)时刻的数据点\(D\)为:
$$(-\frac{t^3}{2} + t^2 - \frac{t}{2})D_{i-1} + (\frac{3t^3}{2} - \frac{5t^2 }{2} + 1)D_{i} + (-\frac{3t^3}{2} + 2t^2 + \frac{t }{2} )D_{i+1} + (\frac{t^3}{2} - \frac{t^2 }{2} )D_{i+1} $$
这种方法总可以将误差限定于一定阈值,因为如果误差过大,只要二分即可.
动画压缩可以在局部空间和全局空间进行.全局空间的好处是误差不会在骨骼层级之间传播,所以当压缩动画的时候可以使用更大的误差阈值.但是另一方面全局空间的运动描述更加复杂.另一方面,动画混合等一般都是在局部空间进行.因而综合考虑,我们在局部空间进行动画压缩.
至于数据量化,对于三维向量,用16位表示每个部分,然后范围拟定-10m~10m,这样会得到0.3mm的分辨率
最后一点很重要的四元数,用2bits来储存最大部分的索引, 然后用10bits来表示剩下三个部分的值, 因为是单位复数,所以最大值可以求得.并且因为我们保存的不是最大值,所以三个部分的值的范围必定是\((-1/\sqrt2, 1/\sqrt2)\).而我们用10bits来量化,所以精度是0.0014.
我们现在总结一下:曲线上每个三维向量点用48bits表示,每个曲线点量化用32bits表示(2 + 3 * 10),然后16bits表示时间戳.
剩下的问题就是,如果将所有骨骼的所有曲线点以一种友好的缓存获取方式压缩.
友好缓存访问
每个动作包含多个轨迹(track).每个轨迹包含时间和对应的数据.最简单我们考虑一个时刻\(t\)的数据需要前面和后面的时刻数据来确定.