4

好的,所以我正在尝试权衡使用各种不同纹理压缩技术的利弊。我花费了 99.999% 的时间为使用 DirectX 的 Windows 机器编写 2D sprite 游戏。

到目前为止,我已经研究了带有 alpha-trimming 的纹理打包(SpriteSheets),这似乎是一种获得更多性能的好方法。现在我开始研究它们存储的纹理格式;目前所有内容都存储为 *.PNG。

我听说 *.DDS 文件很好,尤其是与 DXT5(/3/1,取决于任务)压缩一起使用时,因为纹理在 VRAM 中保持压缩?人们还说,由于它们已经是 DirectDraw 表面,因此它们的加载速度也快得多。

所以我创建了一个应用程序来测试它;我调用了 20 次以下的行,在每次调用之间释放纹理。

    for (int i = 0; i < 20; i++)
 {
  if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"Test.dds", &g_pTexture ) ) )
  {
   return E_FAIL;
  }

  g_pTexture->Release();
  g_pTexture = NULL;
 }

现在,如果我使用 DXT5 纹理尝试此操作,完成时间比加载简单 *.PNG 的时间长 5 倍。我听说如果你不生成 Mipmap,它会变慢,所以我仔细检查了一遍。然后我更改了用于生成 *.DDS 文件的程序,切换到 NVIDIA 自己的 nvcompress.exe,但没有任何效果。

编辑:我忘了提到文件(*.png 和 *.dds)都是相同的图像,只是以不同的格式保存。(相同的大小,alpha 的数量,一切!)

编辑 2:当使用以下参数时,它的加载速度几乎快了 2.5 倍,并且消耗的 VRAM 更少!

 D3DXCreateTextureFromFileEx( g_pd3dDevice, L"Test.dds", D3DX_DEFAULT_NONPOW2, D3DX_DEFAULT_NONPOW2, D3DX_FROM_FILE, 0, D3DFMT_FROM_FILE, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_FILTER_NONE, 0, NULL, NULL, &g_pTexture )

但是,我现在失去了纹理中的所有透明度,我查看了 DXT5 纹理,它在 Paint.NET 和 DirectX DDS 查看器中看起来很好。但是,当加载所有透明度时,会变成纯黑色。颜色键问题?

编辑 3:忽略最后一点,我很愚蠢,在我的“快速示例”中,我忘记在 D3DXSprite->Begin() 上启用 Alpha-Blending。嗬!

4

2 回答 2

14

您需要区分文件存储在磁盘上的格式和纹理最终在视频内存中使用的格式。DXT 压缩纹理在显存中的内存使用和质量之间提供了良好的平衡,但其他压缩技术(如 PNG 或 Jpeg 压缩)通常会导致更小的文件和/或更好的磁盘质量。

DDS 文件的优点是它们直接支持 DXT 格式,并且在磁盘上的布局方式与 DirectX 期望数据在内存中布局的方式相同,因此在加载它们后将它们转换为格式所需的 CPU 时间最少硬件可以使用。它们还支持 PNG 等格式不支持的预生成的 mipmap 链。将图像压缩为 DXT 格式是一个相当耗时的过程,因此您通常希望尽可能避免在加载时执行此操作。

具有与您计划从中创建的视频内存纹理相同大小并使用相同格式的预生成 mipmap 的 DDS 文件将使用任何标准格式的最少 CPU 时间。您需要确保告诉 D3DX 不要执行任何缩放、过滤、格式转换或 mipmap 生成以保证这一点。D3DXCreateTextureFromFileEx允许您指定防止发生任何内部转换的标志(D3DX_DEFAULT_NONPOW2如果您的硬件支持两个纹理的非幂次,则用于图像宽度和高度,D3DFMT_FROM_FILE以防止 mipmap 生成或格式转换,D3DX_FILTER_NONE以防止任何过滤或缩放)。

CPU时间只是故事的一半。如今,CPU 速度非常快,而硬盘驱动器相对较慢,因此有时如果您加载较小的压缩文件格式(如 PNG 或 JPG),然后执行大量 CPU 工作来转换它,而不是加载较大的文件,您的总加载时间可能会更短像 DDS 一样,只需对视频内存进行 memcpy。提供良好结果的一种常见方法是压缩 DDS 文件并解压缩它们,以便从磁盘快速加载并最小化格式转换的 CPU 成本。

PNG 和 JPG 等压缩格式会比其他压缩格式更有效地压缩某些图像。DDS 是一个固定的压缩比——给定的图像分辨率和格式总是会压缩到相同的大小(这就是为什么它更适合在硬件中解压缩)。如果您使用简单的非代表性图像进行测试(例如,统一的颜色或简单的图案),那么您的 PNG 文件可能非常小,因此从磁盘加载的速度比典型的游戏图像要快。

于 2009-09-22T23:31:45.033 回答
1

比较加载标准 PNG,然后将其压缩到加载 DDS 文件所需的时间。

我仍然不明白为什么 PNG 会比压缩的相同纹理 DXT5 加载更快。一方面它会小一点,所以它应该更快地从磁盘加载!这个 DXt5 纹理和 PNG 纹理一样吗?即它们的大小相同吗?

你试过玩 D3DXCreateTextureFromFileEx 吗?你对正在发生的事情有更多的控制权。它可能会帮助你。

于 2009-09-22T19:45:45.260 回答