算法:线性时间选择_UE4 Animation Sequence的压缩算法

2ad4adf2eacf52112435237f362e12ae.png

本文章主要参考Frechette的这篇文章,介绍了UE4的Sequence所使用的压缩算法,并分析在实际中如何选择使用。

UE4的Animation Sequence里的压缩算法基本原理:将原始数据分散到Translation、Rotation和Scale三种Track里面,然后根据算法去分别进行位压缩(Bitwise Compress)或者抽帧来完成压缩。

187ebb5382501bc6254d07aaef0e4569.png

每个Track由帧和时间组成:

e07c8b81254027e0e0faf58565f695a1.png

下面逐一介绍具体的算法和原理:

Least Destructive(无损)

解压动画,尽可能地保持原始数据。

Translation使用None即全精度,Rotation使用Float96NoW。要注意Scale没有设置解压格式,有可能是个bug。W在这里是用于重构旋转四元数(rotation quaternion)的,如果不考虑组件丢弃的问题可以不要。

7f2317c1d7bff81227c6ff0eb4276c1a.png

这个算法没什么参数值得修改的。

Remove Trivial Keys(移除非关键帧)

当出现连续相似帧的时候,仅保留一帧关键帧删除其他帧。

这个算法在UE4的压缩算法里用得很普遍,几乎所有的算法一开始就会先使用它。

042254c53b4d9ab40663a59cd4ffcabb.png

非关键帧的范围可以手动调整参数:

eca33aeca374c3832da5cf6406d9b0ec.png

Bitwise Compress Only(仅位压缩)

这个算法首先会移除非关键帧,然后对每帧都进行位压缩。

e96f492a5da54e6d8e82c2b3ad7b5236.png

这个算法没什么参数值得修改的。

Remove Every Second Key(隔帧移除)

这个算法其实就是上述几个算法的结合。首先会移除非关键帧,然后进行隔帧移除,最后进行位压缩。隔帧移除就是每两帧删除一帧,相当于一种子采样。当然这个Interval你可以自己改。

39ce86302c8a4ecdfa756dc598bbf485.png

可以设定至少有几帧时才进行隔帧移除,也可以选择从第二帧才开始执行隔帧移除。

66de005d237d46cb35c7e4885bf84768.png

Remove Linear Keys(移除线性帧)

这个算法首先会移除非关键帧,然后使用经典的减少线性帧算法(the linear key reduction algorithm)去除线性插值用到的关键帧以外的帧。UE4还使用了局部空间误差度量(local space error metric)和局部虚拟顶点误差度量(partial virtual vertex error metric)两种算法去减少父节点帧的删除可能会造成子节点关键帧缺失、错误的问题。具体原理参考:

http://nfrechette.github.io/2016/11/01/anim_compression_accuracy/​nfrechette.github.io

可以修改参数决定关键帧范围:

5a8c2e05691f7f32821a2a9af712ad2e.png

Compress per track independently(按照不同的Track独立压缩)

这个算法除了使用上述提到的减少线性帧算法,还用到了简单量化位压缩算法(the simple quantization bitwise compression algorithm)。这个算法其实非常简单,就是将需要压缩的浮点值量化到取值范围,然后将它扩大到想要压缩的类型范围,最后对其四舍五入即可。比如有个浮点型的值0.45,它的取值范围为-PI到PI,我想将它位压缩为signed16的整数,那么只需要0.45 / PI = 0.14,因为signed16的整数范围为-32767到32767,所以0.14 * 32767.0 = 4587.38, 最后四舍五入Floor (4587.38 + 0.5) = 4587,这个4587就是我们压缩后的值了。要解压它只需要逆推,即4587.0 / 32767.0 = 0.14,0.14 * PI = 0.45。当然还有别的情况要考虑,详细参考这个博客:

Animation Compression: Simple Quantization​nfrechette.github.io

可以选择每个Track支持的格式。这个算法参数比较多,误差度量(error metric)需要手动调整,如果不知道如何调整可以直接选择Automatic算法。

bf44cb6f751ed00ce7ab25198b8e2d45.png

Automatic(自动选择)

自动测试上述所有算法,也会自动测试减少线性帧算法和简单量化位压缩算法的采样值和其他参数,最后应用压缩效果最好的算法。一般来说Compress per track independently的效果最好,所以选择Automatic基本就是使用这个算法。

可以调整自动选择的效果

7f1f306d3a11efadd73e18f392ca43f7.png

选择后Apply的结果:

6731f7f323aeb01f0309c0d658b88202.png

总结

Frechette认为,UE4的动画压缩的数据布局是简单地按照Track排序的,这样一来在解压的时候每个Track都需要花费一个Cache Miss去读取压缩数据。由于上述提到的内存布局不合理造成的Cache Miss,再加上UE4在使用减少线性帧算法时缺少一个指针(curser)或者其他加速结构,会导致解压时间变长。另外UE4所采用的减少线性帧算法里的误差度量和量化算法也过于简陋。从结果上来说,选择了Automatic几乎就等于选择了Compress per track independently,也就用到了减少线性帧算法,因此不要以为选择了Automatic就是一劳永逸的。总体来说这个动画压缩系统还是有待改进的。

综上所述,Compress per track independently压缩效果最好,但是Frechette指出它比较简陋,解压速度过慢,而且它的算法比较复杂,不太容易理解参数。Remove Trivial Keys和Bitwise Compress Only在很多情况下压缩效果并不好。如果在实际测试时发现使用Compress per track independently后动画有卡顿、失真等现象,我建议使用更简单易控、压缩效果比较明显的Remove Every Second Key。当然,了解了原生压缩算法的缺点,大家也可以直接在原有的Compress per track independently算法上进行魔改。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值