點陣圖區塊壓縮

CanvasBitmap 支援區塊壓縮位圖。 這些檔案可以從 DDS 檔案載入,或用 CreateFromBytes(ICanvasResourceCreator,Byte[], Int32, Int32, DirectXPixelFormat)建立。

區塊壓縮位圖非常適合位圖密集的應用(如遊戲),因為它們佔用的記憶體較少,且繪製效率更高。 區塊壓縮位圖所需的記憶體最多只有未壓縮位圖的 1/8。 因此,GPU 在繪製點陣圖時需要存取的記憶體大幅減少,繪製速度更快。

關於區塊壓縮

區塊壓縮與 PNG 或 JPG 檔案所採用的壓縮不同。 壓縮檔案格式雖然是以壓縮狀態儲存,但當被 Win2D 載入時,會解壓縮為使用如 DirectXPixelFormat::B8G8R8A8UIntNormalized 這類格式的點陣圖,而這種格式每個像素使用 32 位元(4 位元組)。 所以一個 256x256 位元圖會佔用 256 * 256 * 4 = 262,144 位元組。

區塊壓縮點陣圖使用8或16位元組(視格式而定——稍後會詳細說明)來儲存一個4x4像素的區塊。 因此,在這種情況下,一個 256x256 位元圖會佔用 256 * 256 / (4 * 4) * 8 = 32,768 位元組,或 256 * 256 / (4 * 4) * 16 = 65,536 位元組。 尺寸最多可縮小 8 倍! 由於區塊壓縮由 GPU 硬體直接支援,位圖可以保持在記憶體中壓縮,並直接從壓縮格式繪製,而無需完全解壓。

Win2D 支援三種區塊壓縮格式。 下表說明這些格式,並附有一個未壓縮格式供比較。

DirectXPixelFormat 4x4 位圖的尺寸 256x256 點陣圖的尺寸 Alpha
BC1Unorm 8 個字節 32,768 位元組 1位元
BC2Unorm 16 個字節 65,536 位元組 4位元
BC3Unorm 16 個字節 65,536 位元組 ~8位元(壓縮)
B8G8R8A8UintNormalized 64 位元組 262,144 位元組 8位元

BC1Unorm BC2Unorm BC3Unorm主要差異在於它們支援 alpha 的方式。 BC1 僅支援 1 位元 alpha。 BC2 支援區塊中每個像素擁有獨特的 4 位元 alpha 值。 BC3 會壓縮 Alpha 值。

欲了解更多區塊壓縮的運作方式,請參閱 Direct2D 區塊壓縮文件Direct3D 區塊壓縮文件

Restrictions

  • 所有區塊壓縮材質的寬度和高度必須是 4 的倍數。 這是因為區塊壓縮適用於 4x4 像素的區塊。
  • 對區塊壓縮紋理的子矩形進行任何操作(使用 GetPixelBytes()SetPixelBytes(Byte[])CopyPixelsFromBitmap(CanvasBitmap, Int32, Int32))時,都要求該子矩形按 4 像素對齊。
  • Win2D 在使用區塊壓縮格式時需要預先乘法 alpha。

撰寫 DDS 檔案

區塊壓縮的影像可以儲存在 DDS 檔案中。 雖然這些檔案可透過 Photoshop 或 Paint.NET 等應用程式的外掛產生,但必須注意確保產生的檔案以預先乘法的 alpha 格式儲存。 Win2D 會載入任何包含 BC1UnormBC2UnormBC3Unorm 影像的 DDS 檔案,並假設該檔案是以預乘 Alpha 方式建立。

如果你正在撰寫 C++ 專案,可以使用影像內容管線(Image Content Pipeline)來轉換影像,如 Visual Studio 文件中所述。

或者,您也可以使用來自 https://github.com/Microsoft/DirectXTextexconv.exetexconv.exe 可以用DirectXTex_Desktop_2015.sln解來建構。 以下指令會將「smoke.png」轉換成具有預乘 alpha 的 BC3Unorm 影像:

texconv -pmalpha -m 1 -f BC3_UNORM smoke.png