Blockkomprimierung (Direct3D 10)

Die Blockkomprimierung ist ein Verfahren zur Texturkomprimierung zum Reduzieren der Texturgröße. Im Vergleich zu einer Textur mit 32 Bits pro Farbe kann eine blockkomprimierte Textur bis zu 75 Prozent kleiner sein. Anwendungen sehen in der Regel eine Leistungssteigerung bei verwendung der Blockkomprimierung aufgrund des geringeren Arbeitsspeicherbedarfs.

Obwohl verlustbehaftet, funktioniert die Blockkomprimierung gut und wird für alle Texturen empfohlen, die von der Pipeline transformiert und gefiltert werden. Texturen, die direkt dem Bildschirm zugeordnet sind (UI-Elemente wie Symbole und Text), sind keine gute Wahl für die Komprimierung, da Artefakte auffälliger sind.

Eine blockkomprimierte Textur muss als Vielfaches der Größe 4 in allen Dimensionen erstellt werden und kann nicht als Ausgabe der Pipeline verwendet werden.

Wie funktioniert die Blockkomprimierung?

Die Blockkomprimierung ist ein Verfahren zum Reduzieren des zum Speichern von Farbdaten erforderlichen Arbeitsspeichers. Indem Sie einige Farben in ihrer ursprünglichen Größe und andere Farben mithilfe eines Codierungsschemas speichern, können Sie den Speicherplatz erheblich reduzieren, der zum Speichern des Bilds erforderlich ist. Da die Hardware komprimierte Daten automatisch decodiert, gibt es keine Leistungseinbußen für die Verwendung komprimierter Texturen.

Sehen Sie sich die folgenden beiden Beispiele an, um zu sehen, wie die Komprimierung funktioniert. Das erste Beispiel beschreibt die Menge an Arbeitsspeicher, die beim Speichern nicht komprimierter Daten verwendet wird. Das zweite Beispiel beschreibt die Menge an Arbeitsspeicher, die beim Speichern komprimierter Daten verwendet wird.

Speichern nicht komprimierter Daten

Die folgende Abbildung stellt eine nicht komprimierte 4×4-Textur dar. Angenommen, jede Farbe enthält eine einzelne Farbkomponente (rot für instance) und wird in einem Byte Arbeitsspeicher gespeichert.

Abbildung einer unkomprimierten 4x4-Textur

Die nicht komprimierten Daten werden sequenziell im Arbeitsspeicher angeordnet und erfordern 16 Bytes, wie in der folgenden Abbildung gezeigt.

Abbildung nicht komprimierter Daten im sequenziellen Arbeitsspeicher

Speichern komprimierter Daten

Nachdem Sie nun gesehen haben, wie viel Arbeitsspeicher ein nicht komprimiertes Image benötigt, sehen Sie sich an, wie viel Arbeitsspeicher ein komprimiertes Image speichert. Das BC4-Komprimierungsformat speichert 2 Farben (jeweils 1 Byte) und 16 3-Bit-Indizes (48 Bits oder 6 Bytes), die verwendet werden, um die ursprünglichen Farben in der Textur zu interpolieren, wie in der folgenden Abbildung gezeigt.

Abbildung des bc4-Komprimierungsformats

Der zum Speichern der komprimierten Daten erforderliche Gesamtspeicherplatz beträgt 8 Bytes, was eine Speichereinsparung von 50 Prozent gegenüber dem nicht komprimierten Beispiel darstellt. Die Einsparungen sind noch größer, wenn mehr als eine Farbkomponente verwendet wird.

Die erheblichen Speichereinsparungen durch die Blockkomprimierung können zu einer Leistungssteigerung führen. Diese Leistung geht auf Kosten der Bildqualität (aufgrund der Farbinterpolation); die geringere Qualität fällt jedoch häufig nicht auf.

Im nächsten Abschnitt erfahren Sie, wie Direct3D 10 die Verwendung der Blockkomprimierung in Ihrer Anwendung vereinfacht.

Verwenden der Blockkomprimierung

Erstellen Sie eine blockkomprimierte Textur genau wie eine nicht komprimierte Textur (siehe Erstellen einer Textur aus einer Datei), mit der Ausnahme, dass Sie ein blockkomprimiertes Format angeben.

loadInfo.Format = DXGI_FORMAT_BC1_UNORM;
D3DX10CreateTextureFromFile(...);

Erstellen Sie als Nächstes eine Ansicht, um die Textur an die Pipeline zu binden. Da eine blockkomprimierte Textur nur als Eingabe für eine Shaderphase verwendet werden kann, möchten Sie eine Shaderressourcensicht erstellen, indem Sie CreateShaderResourceView aufrufen.

Verwenden Sie eine blockkomprimierte Textur auf die gleiche Weise wie eine nicht komprimierte Textur. Wenn Ihre Anwendung einen Speicherzeiger auf blockkomprimierte Daten erhält, müssen Sie die Speicherfüllung in einer Mipmap berücksichtigen, die dazu führt, dass die deklarierte Größe von der tatsächlichen Größe abweicht.

Virtuelle Größe im Vergleich zur physischen Größe

Wenn Sie über Anwendungscode verfügen, der einen Speicherzeiger verwendet, um den Arbeitsspeicher einer komprimierten Blocktextur zu durchlaufen, gibt es einen wichtigen Aspekt, der möglicherweise eine Änderung im Anwendungscode erfordert. Eine blockkomprimierte Textur muss in allen Dimensionen ein Vielfaches von 4 sein, da die Blockkomprimierungsalgorithmen mit 4x4-Texelblöcken arbeiten. Dies ist ein Problem für eine Mipmap, deren anfängliche Dimensionen durch 4 teilbar sind, unterteilte Ebenen jedoch nicht. Das folgende Diagramm zeigt den Unterschied im Bereich zwischen der virtuellen (deklarierten) Größe und der physischen (tatsächlichen) Größe der einzelnen mipmap-Ebene.

Diagramm der nicht komprimierten und komprimierten Mipmap-Ebenen

Die linke Seite des Diagramms zeigt die mipmap-Ebenengrößen, die für eine nicht komprimierte 60×40-Textur generiert werden. Die Größe der obersten Ebene wird dem API-Aufruf entnommen, der die Textur generiert. jede nachfolgende Ebene ist halb so groß wie die vorherige Ebene. Bei einer nicht komprimierten Textur gibt es keinen Unterschied zwischen der virtuellen (deklarierten) Größe und der physischen (tatsächlichen) Größe.

Die rechte Seite des Diagramms zeigt die mipmap-Ebenengrößen, die für dieselbe 60×40-Textur mit Komprimierung generiert werden. Beachten Sie, dass sowohl die zweite als auch die dritte Ebene über Speicherauffüllung verfügen, um die Größenfaktoren von 4 auf jeder Ebene zu machen. Dies ist notwendig, damit die Algorithmen auf 4×4 Texelblöcken arbeiten können. Dies ist besonders offensichtlich, wenn Sie Mipmap-Ebenen berücksichtigen, die kleiner als 4×4 sind; die Größe dieser sehr kleinen Mipmap-Ebenen wird auf den nächsten Faktor 4 aufgerundet, wenn Texturspeicher zugewiesen wird.

Die Stichprobenhardware verwendet die virtuelle Größe. wenn die Textur stichprobeniert wird, wird die Speicherfüllung ignoriert. Bei Mipmap-Ebenen, die kleiner als 4×4 sind, werden nur die ersten vier Texels für eine 2×2-Karte verwendet, und nur der erste Texel wird von einem 1×1-Block verwendet. Es gibt jedoch keine API-Struktur, die die physische Größe (einschließlich des Speicherraums) verfügbar macht.

Zusammenfassend kann man also darauf achten, beim Kopieren von Regionen, die blockkomprimierte Daten enthalten, ausgerichtete Speicherblöcke zu verwenden. Um dies in einer Anwendung zu tun, die einen Speicherzeiger abruft, stellen Sie sicher, dass der Zeiger die Surface Pitch verwendet, um die größe des physischen Arbeitsspeichers zu berücksichtigen.

Komprimierungsalgorithm

Blockkomprimierungstechniken in Direct3D unterteilen unkomprimierte Texturdaten in 4×4 Blöcke, komprimieren jeden Block und speichern dann die Daten. Aus diesem Grund müssen Texturen, von denen erwartet wird, dass sie komprimiert werden, Texturdimensionen aufweisen, die ein Vielfaches von 4 sind.

Diagramm der Blockkomprimierung

Das obige Diagramm zeigt eine Textur, die in Texelblöcke unterteilt ist. Der erste Block zeigt das Layout der 16 Texel mit der Bezeichnung a-p, aber jeder Block hat die gleiche organization von Daten.

Direct3D implementiert mehrere Komprimierungsschemas, von denen jedes einen anderen Kompromiss zwischen der Anzahl der gespeicherten Komponenten, der Anzahl der Bits pro Komponente und der Menge des verbrauchten Arbeitsspeichers implementiert. Verwenden Sie diese Tabelle, um das Format auszuwählen, das am besten mit dem Datentyp und der Datenauflösung funktioniert, die am besten zu Ihrer Anwendung passt.

Quelldaten Datenkomprimierungsauflösung (in Bits) Wählen Sie dieses Komprimierungsformat aus.
Drei-Komponenten-Farbe und Alpha Farbe (5:6:5), Alpha (1) oder kein Alpha BC1
Drei-Komponenten-Farbe und Alpha Farbe (5:6:5), Alpha (4) BU2
Drei-Komponenten-Farbe und Alpha Farbe (5:6:5), Alpha (8) BC3
Ein-Komponenten-Farbe Eine Komponente (8) BC4
Zwei-Komponenten-Farbe Zwei Komponenten (8:8) BC5

 

BC1

Verwenden Sie das erste Blockkomprimierungsformat (BC1) (entweder DXGI_FORMAT_BC1_TYPELESS, DXGI_FORMAT_BC1_UNORM oder DXGI_BC1_UNORM_SRGB), um Farbdaten mit drei Komponenten unter Verwendung einer 5:6:5-Farbe (5 Bits rot, 6 Bit grün, 5 Bit blau) zu speichern. Dies gilt auch dann, wenn die Daten auch 1-Bit-Alpha enthalten. Bei einer 4×4-Textur mit dem größtmöglichen Datenformat reduziert das BC1-Format den erforderlichen Arbeitsspeicher von 48 Bytes (16 Farben × 3 Komponenten/Farbe × 1 Byte/Komponente) auf 8 Bytes Arbeitsspeicher.

Der Algorithmus funktioniert auf 4×4 Blöcken von Texels. Anstatt 16 Farben zu speichern, speichert der Algorithmus 2 Referenzfarben (color_0 und color_1) und 16 2-Bit-Farbindizes (Blöcke a–p), wie im folgenden Diagramm gezeigt.

Diagramm des Layouts für die bc1-Komprimierung

Die Farbindizes (a–p) werden verwendet, um die ursprünglichen Farben aus einer Farbtabelle nachzuschlagen. Die Farbtabelle enthält 4 Farben. Die ersten beiden Farben – color_0 und color_1 – sind die minimalen und maximalen Farben. Die beiden anderen Farben, color_2 und color_3, sind Zwischenfarben, die mit linearer Interpolation berechnet werden.

color_2 = 2/3*color_0 + 1/3*color_1
color_3 = 1/3*color_0 + 2/3*color_1

Den vier Farben sind 2-Bit-Indexwerte zugewiesen, die in den Blöcken a–p gespeichert werden.

color_0 = 00
color_1 = 01
color_2 = 10
color_3 = 11

Schließlich werden alle Farben in den Blöcken a bis p mit den vier Farben in der Farbtabelle verglichen, und der Index für die nächstgelegene Farbe wird in den 2-Bit-Blöcken gespeichert.

Dieser Algorithmus eignet sich auch für Daten, die 1-Bit-Alpha enthalten. Der einzige Unterschied besteht darin, dass color_3 auf 0 festgelegt ist (was eine transparente Farbe darstellt) und color_2 eine lineare Mischung aus color_0 und color_1 ist.

color_2 = 1/2*color_0 + 1/2*color_1;
color_3 = 0;

Unterschiede zwischen Direct3D 9 und Direct3D 10:

Dieses Format ist sowohl in Direct3D 9 als auch in 10 vorhanden.

  • In Direct3D 9 wird das BC1-Format D3DFMT_DXT1 genannt.
  • In Direct3D 10 wird das BC1-Format durch DXGI_FORMAT_BC1_UNORM oder DXGI_FORMAT_BC1_UNORM_SRGB dargestellt.

BU2

Verwenden Sie das BC2-Format (entweder DXGI_FORMAT_BC2_TYPELESS, DXGI_FORMAT_BC2_UNORM oder DXGI_BC2_UNORM_SRGB), um Daten zu speichern, die Farb- und Alphadaten mit geringer Kohärenz enthalten (verwenden Sie BC3 für hoch kohärente Alphadaten). Das BC2-Format speichert RGB-Daten als 5:6:5-Farbe (5 Bits rot, 6 Bit grün, 5 Bit blau) und Alpha als separaten 4-Bit-Wert. Bei einer 4×4-Textur mit dem größtmöglichen Datenformat reduziert dieses Komprimierungsverfahren den erforderlichen Arbeitsspeicher von 64 Bytes (16 Farben × 4 Komponenten/Farbe × 1 Byte/Komponente) auf 16 Bytes Arbeitsspeicher.

Das BC2-Format speichert Farben mit der gleichen Anzahl von Bits und Datenlayout wie das BC1-Format . BC2 benötigt jedoch zusätzliche 64 Bit Arbeitsspeicher, um die Alphadaten zu speichern, wie im folgenden Diagramm dargestellt.

Diagramm des Layouts für die bc2-Komprimierung

Unterschiede zwischen Direct3D 9 und Direct3D 10:

Dieses Format ist sowohl in Direct3D 9 als auch in 10 vorhanden.

  • In Direct3D 9 wird das BC2-Format D3DFMT_DXT2 und D3DFMT_DXT3 genannt.

  • In Direct3D 10 wird das BC2-Format durch DXGI_FORMAT_BC2_UNORM oder DXGI_FORMAT_BC2_UNORM_SRGB

BC3

Verwenden Sie das BC3-Format (entweder DXGI_FORMAT_BC3_TYPELESS, DXGI_FORMAT_BC3_UNORM oder DXGI_BC3_UNORM_SRGB), um hoch kohärente Farbdaten zu speichern (verwenden Sie BC2 mit weniger kohärenten Alphadaten). Das BC3-Format speichert Farbdaten mit der Farbe 5:6:5 (5 Bit rot, 6 Bit grün, 5 Bit blau) und Alphadaten mit einem Byte. Bei einer 4×4-Textur mit dem größtmöglichen Datenformat reduziert dieses Komprimierungsverfahren den erforderlichen Arbeitsspeicher von 64 Bytes (16 Farben × 4 Komponenten/Farbe × 1 Byte/Komponente) auf 16 Bytes Arbeitsspeicher.

Das BC3-Format speichert Farben mit der gleichen Anzahl von Bits und Datenlayout wie das BC1-Format . BC3 benötigt jedoch zusätzliche 64 Bit Arbeitsspeicher, um die Alphadaten zu speichern. Das BC3-Format verarbeitet Alpha, indem zwei Verweiswerte gespeichert und zwischen ihnen interpoliert werden (ähnlich wie bc1 RGB-Farbe speichert).

Der Algorithmus funktioniert auf 4×4 Blöcken von Texels. Anstatt 16 Alphawerte zu speichern, speichert der Algorithmus 2 Referenz-Alphas (alpha_0 und alpha_1) und 16 3-Bit-Farbindizes (alpha a bis p), wie im folgenden Diagramm dargestellt.

Diagramm des Layouts für die bc3-Komprimierung

Das BC3-Format verwendet die Alphaindizes (a–p), um die ursprünglichen Farben aus einer Nachschlagetabelle mit 8 Werten nachzuschlagen. Die ersten beiden Werte – alpha_0 und alpha_1 – sind die Minimal- und Höchstwerte. die anderen sechs Zwischenwerte werden mithilfe der linearen Interpolation berechnet.

Der Algorithmus bestimmt die Anzahl interpolierter Alphawerte, indem er die beiden Alpha-Referenzwerte untersucht. Wenn alpha_0 größer als alpha_1 ist, interpoliert BC3 6 Alphawerte; Andernfalls interpoliert sie 4. Wenn BC3 nur 4 Alphawerte interpoliert, legt es zwei zusätzliche Alphawerte fest (0 für vollständig transparent und 255 für vollständig undurchsichtig). BC3 komprimiert die Alphawerte im 4×4-Texelbereich, indem der Bitcode gespeichert wird, der den interpolierten Alphawerten entspricht, die dem ursprünglichen Alpha für ein bestimmtes Texel am ehesten entsprechen.

if( alpha_0 > alpha_1 )
{
  // 6 interpolated alpha values.
  alpha_2 = 6/7*alpha_0 + 1/7*alpha_1; // bit code 010
  alpha_3 = 5/7*alpha_0 + 2/7*alpha_1; // bit code 011
  alpha_4 = 4/7*alpha_0 + 3/7*alpha_1; // bit code 100
  alpha_5 = 3/7*alpha_0 + 4/7*alpha_1; // bit code 101
  alpha_6 = 2/7*alpha_0 + 5/7*alpha_1; // bit code 110
  alpha_7 = 1/7*alpha_0 + 6/7*alpha_1; // bit code 111
}
else
{
  // 4 interpolated alpha values.
  alpha_2 = 4/5*alpha_0 + 1/5*alpha_1; // bit code 010
  alpha_3 = 3/5*alpha_0 + 2/5*alpha_1; // bit code 011
  alpha_4 = 2/5*alpha_0 + 3/5*alpha_1; // bit code 100
  alpha_5 = 1/5*alpha_0 + 4/5*alpha_1; // bit code 101
  alpha_6 = 0;                         // bit code 110
  alpha_7 = 255;                       // bit code 111
}

Unterschiede zwischen Direct3D 9 und Direct3D 10:

  • In Direct3D 9 wird das BC3-Format D3DFMT_DXT4 und D3DFMT_DXT5 genannt.

  • In Direct3D 10 wird das BC3-Format durch DXGI_FORMAT_BC3_UNORM oder DXGI_FORMAT_BC3_UNORM_SRGB dargestellt.

BC4

Verwenden Sie das BC4-Format, um Einkomponentenfarbdaten mit 8 Bits für jede Farbe zu speichern. Aufgrund der erhöhten Genauigkeit (im Vergleich zu BC1) eignet sich BC4 ideal zum Speichern von Gleitkommadaten im Bereich von [0 bis 1] mit dem DXGI_FORMAT_BC4_UNORM-Format und [-1 bis +1] mit dem DXGI_FORMAT_BC4_SNORM-Format. Bei einer 4×4-Textur mit dem größtmöglichen Datenformat reduziert dieses Komprimierungsverfahren den erforderlichen Arbeitsspeicher von 16 Bytes (16 Farben × 1 Komponenten/Farbe × 1 Byte/Komponente) auf 8 Bytes.

Der Algorithmus funktioniert auf 4×4 Blöcken von Texels. Anstatt 16 Farben zu speichern, speichert der Algorithmus 2 Referenzfarben (red_0 und red_1) und 16 3-Bit-Farbindizes (rot a bis rot p), wie im folgenden Diagramm dargestellt.

Diagramm des Layouts für die bc4-Komprimierung

Der Algorithmus verwendet die 3-Bit-Indizes, um Farben aus einer Farbtabelle zu suchen, die 8 Farben enthält. Die ersten beiden Farben – red_0 und red_1 – sind die minimalen und maximalen Farben. Der Algorithmus berechnet die verbleibenden Farben mithilfe der linearen Interpolation.

Der Algorithmus bestimmt die Anzahl interpolierter Farbwerte, indem er die beiden Referenzwerte untersucht. Wenn red_0 größer als red_1 ist, interpoliert BC4 6 Farbwerte; Andernfalls interpoliert sie 4. Wenn BC4 nur vier Farbwerte interpoliert, legt es zwei zusätzliche Farbwerte fest (0,0f für vollständig transparent und 1,0f für vollständig undurchsichtig). BC4 komprimiert die Alphawerte im 4×4-Texelbereich, indem der Bitcode den interpolierten Alphawerten entspricht, die dem ursprünglichen Alpha für ein bestimmtes Texel am ehesten entsprechen.

BC4_UNORM

Die Interpolation der Einzelkomponentendaten erfolgt wie im folgenden Codebeispiel.

unsigned word red_0, red_1;

if( red_0 > red_1 )
{
  // 6 interpolated color values
  red_2 = (6*red_0 + 1*red_1)/7.0f; // bit code 010
  red_3 = (5*red_0 + 2*red_1)/7.0f; // bit code 011
  red_4 = (4*red_0 + 3*red_1)/7.0f; // bit code 100
  red_5 = (3*red_0 + 4*red_1)/7.0f; // bit code 101
  red_6 = (2*red_0 + 5*red_1)/7.0f; // bit code 110
  red_7 = (1*red_0 + 6*red_1)/7.0f; // bit code 111
}
else
{
  // 4 interpolated color values
  red_2 = (4*red_0 + 1*red_1)/5.0f; // bit code 010
  red_3 = (3*red_0 + 2*red_1)/5.0f; // bit code 011
  red_4 = (2*red_0 + 3*red_1)/5.0f; // bit code 100
  red_5 = (1*red_0 + 4*red_1)/5.0f; // bit code 101
  red_6 = 0.0f;                     // bit code 110
  red_7 = 1.0f;                     // bit code 111
}

Den Referenzfarben werden 3-Bit-Indizes zugewiesen (000–111, da es 8 Werte gibt), die während der Komprimierung in Blöcken rot a bis rot p gespeichert werden.

BC4_SNORM

Die DXGI_FORMAT_BC4_SNORM ist identisch, mit dem Unterschied, dass die Daten im SNORM-Bereich codiert sind und wenn 4 Farbwerte interpoliert werden. Die Interpolation der Einzelkomponentendaten erfolgt wie im folgenden Codebeispiel.

signed word red_0, red_1;

if( red_0 > red_1 )
{
  // 6 interpolated color values
  red_2 = (6*red_0 + 1*red_1)/7.0f; // bit code 010
  red_3 = (5*red_0 + 2*red_1)/7.0f; // bit code 011
  red_4 = (4*red_0 + 3*red_1)/7.0f; // bit code 100
  red_5 = (3*red_0 + 4*red_1)/7.0f; // bit code 101
  red_6 = (2*red_0 + 5*red_1)/7.0f; // bit code 110
  red_7 = (1*red_0 + 6*red_1)/7.0f; // bit code 111
}
else
{
  // 4 interpolated color values
  red_2 = (4*red_0 + 1*red_1)/5.0f; // bit code 010
  red_3 = (3*red_0 + 2*red_1)/5.0f; // bit code 011
  red_4 = (2*red_0 + 3*red_1)/5.0f; // bit code 100
  red_5 = (1*red_0 + 4*red_1)/5.0f; // bit code 101
  red_6 = -1.0f;                     // bit code 110
  red_7 =  1.0f;                     // bit code 111
}

Den Referenzfarben werden 3-Bit-Indizes zugewiesen (000–111, da es 8 Werte gibt), die während der Komprimierung in Blöcken rot a bis rot p gespeichert werden.

BC5

Verwenden Sie das BC5-Format, um Zweikomponentenfarbdaten mit 8 Bits für jede Farbe zu speichern. Aufgrund der erhöhten Genauigkeit (im Vergleich zu BC1) eignet sich BC5 ideal zum Speichern von Gleitkommadaten im Bereich von [0 bis 1] mit dem DXGI_FORMAT_BC5_UNORM-Format und [-1 bis +1] mit dem DXGI_FORMAT_BC5_SNORM-Format. Bei einer 4×4-Textur mit dem größtmöglichen Datenformat reduziert dieses Komprimierungsverfahren den benötigten Arbeitsspeicher von 32 Bytes (16 Farben × 2 Komponenten/Farbe × 1 Byte/Komponente) auf 16 Bytes.

Der Algorithmus funktioniert auf 4×4 Blöcken von Texels. Anstatt 16 Farben für beide Komponenten zu speichern, speichert der Algorithmus 2 Referenzfarben für jede Komponente (red_0, red_1, green_0 und green_1) und 16 3-Bit-Farbindizes für jede Komponente (rot a bis rot p und grün a bis grünes p), wie im folgenden Diagramm dargestellt.

Diagramm des Layouts für die bc5-Komprimierung

Der Algorithmus verwendet die 3-Bit-Indizes, um Farben aus einer Farbtabelle zu suchen, die 8 Farben enthält. Die ersten beiden Farben – red_0 und red_1 (oder green_0 und green_1) – sind die minimalen und maximalen Farben. Der Algorithmus berechnet die verbleibenden Farben mithilfe der linearen Interpolation.

Der Algorithmus bestimmt die Anzahl interpolierter Farbwerte, indem er die beiden Referenzwerte untersucht. Wenn red_0 größer als red_1 ist, interpoliert BC5 6 Farbwerte; Andernfalls interpoliert sie 4. Wenn BC5 nur 4 Farbwerte interpoliert, legt es die restlichen beiden Farbwerte auf 0,0f und 1,0f fest.

BC5_UNORM

Die Interpolation der Einzelkomponentendaten erfolgt wie im folgenden Codebeispiel. Die Berechnungen für die grünen Komponenten sind ähnlich.

unsigned word red_0, red_1;

if( red_0 > red_1 )
{
  // 6 interpolated color values
  red_2 = (6*red_0 + 1*red_1)/7.0f; // bit code 010
  red_3 = (5*red_0 + 2*red_1)/7.0f; // bit code 011
  red_4 = (4*red_0 + 3*red_1)/7.0f; // bit code 100
  red_5 = (3*red_0 + 4*red_1)/7.0f; // bit code 101
  red_6 = (2*red_0 + 5*red_1)/7.0f; // bit code 110
  red_7 = (1*red_0 + 6*red_1)/7.0f; // bit code 111
}
else
{
  // 4 interpolated color values
  red_2 = (4*red_0 + 1*red_1)/5.0f; // bit code 010
  red_3 = (3*red_0 + 2*red_1)/5.0f; // bit code 011
  red_4 = (2*red_0 + 3*red_1)/5.0f; // bit code 100
  red_5 = (1*red_0 + 4*red_1)/5.0f; // bit code 101
  red_6 = 0.0f;                     // bit code 110
  red_7 = 1.0f;                     // bit code 111
}

Den Referenzfarben werden 3-Bit-Indizes zugewiesen (000–111, da es 8 Werte gibt), die während der Komprimierung in Blöcken rot a bis rot p gespeichert werden.

BC5_SNORM

Die DXGI_FORMAT_BC5_SNORM ist identisch, mit der Ausnahme, dass die Daten im SNORM-Bereich codiert sind und wenn 4 Datenwerte interpoliert werden, sind die beiden zusätzlichen Werte -1.0f und 1.0f. Die Interpolation der Einzelkomponentendaten erfolgt wie im folgenden Codebeispiel. Die Berechnungen für die grünen Komponenten sind ähnlich.

signed word red_0, red_1;

if( red_0 > red_1 )
{
  // 6 interpolated color values
  red_2 = (6*red_0 + 1*red_1)/7.0f; // bit code 010
  red_3 = (5*red_0 + 2*red_1)/7.0f; // bit code 011
  red_4 = (4*red_0 + 3*red_1)/7.0f; // bit code 100
  red_5 = (3*red_0 + 4*red_1)/7.0f; // bit code 101
  red_6 = (2*red_0 + 5*red_1)/7.0f; // bit code 110
  red_7 = (1*red_0 + 6*red_1)/7.0f; // bit code 111
}
else
{
  // 4 interpolated color values
  red_2 = (4*red_0 + 1*red_1)/5.0f; // bit code 010
  red_3 = (3*red_0 + 2*red_1)/5.0f; // bit code 011
  red_4 = (2*red_0 + 3*red_1)/5.0f; // bit code 100
  red_5 = (1*red_0 + 4*red_1)/5.0f; // bit code 101
  red_6 = -1.0f;                    // bit code 110
  red_7 =  1.0f;                    // bit code 111
}

Den Referenzfarben werden 3-Bit-Indizes zugewiesen (000–111, da es 8 Werte gibt), die während der Komprimierung in Blöcken rot a bis rot p gespeichert werden.

Formatkonvertierung mit Direct3D 10.1

Direct3D 10.1 ermöglicht Kopien zwischen vorstrukturierten Texturen und blockkomprimierten Texturen derselben Bitbreite. Die Funktionen, die dies erreichen können, sind CopyResource und CopySubresourceRegion.

Ab Direct3D 10.1 können Sie CopyResource und CopySubresourceRegion verwenden, um zwischen einigen Formattypen zu kopieren. Dieser Kopiervorgang führt eine Formatkonvertierung durch, die Ressourcendaten als anderen Formattyp neu interpretiert. Betrachten Sie dieses Beispiel, das den Unterschied zwischen der Neuinterpretierung von Daten mit dem Verhalten eines typischeren Konvertierungstyps zeigt:

    FLOAT32 f = 1.0f;
    UINT32 u;

Verwenden Sie memcpy, um "f" als Typ von "u" neu zu interpretieren:

    memcpy( &u, &f, sizeof( f ) ); // ‘u’ becomes equal to 0x3F800000.

Bei der vorherigen Neuinterpretation ändert sich der zugrunde liegende Wert der Daten nicht. memcpy interpretiert den Float als ganze Zahl ohne Vorzeichen neu.

Verwenden Sie die Zuweisung, um den typischeren Konvertierungstyp auszuführen:

    u = f; // ‘u’ becomes 1.

Bei der vorherigen Konvertierung ändert sich der zugrunde liegende Wert der Daten.

In der folgenden Tabelle sind die zulässigen Quell- und Zielformate aufgeführt, die Sie in diesem Neuinterpretationstyp der Formatkonvertierung verwenden können. Sie müssen die Werte ordnungsgemäß codieren, damit die Neuinterpretation wie erwartet funktioniert.

Bitbreite Nicht komprimierte Ressource Block-Compressed-Ressource
32 DXGI_FORMAT_R32_UINT
DXGI_FORMAT_R32_SINT
DXGI_FORMAT_R9G9B9E5_SHAREDEXP
64 DXGI_FORMAT_R16G16B16A16_UINT
DXGI_FORMAT_R16G16B16A16_SINT
DXGI_FORMAT_R32G32_UINT
DXGI_FORMAT_R32G32_SINT
DXGI_FORMAT_BC1_UNORM[_SRGB]
DXGI_FORMAT_BC4_UNORM
DXGI_FORMAT_BC4_SNORM
128 DXGI_FORMAT_R32G32B32A32_UINT
DXGI_FORMAT_R32G32B32A32_SINT
DXGI_FORMAT_BC2_UNORM[_SRGB]
DXGI_FORMAT_BC3_UNORM[_SRGB]
DXGI_FORMAT_BC5_UNORM
DXGI_FORMAT_BC5_SNORM

 

Ressourcen (Direct3D 10)