區塊壓縮
從 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 到 4 圖元的區塊。 每個區塊會個別壓縮。
注意
這表示影像的寬度和高度都必須是 4 圖元的倍數,才能進行區塊壓縮。
此範例影像顯示影像內的 4x4 圖元區塊。
接下來,在 4 到 4 區塊內,會選取兩個「參考」色彩,並以兩個 16 位值編碼, (5 位紅色、6 位綠色、5 位藍色) 。 這些色彩的選擇會大幅影響影像品質,而且是非Trivial。 兩種中繼色彩的計算方式是線性插補 RGB 色彩空間中的兩個參考色彩。 這總共會產生 4 種不同的可能色彩;每個色彩都會指派兩個位索引值。 不過請注意,只有兩個端點色彩需要儲存為固定插補。
在此圖中,色彩 0 和 3 會選取為區塊的「參考」色彩,而色彩 1 和 2 則是使用線性插補來計算。
最後,區塊中的每個圖元都會對應到四個先前計算色彩的其中一個,而每個圖元都會使用兩個位索引值進行編碼。
用來表示這些 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 位編碼。
有各種變化可支援 Alpha 資料和不同數目的色板。 BC6H 和 BC7 使用明顯不同的演算法,以支援高動態範圍 (HDR) 內容,並分別提高影像品質。
DirectDraw Surface (DDS) 檔案格式
區塊壓縮的資料通常會儲存在 DirectDraw Surface (DDS) 檔案中。 如果您是 Direct3D 開發人員,您可能已熟悉 DDS 檔案。 請注意,Direct2D 僅支援特定 DDS 功能;如需詳細資訊,請參閱 DDS 需求。
區塊壓縮的優點
區塊壓縮格式與常見的產業影像壓縮格式不同,例如 BC 格式的 JPEG 是由新式 GPU 原生支援。 這表示您可以直接將區塊壓縮的影像載入 GPU,而不需要任何解碼或解壓縮。 BC 格式平均每圖元取用 4 到 8 位;相較于一般未壓縮的每個圖元 BGRA 點陣圖 32 位,這會導致記憶體節省 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_HEADER_DX10搭配DDS_ALPHA_MODE_OPAQUE和DDS_ALPHA_MODE_PREMULTIPLIED值的 DDS 檔案。
- X 和 Y 維度必須是 4 圖元的倍數。
- 不允許磁片區紋理、Cubemap、Mipmap 或紋理陣列。 您應該只使用單一畫面來源影像。
產生區塊壓縮資產
有各種不同的 DDS 撰寫工具可用來建立或轉換區塊壓縮的 DDS 檔案。 請注意,並非所有工具都支援搭配 Direct2D 使用 DDS 檔案的需求,如上一節所述。
從Visual Studio 2013開始,您可以讓 Visual Studio 將現有的視覺資產,例如 JPEG 和 PNG 轉換成正確的 DDS 區塊壓縮格式,作為建置程式的自動部分。 這是使用影像內容工作自訂建置步驟來完成的。
如需如何為您的專案設定此專案的資訊,請參閱: 如何:匯出紋理以搭配 Direct2D 或 JAVAscipt Apps 使用。
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 格式:
- ID2D1DeviceCoNtext::IsDxgiFormatSupported
- ID2D1DeviceCoNtext::CreateBitmap
- ID2D1DeviceCoNtext::CreateBitmapFromDxgiSurface
- ID2D1RenderTarget::CreateSharedBitmap
- ID2D1RenderTarget::CreateBitmapFromWicBitmap
- ID2D1Bitmap::CopyFromMemory
- ID2D1Bitmap::CopyFromBitmap
- ID2D1Bitmap1::GetSurface
請注意,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 檔案可能包含 Cubemap、磁片區紋理或紋理陣列,而這些陣列都可以被 mipmapped。 在 Direct3D 中,這些多個映射會公開為子資源。 在 WIC 中,多個影像會公開為 IWICBitmapFrameDecode 和 IWICBitmapFrameEncode) (畫面格。
WIC 僅支援框架單一維度陣列的概念,而 DDS 支援三個獨立維度 (,不過任一檔案) 只能使用兩個。 WIC 提供方便的方法,可協助進行 DDS 子資源與 WIC 框架之間的對應。 針對解碼, IWICDdsDecoder::GetFrame 可讓您指定子資源的陣列索引、mip 層級和配量索引,並傳回正確的 WIC 框架。
為了編碼, IWICDdsEncoder::CreateNewFrame 會在您建立新框架時計算產生的陣列索引、mip 層級和配量索引。 您必須先呼叫 IWICDdsEncoder::SetParameters ,才能定義 DDS 特定的檔案參數。
相關主題