Comment retourner une texture BC6 / BC7?


8

J'ai du code pour charger des fichiers d'images DDS dans des textures OpenGL, et j'aimerais l'étendre pour prendre en charge les formats compressés BC6 et BC7 introduits dans D3D11. Étant donné que DirectX et OpenGL ne s'entendent pas sur l'origine d'une texture dans le coin supérieur gauche ou inférieur gauche, mon chargeur DDS retourne les pixels de chaque image le long de l'axe Y avant de passer les pixels à OpenGL.

Le retournement des textures compressées présente une ride supplémentaire: en plus de retourner chaque rangée de blocs de 4x4 pixels, vous devez également retourner les pixels à l'intérieur de chaque bloc. J'ai trouvé du code ici pour retourner les blocs BC1 / BC2 / BC3, et à partir des diagrammes de blocs sur MSDN, il était facile d'adapter le code de retournement BC3 pour gérer BC4 et BC5. Les formats BC6 et BC7 semblent cependant beaucoup plus intimidants. Existe-t-il une astuce similaire pour modifier ces formats, ou devrais-je décompresser et recompresser complètement chaque bloc?

MISE À JOUR: Il s'avère que le retournement de texture n'était nécessaire que parce que mes coordonnées de texture étaient incorrectement inversées au moment de l'exportation. La suppression des deux flips a rendu le code à la fois plus simple et plus rapide (merci Humus!). Le retournement des blocs BC6 / BC7 peut toujours être un défi intéressant, mais il n'est plus pertinent pour mon scénario d'origine.


1
Notez que si vous inversez les coordonnées de texture au lieu des images de texture, vous ne pouvez pas utiliser les FBO avec les mêmes maillages / shaders.
msell

C'est vrai. Laisser les textures DDS non retournées les fait également apparaître à l'envers dans des outils comme gDEBugger . Hrm.
postgoodism

Réponses:


6

Je soupçonne qu'il est en effet possible de retourner des blocs BC6-7 avec beaucoup moins de travail qu'une décompression et une recompression complètes, mais ce n'est toujours pas un pique-nique et c'est beaucoup plus complexe que de retourner des blocs BC1-5.

Tout d'abord, les BC6-7 ont une variété de modes qui peuvent être sélectionnés par bloc. Les modes ont des dispositions binaires complètement différentes, vous devrez donc à peu près écrire une routine de retournement différente pour chaque mode (il y en a ~ 20 au total, IIRC).

Une autre difficulté réside dans les modes partitionnés, où les pixels du bloc sont partitionnés en 2 ou 3 sous-ensembles, chacun avec son propre segment de ligne RVB. La partition doit être choisie dans un ensemble prédéfini; ceux pour BC6 peuvent être vus ici . Le problème est que cet ensemble de partitions n'est pas symétrique sous les retournements verticaux. Cependant, je soupçonne qu'il échange des 0 et des 1, vous vous retrouvez avec la partition # 9 (3e ligne, 2e colonne). Je n'ai pas vérifié que chaque partition peut être retournée de cette façon, ni vérifié celles de BC7 (qui comprend également des partitions avec 3 sous-ensembles). est symétrique sous une combinaison de retournements verticaux et d'interchanger les deux sous-ensembles. Par exemple, en regardant la partition # 22 (6ème ligne, 3ème colonne) sur ce lien, il n'y a pas de version inversée verticalement dans le tableau, mais si vous inversez verticalement et

Même si cela fonctionne, vous n'êtes toujours pas à la maison. Dans BC1-5, l'ordre des deux points d'extrémité du segment de ligne RVB a été utilisé pour changer de mode, mais dans BC6-7 l'ordre des points d'extrémité est choisi pour fixer un bit des indices par pixel dans chaque sous-ensemble de partition. Par conséquent, si vous modifiez la partition autour, vous devrez peut-être également échanger l'ordre des points de terminaison.

Enfin et surtout, dans BC6-7, les points d'extrémité sont souvent compressés en delta (c'est-à-dire qu'un point d'extrémité est stocké avec une précision totale et les autres sont stockés en tant que deltas de moindre précision). L'échange de sous-ensembles de partitions et de l'ordre des points de terminaison changera le point de terminaison de haute précision, vous devrez donc mélanger les bits de faible précision et annuler certains deltas.

Dans l'ensemble, il ne semble pas y avoir de showstopper fondamental (même si je n'ai pas vraiment écrit le code), mais ce serait certainement beaucoup de travail pour inverser ou faire pivoter ces formats. Si possible, je recommanderais de retourner les images dans votre pipeline d'art avant qu'elles ne soient compressées.

(BTW, la spécification la plus complète de BC6-7 que j'ai trouvée est la spécification ARB_texture_compression_bptc ; j'ai également écrit un article de blog sur les formats BCn il y a quelque temps.)


Merci; Je suis suffisamment terrifiée. En fait, je suis allé chercher votre article de blog, mais je ne me souvenais pas du lien. C'est une excellente ressource sur tout ce qui concerne BCn; cela vaut à lui seul un vote positif!
postgoodism

0

Le retournement n'est qu'une question de défaut sur les deux formats. Vous pouvez aller contre la valeur par défaut.

C'est probablement mieux à faire du côté d'OpenGL, car OpenGL est de niveau inférieur, et donc moins susceptible de perdre l'optimisation en faisant des choses comme ça.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.