Come invertire una trama BC6 / BC7?


8

Ho del codice per caricare i file di immagine DDS nelle trame OpenGL e vorrei estenderlo per supportare i formati compressi BC6 e BC7 introdotti in D3D11. Poiché DirectX e OpenGL non sono d'accordo sul fatto che l'origine di una trama sia nell'angolo superiore sinistro o inferiore sinistro, il mio caricatore DDS inverte i pixel di ciascuna immagine lungo l'asse Y prima di passare i pixel a OpenGL.

Lanciare trame compresse presenta un'ulteriore ruga: oltre a capovolgere ogni riga di blocchi di pixel 4x4, è necessario capovolgere i pixel all'interno di ciascun blocco. Ho trovato qui il codice per capovolgere i blocchi BC1 / BC2 / BC3 e dagli schemi a blocchi su MSDN è stato facile adattare il codice che lancia BC3 per gestire BC4 e BC5. I BC6 e BC7 formati sembrano significativamente più intimidatorio, però. Esiste un trucco simile per manipolare questi formati o dovrei decomprimere e ricomprimere completamente ogni blocco?

AGGIORNAMENTO: Si scopre che il capovolgimento della trama era necessario solo perché le coordinate della trama venivano invertite in modo errato al momento dell'esportazione. La rimozione di entrambi i lanci ha reso il codice più semplice e veloce (grazie Humus!). Lanciare i blocchi BC6 / BC7 può essere ancora una sfida interessante, ma non è più rilevante per il mio scenario originale.


1
Nota che se capovolgi le coordinate delle trame anziché le immagini delle trame, non puoi usare gli FBO con le stesse mesh / shader.
msell,

Questo è vero. Se si lasciano trame DDS sbloccate, vengono visualizzate anche sottosopra in strumenti come gDEBugger . Hrm.
postgoodism

Risposte:


6

Ho il sospetto che sia davvero possibile capovolgere i blocchi BC6-7 con molto meno lavoro di una decompressione completa e ricomprimere, ma non è ancora un picnic ed è molto più complesso dei lanci di blocchi BC1-5.

Innanzitutto, BC6-7 ha una varietà di modalità che possono essere selezionate per blocco. Le modalità hanno layout binari completamente diversi, quindi dovresti praticamente scrivere una diversa routine di inversione per ciascuna modalità (ce ne sono circa 20 in totale, IIRC).

Un'altra difficoltà sono le modalità partizionate, in cui i pixel nel blocco sono partizionati in 2 o 3 sottoinsiemi, ognuno con il proprio segmento di linea RGB. La partizione deve essere scelta da un set predefinito; quelli per BC6 possono essere visti qui . Il problema è che questo set di partizioni non è simmetrico sotto i flip verticali. Tuttavia, sospetto che sia simmetrico sotto una combinazione di lanci verticali e scambiando i due sottoinsiemi. Ad esempio, guardando la partizione n. 22 (6a riga, 3a colonna) in corrispondenza di quel collegamento, non esiste una versione capovolta verticalmente nella tabella, ma se si capovolgono verticalmente escambiare 0 e 1, si finisce con la partizione # 9 (3a fila, 2a colonna). Non ho verificato che ogni partizione possa essere capovolta in questo modo, né ho verificato quelle per BC7 (che include anche partizioni con 3 sottoinsiemi).

Anche se funziona, non sei ancora a casa libera. In BC1-5, l'ordine dei due endpoint del segmento di linea RGB è stato utilizzato per cambiare modalità, ma in BC6-7 è stato scelto l'ordine degli endpoint per correggere un bit degli indici per pixel in ciascun sottoinsieme di partizioni. Pertanto, se si modifica la partizione attorno, potrebbe essere necessario scambiare l'ordine degli endpoint.

E, ultimo ma non meno importante, in BC6-7 gli endpoint sono spesso delta-compressi (ovvero un endpoint viene archiviato con la massima precisione e gli altri vengono memorizzati come delta con precisione inferiore da esso). Lo scambio di sottoinsiemi di partizioni e l'ordine degli endpoint cambierà quale endpoint è quello ad alta precisione, quindi dovrai mescolare i bit di bassa precisione e annullare alcuni delta.

Tutto sommato, non sembra che ci sia uno showtopper fondamentale (anche se in realtà non ho scritto il codice), ma sarebbe sicuramente molto lavoro per capovolgere o ruotare questi formati. Se possibile, ti consiglio di capovolgere le immagini nella tua pipeline artistica prima che vengano compresse.

(A proposito, la specifica più completa di BC6-7 che ho trovato è la specifica ARB_texture_compression_bptc ; ho anche scritto un post sul blog sui formati BCn qualche tempo fa.)


Grazie; Sono sufficientemente terrorizzato. In realtà sono andato alla ricerca del tuo post sul blog, ma non riuscivo a ricordare il link. È una risorsa eccellente su tutto ciò che riguarda BCn; che da solo merita un voto!
postgoodism

0

Il lancio è solo una questione di default sui due formati. Puoi andare contro il valore predefinito.

Probabilmente è meglio farlo sul lato OpenGL, perché OpenGL è di livello inferiore e quindi ha meno probabilità di perdere l'ottimizzazione quando si fanno cose del genere.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.