7

我一直在尝试找出游戏引擎如何处理资产压缩。显然,他们在构建游戏时会压缩所有资产。但是他们如何在运行时解压缩它们。我唯一能想到的就是解压缩到内存中,但这一定是非常占用内存的。如果他们在玩游戏时解压到硬盘上,文件夹会被填满吗?这听起来不是很有效。

在 c++ 中使用像 zlib(或任何其他)这样的库,这个运行时解压缩是如何完成的?

大卫

4

3 回答 3

9

有点像这样,你有一个游戏有这么多的数据,它不适合合理的内存量,所以你不能一次将它们全部加载到内存中,所以你为你的数据定义了一些缓冲区用作缓存。

现在内存按速度从低到高的顺序是这样的:

  • DVD
  • 硬盘
  • 内存

理想情况下,您不必从 DVD 流式传输数据,但如果您必须制作控制台游戏,则需要考虑这一点。因此,对于这些可用存储空间中的每一个,您都定义了一个用作缓存的缓冲区。

当游戏引擎决定它可能需要一个资源时,它应该首先在最快的缓存中查看资源是否已经加载。如果是,那么您很幸运,您可以立即将其发送以进行抽奖。如果它不在最快的缓存中,则必须降低到硬盘驱动器缓存的级别。这是一个文件,您可以在其中保存已解压缩并准备加载到内存中的资产。如果最快的缓存没有被完全占用,那么您可以开始加载数据并在准备好时使用它。如果没有足够的空间,那么您必须先卸载其他资产,我建议您删除最近最少使用的资产,直到您有足够的空间来加载新资产。

现在,如果硬盘驱动器缓存没有加载数据,那么您必须再向下一层存档,您将需要使用 zip 格式来压缩它,因为 zip 文件格式不会强制您解压缩整个存档只能访问一个文件,因此您所要做的就是在存档中找到所述文件的偏移量并将其解压缩到硬盘驱动器缓存中。同样,如果缓存已满,您必须先卸载一些其他资产,我再次建议删除最近最少使用的资产,但如果您认为它会提高性能,您也可以尝试其他算法。

John Karmack 在 QuakeCon 2011 上做了一个主题演讲,他解释了整个过程,可能比我在一篇文章中解释得更好(以及其他很棒的事情),你可以在这里找到

于 2012-06-29T09:45:06.110 回答
3

压缩可以在许多不同的层上以多种方式发生,何时、何地以及如何使用它完全取决于它的目的和目标是什么(压缩并不总是与节省磁盘空间有关)。

基本上,在顶层,所有资产都将/可以压缩到批量存档中(这会加快读取速度,因为从 HDD 中读取的内容更少,但是您为此牺牲了处理能力,与使用 DMA读取未压缩的文件,根本不使用 CPU),回读几乎总是内存到内存,回读到 HDD 会破坏性能并导致许多问题(在某些情况下是不可能的,例如在老一代游戏机上)。

第二层可以/可以在资产本身上完成,例如,可以以多种不同方式压缩纹理,但目前主要使用块压缩(S3TC/DXTn,BCn),因为硬件(或由驱动程序模拟),因此当它读取存档/磁盘时,无需进行进一步的解压缩。

压缩策略也因平台而异,尤其是在对内存布局非常敏感、资源有限和缓存小等的控制台上。

在 c++ 中使用像 zlib(或任何其他)这样的库,这个运行时解压缩是如何完成的?

通常,您希望使用存档的内存映射文件并直接解压缩到 RAM,这是一个很好的 AAA 存档系统示例,它有据可查,它是MPQ 格式(暴雪娱乐使用,更多细节在这里),它使用各种压缩算法,例如暗黑破坏神 I 的 deflate、魔兽争霸 III 的 zlib、魔兽世界中的 bzip2,他们最近为 SCII 等新游戏添加了 LZ 和稀疏压缩。

Jan Wassenberg 的论文 ( Optimizing File Accesses via Ordering and Caching) 对文件管理进行了很好的细分,这可能也很有趣。

于 2012-06-29T09:29:17.763 回答
0

游戏引擎处理资产压缩

有不同的游戏引擎资产,例如几何模型(三角剖分/多边形模型)、纹理等。每个资产类别都有不同的压缩策略。你可以说得更详细点吗 ?

对于模型压缩,检查这个

于 2012-06-29T06:53:16.867 回答