压缩
无压缩的动画数据可占用大量内存。主要原因有:
- 每个关节的姿势含最多10个通道。
- 骨骼含有大量关节。
- 角色姿势通常采用高频率采样。
可以通过压缩动画数据,以最少的内存成本提供丰富的动作。
1.通道省略
最简单方法就是省略无关的通道。例如多数动画都不需要非统一缩放,所以三个缩放通道可以缩减至单个。因为大多数骨头(除了一些面部、颈部关节和根关节)是不能伸缩的,所以位移通道也可以部分略去。
2.量化
另一个方法是缩减每个通道的尺寸。
把32位IEEE浮点数转换成n位整数表示法的运算称为量化(quantization)。量化是有损压缩,解码后只能还原为近似值。(因为实质上降低了精确度位数)
- 实现原理:
要把浮点数编码成整数,首先要把合法范围切割成N个相同大小的区间,然后找出浮点数值属于哪个区间,然后用该区间的整数索引表示该值。解码时,只需简单地把整数索引转换为浮点数,并用偏移和缩放把该值还原。
编码有两种方法:1.把浮点数截尾(truncate)至紧接的最低区间边界(T编码)。2.把浮点数舍入(round)至包围区间中值(R编码)。
解码有两种方法:1.传回原值映射到的区间的左值(L重建)。2.传回区间的中值(C重建)。
所以总共有4种可行方法:TL、TC、RL、RC。
应该避免TL和RC,因为这种组合会趋向增加或减少数据中的能量导致灾难性后果。
TC好处是在时间上高效,但是问题是无法准确表示0值(0f编码解码后是一个小的正数)。
RL通常是最好的选择。
- 量化四元数旋转和平移:
为简单起见,可以只量化[0, 1]范围的正浮点数,其他范围可以通过偏移和缩放变成[0, 1]。例如四元数通道的范围是[-1, 1],可以加一再除以二令数值变为[0, 1]范围。
平移的压缩比四元数旋转要棘手,因为平移通道的范围在理论上是无界的。具体压缩方式视情况权衡。
3.采样频率和键省略
动画数据偏大的其中一个原因是采样频率高。有两种压缩方法:
- 降低整体采样率:
在不会明显降低动画质量的前提下,降低整体采样率。
- 键省略:
在通道数据大约呈线性的区间中省略首尾以外的所有采样。在运行时使用线性插值还原删掉的样本。
需要在采样上额外存储关于时间的信息,可能会占用较多的数据量。
4.基于曲线的压缩
CRE:使用少量非等距的采样点组成的曲线(B样条或者Bezier曲线)来创建动画,或者拟合已有的动画,能实现数据量少的同时有很好的动画质量。
5.选择性载入和串流
多数游戏不需要所有动画同时置于内存。
例如有些只应用于某角色的片段,如果在某关卡中不会有该角色,那些片段就不用载入。有些片段在游戏中只会使用一次,这些可以在播放之前载入或串流,播放结束后从内存释放。多数游戏会在游戏开始时载入一组核心动画片段,并一直把它们保留在内存。
Jason:有些游戏引擎把动画打包成逻辑组,以组为单位载入和卸载。
(END)