Blockkomprimierung
Ab Windows 8.1 unterstützt Direct2D mehrere blockkomprimierte Pixelformate. Darüber hinaus enthält Windows 8.1 einen neuen WIC-DDS-Codec (Windows Imaging Component), um das Laden und Speichern von komprimierten Blockbildern im DDS-Dateiformat zu ermöglichen. Die Blockkomprimierung ist ein Verfahren zum Reduzieren des Grafikspeichers, der von Bitmapinhalten verbraucht wird. Durch die Blockkomprimierung kann Ihre App den Arbeitsspeicherverbrauch und die Ladezeiten für Bilder derselben Auflösung reduzieren. Oder Ihre App kann Bilder mit mehr oder höherer Auflösung verwenden und gleichzeitig denselben GPU-Speicherbedarf beanspruchen.
Die Blockkomprimierung wird seit langem von Direct3D-Anwendungen verwendet, und mit Windows 8.1 ist auch für Mainstream- und Direct2D-Anwendungsentwickler verfügbar.
In diesem Thema wird beschrieben, wie die Blockkomprimierung funktioniert und wie sie in WIC und Direct2D verwendet wird.
Informationen zur Blockkomprimierung
Blockkomprimierung (Block Compression, BC) bezieht sich auf eine Klasse von Komprimierungstechniken zum Reduzieren von Texturgrößen. Direct3D 11 unterstützt je nach Featureebene bis zu 7 verschiedene BC-Formate. In Windows 8.1 Direct2D die Unterstützung für die Formate BC1, BC2 und BC3 eingeführt, die für alle Featureebenen verfügbar sind.
Funktionsweise der Blockkomprimierung
Die komprimierten Formate des Blocks verwenden alle dasselbe grundlegende Verfahren, um den durch Farbdaten belegten Speicherplatz zu reduzieren. In diesem Abschnitt wird der einfachste Algorithmus BC1 zusammengefasst. Eine ausführlichere Erklärung finden Sie unter Blockieren der Komprimierung.
Zunächst ist das Bild in Blöcke mit 4 x 4 Pixel unterteilt. Jeder Block wird separat komprimiert.
Hinweis
Dies bedeutet, dass die Breite und Höhe eines Bilds jeweils ein Vielfaches von 4 Pixeln sein müssen, damit es komprimiert werden kann.
Dieses Beispielbild zeigt einen 4x4-Pixelblock in einem Bild.
Als Nächstes werden in einem 4 x 4-Block zwei "Verweis"-Farben ausgewählt und als zwei 16-Bit-Werte codiert (5 Bit rot, 6 Bit grün, 5 Bit blau). Die Wahl dieser Farben wirkt sich erheblich auf die Bildqualität aus und ist nichttrivial. Zwei Zwischenfarben werden durch lineare Interpolation zwischen den beiden Referenzfarben im RGB-Farbraum berechnet. Dies erzeugt insgesamt 4 verschiedene mögliche Farben; jeder Farbe wird ein Zwei-Bit-Indexwert zugewiesen. Beachten Sie jedoch, dass nur die beiden Endpunktfarben gespeichert werden müssen, wenn die Interpolation behoben ist.
In dieser Abbildung werden die Farben 0 und 3 als Referenzfarben für den Block ausgewählt, während die Farben 1 und 2 mithilfe der linearen Interpolation berechnet werden.
Schließlich wird jedes Pixel im Block einer der vier zuvor berechneten Farben zugeordnet, und jedes Pixel wird mithilfe des zwei Bitindexwerts codiert.
Die Gesamtmenge der Daten, die zur Darstellung dieser 16 Pixel verwendet wird, ist:
16 bits [to define a reference color] * 2 + 2 bits * 16 [number of pixels] = 64 bits
Dies ergibt eine durchschnittliche Dichte von 4 Bits pro Pixel. Zum Vergleich: Das gängige DXGI_FORMAT_B8G8R8A8_UNORM Pixelformat verbraucht 32 Bits pro Pixel.
Dieses Diagramm zeigt, dass jedes Pixel als 2-Bit-Index codiert ist. Der gesamte Block ist in 64 Bits codiert.
Es gibt Variationen zur Unterstützung von Alphadaten und unterschiedlicher Anzahl von Farbkanälen. BC6H und BC7 verwenden deutlich unterschiedliche Algorithmen, um HDR-Inhalte (High Dynamic Range) zu unterstützen und die Bildqualität zu erhöhen.
DirectDraw Surface (DDS)-Dateiformat
Komprimierte Daten blockieren werden in der Regel in DDS-Dateien (DirectDraw Surface) gespeichert. Möglicherweise sind Sie mit DDS-Dateien vertraut, wenn Sie ein Direct3D-Entwickler sind. Beachten Sie, dass Direct2D nur bestimmte DDS-Features unterstützt. Weitere Informationen finden Sie unter DDS-Anforderungen.
Vorteile der Blockkomprimierung
Komprimierte Blockformate unterscheiden sich von gängigen Bildkomprimierungsformaten der Industrie wie JPEG dadurch, dass BC-Formate von modernen GPUs nativ unterstützt werden. Dies bedeutet, dass Sie ein komprimiertes Blockbild direkt auf die GPU laden können, ohne zu decodieren oder zu dekomprimieren. BC-Formate verbrauchen durchschnittlich 4 bis 8 Bits pro Pixel; im Vergleich zu einer typischen unkomprimierten BGRA-Bitmap mit 32 Bit pro Pixel führt dies zu Speichereinsparungen von 75 % bis 87,5 %. Da es keinen Decodierungsschritt gibt, ist die Zeit zum Laden eines BC-Bilds im Vergleich zu Formaten wie JPEG erheblich reduziert.
Wann sollte die Blockkomprimierung verwendet werden?
Sie sollten die Verwendung komprimierter Blockbilder in Ihrer App anstelle anderer Formate wie JPEG in Erwägung ziehen, wenn Sie den Arbeitsspeicherverbrauch von Bitmaps reduzieren oder die Decodierungs- und Ladezeiten reduzieren möchten.
Die Blockkomprimierung ist jedoch nicht für alle Fälle geeignet und erfordert einige Kompromisse. Erstens sind die Blockkomprimierungsalgorithmen verlustbehaftet. Die Blockkomprimierung funktioniert gut mit natürlichen fotografischen Inhalten, kann jedoch unerwünschte visuelle Artefakte in Bilder mit scharfen, hohen Kontrastgrenzen einführen, z. B. computergenerierte Screenshots. Sie sollten sicherstellen, dass ihre komprimierten Bildressourcen des Blocks eine akzeptable Bildqualität aufweisen, bevor Sie sie verwenden.
Zweitens belegen komprimierte DDS-Dateien im Allgemeinen mehr Speicherplatz auf dem Datenträger als vergleichbare JPEG-Bilder. Dies wiederum erhöht die Paketgröße und Netzwerkbandbreitenanforderungen Ihrer App.
Verwenden der Blockkomprimierung
In diesem Abschnitt wird erläutert, wie Sie komprimierte Blockobjekte in einer Direct2D-App generieren und verwenden.
Übersicht
Blockkomprimierte DDS-Dateien sind ein laufzeitoptimiertes Format, was bedeutet, dass sie speziell für eine gute Leistung in der App-Runtime optimiert sind. Es wird empfohlen, die vorhandene Pipeline zum Erstellen und Bearbeiten von Ressourcen weiterhin zu verwenden und nur beim Importieren in ihr Anwendungsprojekt oder zur Erstellungszeit in ein komprimiertes Blockformat zu konvertieren.
DDS-Anforderungen
Das DDS-Dateiformat wurde entwickelt, um eine Vielzahl von Features zu unterstützen, die in Direct3D verwendet werden. Direct2D verwendet nur eine Teilmenge dieser Features. Wenn Sie DDS-Images für die Verwendung mit Direct2D erstellen, müssen Sie daher die folgenden Einschränkungen beachten:
- Nur die folgenden DXGI_FORMAT Werte sind zulässig:
- DXGI_FORMAT_BC1_UNORM
- DXGI_FORMAT_BC2_UNORM
- DXGI_FORMAT_BC3_UNORM
- Vormultiplizierte Alphadaten müssen verwendet werden. Dies umfasst Ältere DDS-Dateien, die Formate verwenden, die vormultipliziertes Alpha explizit definieren (DXT1, DXT2, DXT4), sowie DDS-Dateien, die die DDS_HEADER_DX10-Struktur mit den DDS_ALPHA_MODE_OPAQUE- und DDS_ALPHA_MODE_PREMULTIPLIED-Werten verwenden.
- Die X- und Y-Dimensionen müssen ein Vielfaches von 4 Pixeln aufweisen.
- Volumetexturen, Cubemaps, Mipmaps oder Texturarrays sind nicht zulässig. Sie sollten nur Einzelframe-Quellimages verwenden.
Generieren von komprimierten Blockobjekten
Es gibt eine Vielzahl von DDS-Erstellungstools, um blockkomprimierte DDS-Dateien zu erstellen oder zu konvertieren. Beachten Sie, dass nicht alle Tools die Anforderungen für die Verwendung von DDS-Dateien mit Direct2D unterstützen, wie im vorherigen Abschnitt beschrieben.
Ab Visual Studio 2013 kann Visual Studio vorhandene visuelle Ressourcen wie JPEG und PNG als automatischen Teil Des Buildprozesses in das richtige komprimierte DDS-Blockformat konvertieren. Dies wird mithilfe des benutzerdefinierten Buildschritts "Image Content Task" erreicht.
Informationen dazu, wie Sie dies für Ihr Projekt einrichten, finden Sie unter Vorgehensweise: Exportieren einer Textur für die Verwendung mit Direct2D- oder Javascipt-Apps.
Direct2D-APIs
Direct2D wird in Windows 8.1 aktualisiert, um die folgenden Pixelformate zu unterstützen:
- DXGI_FORMAT_BC1_UNORM
- DXGI_FORMAT_BC2_UNORM
- DXGI_FORMAT_BC3_UNORM
Für die obigen Formate müssen Sie vorab multipliziertes Alpha verwenden. Darüber hinaus sind diese Formate nur für die Verwendung als Quelle und nicht als Ziel gültig. Dies bedeutet beispielsweise, dass Sie eine Direct2D-Bitmap mit BC1, aber nicht mit einem Gerätekontext erstellen können.
Die folgenden Methoden werden in Windows 8.1 aktualisiert, um BC-Formate zu unterstützen:
- ID2D1DeviceContext::IsDxgiFormatSupported
- ID2D1DeviceContext::CreateBitmap
- ID2D1DeviceContext::CreateBitmapFromDxgiSurface
- ID2D1RenderTarget::CreateSharedBitmap
- ID2D1RenderTarget::CreateBitmapFromWicBitmap
- ID2D1Bitmap::CopyFromMemory
- ID2D1Bitmap::CopyFromBitmap
- ID2D1Bitmap1::GetSurface
Beachten Sie, dass CreateBitmapFromWicBitmapIWICBitmapSource als Schnittstelle verwendet. in Windows 8.1 wiC unterstützt jedoch nicht das Abrufen komprimierter Blockdaten aus IWICBitmapSource, und es gibt kein WIC-Pixelformat, das DXGI_FORMAT_BC1_UNORM usw. entspricht. Stattdessen bestimmt CreateBitmapFromWicBitmap, ob die IWICBitmapSource ein gültiger DDS IWICBitmapFrameDecode ist und lädt direkt die komprimierten Daten des Blocks. Sie können entweder explizit das Pixelformat in der D2D1_BITMAP_PROPERTIES1 Struktur angeben oder Direct2D erlauben, das richtige Format automatisch zu bestimmen.
ApIs für Windows-Bildverarbeitungskomponenten
Die Windows Imaging Component (WIC) fügt einen neuen DDS-Codec in Windows 8.1 hinzu. Darüber hinaus werden neue Schnittstellen hinzugefügt, die den Zugriff auf DDS-spezifische Daten unterstützen, einschließlich blockkomprimierter Pixeldaten:
Blockieren komprimierter WIC-Pixelformate
Es gibt keine neuen komprimierten Pixelformate des WIC-Blocks in Windows 8.1. Wenn Sie stattdessen einen IWICBitmapFrameDecode vom DDS-Decoder abrufen und CopyPixels aufrufen, erhalten Sie nicht komprimierte Standardpixel wie WICPixelFormat32bppPBGRA. Sie können IWICDdsFrameDecode::CopyBlocks verwenden, um die komprimierten Rohdaten des Blocks in Form eines Speicherpuffers aus einer DDS-Datei abzurufen.
Multiframe-DDS-Zugriff
Das DDS-Dateiformat ermöglicht es, mehrere verwandte Bilder in einer einzigen Datei zu speichern. Beispielsweise kann eine DDS-Datei eine Cubemap, Eine Volumetextur oder ein Texturarray enthalten, die alle mipmapped sein können. In Direct3D werden diese mehrere Bilder als Unterressourcen verfügbar gemacht. In WIC werden mehrere Bilder als Frames (IWICBitmapFrameDecode und IWICBitmapFrameEncode) verfügbar gemacht.
WIC unterstützt nur das Konzept eines eindimensionalen Arrays von Frames, während DDS drei unabhängige Dimensionen unterstützt (obwohl nur zwei in einer Datei verwendet werden können). WIC bietet praktische Methoden zur Unterstützung der Zuordnung zwischen einer DDS-Unterquelle und einem WIC-Frame. Zum Decodieren können Sie mit IWICDdsDecoder::GetFrame den Arrayindex, die MIP-Ebene und den Sliceindex der Unterressource angeben und den richtigen WIC-Frame zurückgeben.
Für die Codierung berechnet IWICDdsEncoder::CreateNewFrame den resultierenden Arrayindex, die MIP-Ebene und den Sliceindex, wenn Sie einen neuen Frame erstellen. Sie müssen zuerst IWICDdsEncoder::SetParameters aufgerufen haben, um die DDS-spezifischen Dateiparameter zu definieren.
Zugehörige Themen