块压缩

从 Windows 8.1 开始,Direct2D 支持多种块压缩像素格式。 此外,Windows 8.1包含新的 Windows 图像处理组件 (WIC) DDS 编解码器,以 DDS 文件格式加载和存储块压缩图像。 块压缩是一种减少位图内容消耗的图形内存量的技术。 通过使用块压缩,应用可以减少相同分辨率图像的内存消耗和加载时间。 或者,你的应用可以使用更多或更高分辨率的图像,同时仍占用相同的 GPU 内存。

块压缩已被 Direct3D 应用程序使用很长时间,并且具有 Windows 8.1也可供主流和 Direct2D 应用程序开发人员使用。

本主题介绍块压缩的工作原理,以及如何在 WIC 和 Direct2D 中使用它。

关于块压缩

块压缩 (BC) 是指用于减小纹理大小的一类压缩技术。 Direct3D 11 最多支持 7 种不同的 BC 格式,具体取决于功能级别。 在 Windows 8.1 Direct2D 引入了对 BC1、BC2 和 BC3 格式的支持,这些格式在所有功能级别上都可用。

块压缩的工作原理

块压缩格式都使用相同的基本技术来减少颜色数据占用的空间。 本节总结了最简单的算法 BC1。 有关更详细的说明,请参阅 块压缩

首先,图像分为 4 x 4 像素的块。 每个块单独压缩。

注意

这意味着图像的宽度和高度都必须是 4 像素的倍数才能被块压缩。

 

此示例图像显示了图像中的一个 4x4 像素块。

示例图像显示了图像中的一个 4x4 像素块。

接下来,在 4 乘 4 块中,选择两个“参考”颜色,并将其编码为两个 16 位值 (5 位红色、6 位绿色、5 位蓝色) 。 这些颜色的选择会显著影响图像质量,并且是非琐碎的。 通过在 RGB 颜色空间中的两种参考颜色之间线性内插来计算两种中间颜色。 这总共产生 4 种不同的可能颜色:每种颜色都分配有一个两位索引值。 但请注意,在内插固定时,只需要存储两种端点颜色。

在此图中,颜色 0 和 3 被选为块的“参考”颜色,而颜色 1 和 2 是使用线性内插计算的。

显示计算 4 个颜色值以表示块的示意图。

最后,块中的每个像素都映射到先前计算的四种颜色之一,并且每个像素使用两位索引值进行编码。

用于表示这 16 个像素的数据总量为:

16 bits [to define a reference color] * 2 + 2 bits * 16 [number of pixels] = 64 bits

这会导致每个像素的平均密度为 4 位。 为了进行比较,常见的DXGI_FORMAT_B8G8R8A8_UNORM像素格式每像素消耗 32 位。

此图显示每个像素编码为 2 位索引。 整个块以 64 位编码。

计算 4 个颜色值来表示块。

有一些变体支持 alpha 数据和不同数量的颜色通道。 BC6H 和 BC7 使用明显不同的算法,分别支持高动态范围 (HDR) 内容并提高图像质量。

DirectDraw Surface (DDS) 文件格式

块压缩数据通常存储在 DirectDraw Surface (DDS) 文件中。 如果你是 Direct3D 开发人员,你可能熟悉 DDS 文件。 请注意,Direct2D 仅支持某些 DDS 功能;有关详细信息,请参阅 DDS 要求

块压缩的优点

块压缩格式不同于常见的行业图像压缩格式(如 JPEG),因为 BC 格式由新式 GPU 本机支持。 这意味着,无需任何解码或解压缩即可将块压缩图像直接加载到 GPU 上。 BC 格式平均每像素消耗 4 到 8 位;与典型的未压缩的每像素 32 位 BGRA 位图相比,这可以节省 75% 到 87.5% 的内存。 此外,由于没有解码步骤,因此与 JPEG 等格式相比,加载 BC 图像的时间显著缩短。

何时使用块压缩

如果要减少位图的内存消耗或希望减少解码和加载时间,应考虑在应用中使用块压缩图像,而不是 JPEG 等其他格式。

但是,块压缩并非适用于所有情况,需要一些权衡。 首先,块压缩算法是有损的。 块压缩适用于自然摄影内容,但可能会将不需要的视觉伪像引入具有清晰、高对比度边界的图像中,例如计算机生成的屏幕截图。 在使用块压缩图像资产之前,应确保其图像质量可接受。

其次,块压缩的 DDS 文件通常比类似的 JPEG 映像消耗更多的磁盘空间。 这反过来会增加应用的包大小和网络带宽要求。

使用块压缩

本部分介绍如何在 Direct2D 应用中生成和使用块压缩资产。

概述

块压缩的 DDS 文件是运行时优化的格式,这意味着它们经过专门优化,以便在应用运行时获得良好的性能。 建议继续使用现有资产创建和编辑管道,仅在将资产导入应用程序项目或在生成时将其转换为块压缩格式。

DDS 要求

DDS 文件格式旨在支持 Direct3D 中使用的各种功能。 Direct2D 仅使用这些功能的子集。 因此,在创建用于 Direct2D 的 DDS 映像时,必须记住以下限制:

  • 仅允许以下 DXGI_FORMAT 值:
    • DXGI_FORMAT_BC1_UNORM
    • DXGI_FORMAT_BC2_UNORM
    • DXGI_FORMAT_BC3_UNORM
  • 必须使用预乘的 alpha 数据。 这包括使用显式定义预乘 alpha (DXT1、DXT2、DXT4) 的格式的旧 DDS 文件,以及使用具有DDS_ALPHA_MODE_OPAQUE和DDS_ALPHA_MODE_PREMULTIPLIED值的DDS_HEADER_DX10结构的 DDS 文件。
  • X 和 Y 尺寸必须是 4 像素的倍数。
  • 不允许使用体积纹理、立方体贴图、mipmap 或纹理数组。 应仅使用单帧源图像。

生成块压缩资产

有多种 DDS 创作工具可用于创建或转换块压缩的 DDS 文件。 请注意,并非所有工具都支持将 DDS 文件与 Direct2D 配合使用的要求,如上一部分所述。

从 Visual Studio 2013 开始,你可以让 Visual Studio 将现有的视觉资产(如 JPEG 和 PNG)转换为正确的 DDS 块压缩格式,作为生成过程的自动部分。 这是使用图像内容任务自定义生成步骤完成的。

有关如何为项目设置此功能的信息,请参阅: 如何:导出纹理以用于 Direct2D 或 Javascipt 应用

Direct2D API

Direct2D 在 Windows 8.1 中进行了更新,以支持以下像素格式:

  • DXGI_FORMAT_BC1_UNORM
  • DXGI_FORMAT_BC2_UNORM
  • DXGI_FORMAT_BC3_UNORM

对于上述格式,必须使用预乘 alpha。 此外,这些格式仅有效用作源,不能用作目标。 例如,这意味着可以使用 BC1 创建 Direct2D 位图,但不能创建设备上下文。

Windows 8.1中更新了以下方法以支持 BC 格式:

请注意,CreateBitmapFromWicBitmap 采用 IWICBitmapSource 作为接口;但在 Windows 8.1 WIC 不支持从 IWICBitmapSource 获取块压缩数据,并且没有对应于DXGI_FORMAT_BC1_UNORM等的 WIC 像素格式。相反,CreateBitmapFromWicBitmap 确定 IWICBitmapSource 是否为有效的 DDS IWICBitmapFrameDecode,并直接加载块压缩的数据。 可以在 D2D1_BITMAP_PROPERTIES1 结构中显式指定像素格式,或者允许 Direct2D 自动确定正确的格式。

Windows 映像组件 API

Windows 图像处理组件 (WIC) 在 Windows 8.1 中添加了一个新的 DDS 编解码器。 此外,它还添加了支持访问 DDS 特定数据(包括块压缩像素数据)的新接口:

阻止压缩的 WIC 像素格式

Windows 8.1中没有新的 WIC 块压缩像素格式。 相反,如果从 DDS 解码器获取 IWICBitmapFrameDecode 并调用 CopyPixels,则会收到标准未压缩像素,例如 WICPixelFormat32bppPBGRA。 可以使用 IWICDdsFrameDecode::CopyBlocks 从 DDS 文件中获取内存缓冲区形式的原始块压缩数据。

多帧 DDS 访问

DDS 文件格式允许将多个相关图像存储在单个文件中。 例如,DDS 文件可能包含立方体贴图、体积纹理或纹理数组,所有这些都可能被误用。 在 Direct3D 中,这些多个图像作为子资源公开。 在 WIC 中,多个图像作为帧 (IWICBitmapFrameDecodeIWICBitmapFrameEncode) 公开。

WIC 仅支持一维帧数组的概念,而 DDS 支持三个独立维度 (尽管在任意一个文件) 中只能使用两个独立维度。 WIC 提供了方便的方法来帮助在 DDS 子资源与 WIC 帧之间进行映射。 对于解码, IWICDdsDecoder::GetFrame 允许指定子资源的数组索引、mip 级别和切片索引,并返回正确的 WIC 帧。

对于编码, IWICDdsEncoder::CreateNewFrame 会在创建新帧时计算生成的数组索引、mip 级别和切片索引。 必须首先调用 IWICDdsEncoder::SetParameters 来定义特定于 DDS 的文件参数。

如何:导出纹理以用于 Direct2D 或 Javascipt 应用

DDS 参考

块压缩