Wie kann man eine BC6 / BC7-Textur umdrehen?

8

Ich habe Code zum Laden von DDS-Bilddateien in OpenGL-Texturen und möchte ihn erweitern, um die in D3D11 eingeführten komprimierten Formate BC6 und BC7 zu unterstützen. Da DirectX und OpenGL sich nicht darüber einig sind, ob der Ursprung einer Textur in der oberen linken oder unteren linken Ecke liegt, dreht mein DDS-Loader die Pixel jedes Bildes entlang der Y-Achse, bevor die Pixel an OpenGL übergeben werden.

Das Spiegeln komprimierter Texturen stellt eine zusätzliche Falte dar: Zusätzlich zum Spiegeln jeder Reihe von 4x4-Pixel-Blöcken müssen Sie auch die Pixel in jedem Block spiegeln. Ich habe hier Code gefunden , um BC1 / BC2 / BC3-Blöcke umzudrehen, und aus den Blockdiagrammen auf MSDN war es einfach, den BC3-Umkehrcode an BC4 und BC5 anzupassen. Die Formate BC6 und BC7 wirken jedoch deutlich einschüchternder. Gibt es einen ähnlichen Bit-Twiddling-Trick, um diese Formate umzudrehen, oder müsste ich jeden Block vollständig dekomprimieren und neu komprimieren?

UPDATE: Es stellte sich heraus, dass der Textur-Flip nur notwendig war, weil meine Texturkoordinaten beim Export falsch invertiert wurden. Durch das Entfernen beider Flips wurde der Code sowohl einfacher als auch schneller (danke Humus!). Das Umdrehen von BC6 / BC7-Blöcken mag immer noch eine interessante Herausforderung sein, ist aber für mein ursprüngliches Szenario nicht mehr relevant.

Postgoodismus
quelle
1
Beachten Sie, dass Sie keine FBOs mit denselben Maschen / Shadern verwenden können, wenn Sie die Texturkoordinaten anstelle der Texturbilder spiegeln.
Msell
Das ist wahr. Wenn DDS-Texturen nicht gespiegelt werden, werden sie auch in Tools wie gDEBugger verkehrt herum angezeigt . Hrm.
Postgoodism

Antworten:

6

Ich vermute, dass es tatsächlich möglich ist, BC6-7-Blöcke mit viel weniger Arbeit als eine vollständige Dekomprimierung und Neukomprimierung umzudrehen, aber es ist immer noch kein Picknick und viel komplexer als das Umdrehen von BC1-5-Blöcken.

Erstens verfügt BC6-7 über eine Vielzahl von Modi, die pro Block ausgewählt werden können. Die Modi haben völlig unterschiedliche binäre Layouts, so dass Sie für jeden Modus so ziemlich eine andere Flip-Routine schreiben müssten (es gibt insgesamt ~ 20 davon, IIRC).

Eine weitere Schwierigkeit sind die partitionierten Modi, bei denen die Pixel im Block in 2 oder 3 Teilmengen mit jeweils einem eigenen RGB-Liniensegment unterteilt sind. Die Partition muss aus einer vordefinierten Menge ausgewählt werden. diejenigen , die für BC6 zu sehen ist hier . Das Problem ist, dass dieser Partitionssatz unter vertikalen Flips nicht symmetrisch ist. Ich vermute jedoch, dass es unter einer Kombination aus vertikalen Flips und dem Austausch der beiden Teilmengen symmetrisch ist . Wenn Sie sich beispielsweise die Partition Nr. 22 (6. Zeile, 3. Spalte) unter diesem Link ansehen, gibt es keine vertikal gespiegelte Version davon in der Tabelle, aber wenn Sie vertikal spiegeln undWenn Sie 0s und 1s austauschen, erhalten Sie die Partition Nr. 9 (3. Zeile, 2. Spalte). Ich habe weder überprüft, ob jede Partition auf diese Weise gespiegelt werden kann, noch habe ich die Partitionen für BC7 überprüft (einschließlich Partitionen mit 3 Teilmengen).

Selbst wenn das funktioniert, sind Sie immer noch nicht frei zu Hause. In BC1-5 wurde die Reihenfolge der beiden Endpunkte des RGB-Liniensegments zum Umschalten der Modi verwendet, in BC6-7 wird die Reihenfolge der Endpunkte so gewählt, dass ein Bit der Pro-Pixel-Indizes in jeder Partitionsuntermenge festgelegt wird. Wenn Sie die Partition ändern, müssen Sie möglicherweise auch die Reihenfolge der Endpunkte austauschen.

Und zu guter Letzt werden in BC6-7 die Endpunkte häufig deltakomprimiert (dh ein Endpunkt wird mit voller Genauigkeit gespeichert und die anderen werden als Deltas mit niedrigerer Genauigkeit daraus gespeichert). Durch das Vertauschen von Partitionsuntermengen und Endpunktreihenfolge wird geändert, welcher Endpunkt der hochpräzise ist. Sie müssen also die niedrigpräzisen Bits mischen und einige Deltas negieren.

Alles in allem scheint es keinen grundlegenden Showstopper zu geben (obwohl ich den Code noch nicht geschrieben habe), aber es wäre sicher eine Menge Arbeit, diese Formate umzudrehen oder zu drehen. Wenn möglich, würde ich empfehlen, die Bilder in Ihrer Kunst-Pipeline umzudrehen bevor sie komprimiert werden.

(Übrigens ist die vollständigste Spezifikation von BC6-7, die ich gefunden habe, die ARB_texture_compression_bptc- Spezifikation; ich habe vor einiger Zeit auch einen Blog-Beitrag über die BCn-Formate geschrieben.)

Nathan Reed
quelle
Vielen Dank; Ich habe genug Angst. Ich habe tatsächlich nach Ihrem Blog-Beitrag gesucht, konnte mich aber nicht an den Link erinnern. Es ist eine ausgezeichnete Ressource für alles, was mit BCn zu tun hat. das allein ist eine positive wert wert!
Postgoodism
0

Das Umdrehen ist bei beiden Formaten nur eine Standardeinstellung. Sie können gegen die Standardeinstellung gehen.

Dies ist auf der OpenGL-Seite wahrscheinlich besser, da OpenGL auf einer niedrigeren Ebene liegt und daher weniger wahrscheinlich die Optimierung verliert, wenn Sie solche Dinge tun.

Robert Wm Ruedisueli
quelle