Oodle 压缩算法

和我当初预想的一样,2021.04.01 的 Feeds:Epic 把 Oodle 集成到 UE4.27 和 UE5 中了。

他们会提供四种 Oodle 系列的压缩算法:

  • Oodle Data Compression:最快和最高压缩比的压缩算法,可以用于数据压缩、打包压缩等。
  • Oodle Texture:用来压缩 Texture,可以压缩 BC1-BC7Texture,能够减少 50% 的 Texture 大小(官方数据)。
  • Oodle Network Compression:压缩 TCP/UDP 数据,降低与服务器传输占用的带宽。
  • Oodle Lossless Image Compression:无损图像压缩算法,比 png 小很多且具有非常高的解压速度。

目前(2021.04.05)可以拉取 UE 的 master 分支,下载依赖之后在以下目录下:

1
2
E:\UnrealEngine\Source\UnrealEngine\Engine\Plugins\Compression
E:\UnrealEngine\Source\UnrealEngine\Engine\Plugins\Developer\TextureFormatOodle

具有 OodleDataOodleNetworkTextureFormatOodle三个插件,注意必须要下载依赖。不然代码中只有 .h 接口,并没有各个平台的链接库。

比较遗憾的是在更早的引擎版本中不支持,我从 UE 的开发分支把这部分代码抽离了出来,放到了单独的仓库中:oodle-compression,看了代码并没有依赖新版本引擎相关的东西,但是直接在低版本引擎启用会有编译错误,我已修复。插件中的实现也是通过 SDK 把 Oodle 添加到了 UE 的 Compression 的 Modular Feature 中,同样可以按照我之前这篇文章的介绍中的方法使用:ModularFeature:为 UE4 集成 ZSTD 压缩算法

当使用 IOS 远程构建时还需要加上 Sdks 的 Rsync 的上传规则:

Build/Rsync/RsyncProject.txt
1
2
3
4
+ /Plugins/Compression/oodle-compression/OodleData/Sdks/2.9.0/include/**
+ /Plugins/Compression/oodle-compression/OodleData/Sdks/2.9.0/lib/IOS/**
+ /Plugins/Compression/oodle-compression/OodleNetwork/Sdks/2.9.0/include/**
+ /Plugins/Compression/oodle-compression/OodleNetwork/Sdks/2.9.0/lib/IOS/**

注意:如果默认打包时想要启用 Oodle 需要将插件放入 Engine/Plugins/Runtime 下,并给 Oodle 插件的 uplugin 添加 "SupportedPrograms" : ["UnrealPak"],在 UnrealPak 启动时会加载Oodle 插件。

通过在项目设置中配置 Oodle,会传递给 UnrealPak 命令行参数 -compressionformats=Oodle 来指定使用 Oodle,以及 -compresslevel=fast 来指定压缩级别。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
UATHelper: Packaging (iOS): Output from: "D:\UE4\Blank\Blank.uproject" "D:\UE4\Blank\Saved\StagedBuilds\IOS\cookeddata\Blank\content\paks\Blank-ios.pak" -create=C:\build_agent\workspace\FGameEngine\Engine\Engine\Programs\AutomationTool\Sav
ed\Logs\PakList_Blank-ios.txt -cryptokeys="D:\UE4\Blank\Saved\Cooked\IOS\Blank\Metadata\Crypto.json" -order="D:\UE4\Blank\Build\IOS\FileOpenOrder\CookerOpenOrder.log" -platform=IOS -AlignForMemoryMapping=16384 -compressionformats=Oodle,Zlib -multi
process -abslog=C:\build_agent\workspace\FGameEngine\Engine\Engine\Programs\AutomationTool\Saved\Logs\UnrealPak-Blank-ios-2021.07.13-18.43.29.txt -compressmethod=Kraken -compresslevel=fast
UATHelper: Packaging (iOS): OodleCompression: Display: Oodle v2.9.0 initializing with method=Kraken, level=3=Fast
UATHelper: Packaging (iOS): LogPakFile: Display: Parsing crypto keys from a crypto key cache file
UATHelper: Packaging (iOS): LogPakFile: Display: Loading response file C:\build_agent\workspace\FGameEngine\Engine\Engine\Programs\AutomationTool\Saved\Logs\PakList_Blank-ios.txt
UATHelper: Packaging (iOS): LogPakFile: Display: Added 2255 entries to add to pak file.
UATHelper: Packaging (iOS): LogPakFile: Display: Loading pak order file D:\UE4\Blank\Build\IOS\FileOpenOrder\CookerOpenOrder.log...
UATHelper: Packaging (iOS): LogPakFile: Display: Finished loading pak order file D:\UE4\Blank\Build\IOS\FileOpenOrder\CookerOpenOrder.log.
UATHelper: Packaging (iOS): LogPakFile: Display: Collecting files to add to pak file...
UATHelper: Packaging (iOS): LogPakFile: Display: Collected 2255 files in 0.01s.
UATHelper: Packaging (iOS): LogPakFile: Display: Creating pak D:\UE4\Blank\Saved\StagedBuilds\IOS\cookeddata\Blank\content\paks\Blank-ios.pak.
UATHelper: Packaging (iOS): LogPakFile: Display: ENABLING pak file index freezing
UATHelper: Packaging (iOS): LogPakFile: Display: Added 2255 files, 123452947 bytes total, time 2.17s.
UATHelper: Packaging (iOS): LogPakFile: Display: Compression summary: 43.30% of original size. Compressed Size 69209450 bytes, Original Size 159833025 bytes.
UATHelper: Packaging (iOS): LogPakFile: Display: Used compression formats (in priority order) 'Oodle, Zlib, '
UATHelper: Packaging (iOS): LogPakFile: Display: Encryption - DISABLED
UATHelper: Packaging (iOS): LogPakFile: Display: Unreal pak executed in 2.233311 seconds
UATHelper: Packaging (iOS): UnrealPak terminated with exit code 0

经过测试,一个使用 zlib 压缩之后有 295M 的 pak 文件使用 Oodle 压缩降低到了 282M,但是 Oodle 的解压速度完胜 zlib。
Oodle 的压缩性能在 RAD 网站上有对比数据:Oodle Compression


其他的对比数据:

压缩算法的选择就是要在压缩率 / 解压速度上来做一个权衡,就是压缩率最低的 Selkie 也比 zlib 要强一点点,但是 decompress 速度比 zlib 高了十几倍,对于游戏而言解压速度非常直观地影响到游戏性能,这应该也是 UE 选择收购 RAD 的原因吧。

其他资料: