Home > 程序/算法 > 骨骼动画的数据压缩(二)

骨骼动画的数据压缩(二)

上一篇遗留了一个问题没有说完,就是关于绝对变换和相对变换。我们的骨架一般是以树形结构存储的,一个骨骼会有一个父骨骼(根骨骼除外)和若干个子骨骼。所以对于骨骼的变换我们可以存储在模型空间中的绝对变换,也可以存储相对于其父骨骼的相对变换,二者是可以相互转换的。

用相对变换形式存储的好处主要是便于拆分成不同类型的变换从而使动画插值成为可能;而保存绝对变换的好处首先是效率较高,因为在蒙皮计算的时候我们真正需要的是骨骼的绝对变换,如果保存的是相对变换就需要根据骨骼的父子关系先计算出绝对变换矩阵,每块骨骼都多出一个矩阵乘法的开销。另外直接保存绝对变换还能避免因为逐层相对变换引起的累积误差。

言归正传,我们继续来看动画数据的压缩,前文已经把200k的数据压缩到60k左右,还有办法继续压缩吗?

用过Max(Maya和XSI不太熟悉,但想来也应该差不多,下文只讨论Max)的同学会发现,虽然我们的动画定的是30fps的标准,但是美术实际摆放的关键帧要远远低于这个密度,对于简单的动画,某些骨骼可能在两秒的时间内只有3~4个关键,其它时间的骨骼方位实际上是导出时Max自动插值得到的。于是小算盘就开始打了,既然我们保存的骨骼关键帧大部分都是Max自动生成的,那么我们能不能只保存真正由美术摆放的关键帧,剩下的也象Max所做的那样自动插值出来呢?如果可以的话,无疑将再次大幅减小动画文件的尺寸。

这个想法很诱人,而且答案基本是肯定的,但是要解决几个问题:

首先,Max的帧间插值方式不是线性的,而我们通常运行时采用的都是线性插值的方法,如果仅导出“美术关键帧”,在运行时就得不到在Max里看到的同样的效果

这个问题不难解决,只要实现一个和Max一样的非线性插值算法就行了,这一点Grandpa已经做到。当然,非线性插值一定会比线性的慢一些,如果效率比较吃紧的话,可以在动画文件加载完先按30fps的帧率非线性插值出均匀的关键帧(就像从Max里导出时所做的)放在内存里,在播放动画时仍然用线性插值;如果效率不是特别敏感(以我的经验动画帧间插值的开销占整体的比例非常小),可以直接在播放动画时采用非线性采样,这样不但节省了硬盘空间,连内存都省了。

另外一个比较麻烦的问题是,美术制作动画时几乎不可避免会用到IK控制器,例如走路时贴地的脚,持双手武器(比如长矛)时的“从动手”,甚至头部和视线的移动等等。IK控制是不能体现在关键帧里的,所以如果想达到只导出“美术关键帧”的目的,你的插件必须能同时导出这些IK控制的参数,而且引擎也必须能够实时处理。

待续……

Categories: 程序/算法 Tags: , ,
  1. funcman
    August 21st, 2010 at 17:57 | #1

    MAX里是不是有多种插值算法?(曲线编辑器)

  2. March 15th, 2011 at 17:09 | #2

    Max的controller太多了,不可能只取key frame;另外,如果美术使用了layer,那么可能根本在最上层取不到实际的key。
    所以还是只能老实得sample,然后删除empty key和可以通过插值生成的key。

  3. March 17th, 2011 at 20:36 | #3

    你说的对。我只是说在没有用到其他controller的时候,直接采用美术关键帧,显然更高效也更准确一些。

    用sample之后再删除key的方法有一个问题,只能保证得到的动画在sample点处和原始动画接近,如果把动画放慢播放,就可以看到非sample时间点上的pose有可能和正确轨迹相差甚远,直观表现一般是容易观察到肢体末端发生抖动。当然,如果播放帧率和sample帧率接近的话就不容易发现问题。

    所以,最理想的方法是,如果可行的话,最好能将Max的controller的原始信息导出,在运行时进行应用相同的控制,至少对于IK这样的控制器是可行的,如果能接受一部分效率损失的话。Max我不是很熟,我想一定会存在一些运算量相当大的控制器,比如物理什么的,就不太适用了。

  4. happynp@qq.com
    January 11th, 2012 at 11:34 | #4

    max的controller那么多,每个都支持,你不累死? 导出后,对动作关键帧做个关键帧精简也可以考虑吧

 

Spam Protection by WP-SpamFree