Comment fonctionne la compression de texture matérielle?

13

Qu'il comprime les données par rapport à la matrice de pixels est évident.

Mais qu'est-ce qui le différencie de la compression normale (comme png, jpeg)?

monstre à cliquet
la source
Qu'est-ce que la «compression normale» - des choses comme JPEG et PNG? Demandez-vous les différences entre ces formats et les formats pris en charge par le matériel comme DXT et ASTC?
Nathan Reed
6
(Enfin, un sujet que je connais un peu!) Ce qui le rend différent du PNG / JPEG, c'est l'accès aléatoire. Étant donné que vous souhaitez accéder à Texel (XY), vous pouvez rapidement déterminer la petite empreinte des données nécessaires pour produire ce texel. JPG ou PNG peuvent nécessiter une décompression de toutes les données! Les sections 1 et 2 de l'article Wikipedia sont un bon résumé.
Simon F
Comme l'a écrit SimonF. C'est une question extrêmement large, et la réponse dépend du type qui vous intéresse. Avez-vous examiné les spécifications, par exemple pour DXT?
imallett

Réponses:

25

Comme l'a fait remarquer le commentaire de Simon, une différence majeure entre la compression de texture matérielle et les autres compressions d'image couramment utilisées est que la première n'utilise pas le codage entropique. Le codage entropique consiste à utiliser des chaînes de bits plus courtes pour représenter des modèles récurrents ou récurrents dans les données source, comme on le voit dans les formats de conteneur tels que ZIP, de nombreux formats d'image courants tels que GIF, JPEG et PNG, ainsi que dans de nombreux fichiers audio courants. et formats vidéo.

Le codage entropique est bon pour compresser toutes sortes de données, mais il produit intrinsèquement un taux de compression variable. Certaines zones de l'image peuvent avoir peu de détails (ou les détails sont bien prédits par le modèle de codage que vous utilisez) et nécessitent très peu de bits, mais d'autres zones peuvent avoir des détails complexes qui nécessitent plus de bits pour encoder. Cela rend difficile la mise en œuvre de l'accès aléatoire, car il n'y a aucun moyen simple de calculer où dans les données compressées vous pouvez trouver le pixel donné ( xy) coordonne. De plus, la plupart des schémas de codage entropique sont avec état, il n'est donc pas possible de commencer simplement le décodage à un endroit arbitraire du flux; vous devez recommencer depuis le début pour construire l'état correct. Cependant, un accès aléatoire est nécessaire pour l'échantillonnage de texture, car un shader peut échantillonner à partir de n'importe quel emplacement dans une texture à tout moment.

Ainsi, plutôt que le codage entropique, la compression matérielle utilise des schémas basés sur des blocs à rapport fixe. Par exemple, dans la compression DXT / BCn , la texture est découpée en blocs de 4 × 4 pixels, chacun étant codé en 64 ou 128 bits (selon le format choisi); dans ASTC , différents formats utilisent des tailles de bloc de 4 × 4 à 12 × 12, et tous les blocs sont codés en 128 bits. Les détails de la façon dont les bits représentent les données d'image varient selon les formats (et peuvent même varier d'un bloc à l'autre au sein de la même image), mais comme le rapport est fixe, le matériel peut facilement calculer où en mémoire trouver le bloc contenant un pixel ( x , y ) donné, et chaque bloc est autonome, il peut donc être décodé indépendamment de tout autre bloc.

Une autre considération dans la compression de texture matérielle est que le décodage doit être efficacement implémentable dans le matériel. Cela signifie que les opérations mathématiques lourdes et les flux de données complexes sont fortement défavorisés. Les formats BCn, par exemple, peuvent être décodés en effectuant une poignée d'opérations mathématiques entières sur 8 bits par bloc pour remplir une petite table de recherche, puis en recherchant simplement l'entrée de table appropriée par pixel. Cela nécessite très peu de surface sur la puce, ce qui est important car vous voulez probablement décoder plusieurs blocs en parallèle, et donc avoir besoin de plusieurs copies du matériel de décodage.

En revanche, les formats basés sur DCT tels que JPEG nécessitent une quantité non triviale de mathématiques par pixel, sans parler d'un flux de données complexe qui permute et diffuse diverses valeurs intermédiaires sur les pixels d'un bloc. (Regardez cet article pour certains des détails sanglants du décodage DCT.) Ce serait beaucoup plus grossier pour la mise en œuvre matérielle, ce qui, je suppose, est la raison pour laquelle AFAICT, aucun matériel GPU n'a jamais implémenté la compression de texture basée sur DCT ou sur ondelettes. .

Nathan Reed
la source
excellente réponse. vous pouvez également ajouter que certains articles mentionnent que dans certaines situations, vous pouvez effectuer la compression vous-même et le décoder avec du code client dans un pixel shader, plutôt que de dépendre d'un matériel dédié. Je ne connais aucune utilisation réelle de cela, qui ne vaut que pour la recherche, mais elle existe.
v.oddou
1
@ Nathan-Reed concernant la compression basée sur la transformation, en fait, le projet Talisman de Microsofts a utilisé un schéma de compression appelé TREC qui (comme l'un des modes) utilisait DCT mais contrairement au JPEG, permettait un accès aléatoire aux blocs (je suppose qu'il devait y avoir une table contenant adresses). Cela permettrait alors des données de longueur variable pour différents blocs, mais l'indirection est désagréable pour HW - une raison pour laquelle VQ TC est tombé en désuétude. FWIW J'ai expérimenté une dizaine d'idées TC B4 PVRTC; certains étaient à taux fixe, basés sur la transformation, mais les coefficients "manquants" utilisent toujours des bits. Les emplacements de coefficients fixes de type BTC impliquent des informations "gratuites".
Simon F
2
@ Nathan-Reed. D'après ce que j'ai vu, tous les décodeurs HW peuvent être implémentés avec un chemin logique pur (décodage de bits, quelques recherches, quelques calculs dans le chemin de données) mais pas de boucle / registre nécessaire. Connaissez-vous un schéma qui ajoute une latence de cycle à la recherche de texture? (J'ai pour le plaisir implémenté un décodeur VHDL ETC1) J'avais l'impression que chaque unité de texture (TU) avait des décodeurs intégrés.
Romain Piquois
31

«Comment fonctionne la compression de texture (matérielle)» est un sujet important. J'espère que je pourrai fournir quelques informations sans reproduire le contenu de la réponse de Nathan .

Exigences

La compression de texture diffère généralement des techniques de compression d'image «standard», par exemple JPEG / PNG de quatre manières principales, comme indiqué dans Rendu à partir de textures compressées de Beers et al :

  1. Vitesse de décodage : vous ne voulez pas que la compression de texture soit plus lente (du moins pas du tout) que l'utilisation de textures non compressées. Il devrait également être relativement simple à décompresser car cela peut aider à réaliser une décompression rapide sans coûts matériels et électriques excessifs.

  2. Accès aléatoire : vous ne pouvez pas facilement prédire quels texels seront nécessaires lors d'un rendu donné. Si un sous-ensemble, M , des texels accédés provient, disons, du milieu de l'image, il est essentiel que vous n'ayez pas à décoder toutes les lignes «précédentes» de la texture pour déterminer M ; avec JPEG et PNG, cela est nécessaire car le décodage des pixels dépend des données précédemment décodées.
    Notez, ceci dit, juste parce que vous avez un accès "aléatoire", ne signifie pas que vous devriez essayer d'échantillonner complètement arbitrairement

  3. Taux de compression et qualité visuelle : Beers et al soutiennent (de manière convaincante) que la perte d'une certaine qualité du résultat compressé afin d'améliorer le taux de compression est un compromis intéressant. Dans le rendu 3D, les données vont probablement être manipulées (par exemple filtrées et ombrées, etc.) et donc certaines pertes de qualité peuvent être masquées.

  4. Encodage / décodage asymétrique : Bien que peut-être légèrement plus litigieux, ils soutiennent qu'il est acceptable d'avoir le processus d'encodage beaucoup plus lent que le décodage. Étant donné que le décodage doit être à des taux de remplissage HW, cela est généralement acceptable. (J'admettrai que la compression de PVRTC, ETC2 et quelques autres à une qualité maximale pourrait être plus rapide)

Histoire et techniques anciennes

Cela peut surprendre certains d'apprendre que la compression des textures existe depuis plus de trois décennies. Les simulateurs de vol des années 70 et 80 avaient besoin d'accéder à des quantités relativement importantes de données de texture et étant donné que 1 Mo de RAM en 1980 était> 6 000 $ , la réduction de l'empreinte de texture était essentielle. Autre exemple, au milieu des années 70, même une petite quantité de mémoire et de logique à grande vitesse, par exemple suffisamment pour un modeste tampon de trame RVB 512x512 ) pourrait vous faire baisser le prix d'une petite maison.

Cependant, AFAIK, non explicitement appelé compression de texture, dans la littérature et les brevets, vous pouvez trouver des références à des techniques telles que:
a. formes simples de synthèse mathématique / procédurale des textures,
b. utilisation d'une texture monocanal (par exemple 4 bpp) qui est ensuite multipliée par une valeur RVB par texture,
c. YUV et
d. palettes (la littérature suggérant l'utilisation de l'approche de Heckbert pour effectuer la compression)

Modélisation des données d'image

Comme indiqué ci-dessus, la compression de texture est presque toujours avec perte et donc le problème devient celui d'essayer de représenter les données importantes de manière compacte tout en éliminant les informations les moins significatives. Les différents schémas qui seront décrits ci-dessous ont tous un modèle implicite «paramétré» qui se rapproche du comportement typique des données de texture et de la réponse de l'œil.

De plus, étant donné que la compression de texture a tendance à utiliser un codage à taux fixe, le processus de compression comprend généralement une étape de recherche pour trouver l'ensemble de paramètres qui, une fois alimenté dans le modèle, générera une bonne approximation de la texture d'origine. Cependant, cette étape de recherche peut prendre du temps.
(À l'exception peut-être d'outils tels que optipng , c'est un autre domaine où l'utilisation typique de PNG et JPEG diffère des schémas de compression de texture)

Avant de progresser davantage, pour mieux comprendre TC, il convient de jeter un coup d'œil à l' analyse en composantes principales (ACP) , un outil mathématique très utile pour la compression des données.

Exemple de texture

Pour comparer les différentes méthodes, nous utiliserons l'image suivante:

petit loriquet + texte
Notez qu'il s'agit d'une image assez difficile, en particulier pour les méthodes de palette et VQTC car elle s'étend sur une grande partie du cube de couleur RVB et seulement 15% des texels utilisent des couleurs répétées.

Compression de textures pour PC et (après le milieu des années 90)

Pour réduire les coûts de données, certains jeux PC et consoles de premiers jeux ont également utilisé des images de palette, qui est une forme de quantification vectorielle (VQ). Les approches basées sur des palettes supposent qu'une image donnée n'utilise que des portions relativement petites du cube de couleur RVB (A). Un problème avec les textures de palette est que les taux de compression pour la qualité obtenue sont généralement plutôt modestes. L'exemple de texture compressé en "4bpp" (en utilisant GIMP) a produit une nouvelle fois qu'il s'agit d'une image relativement difficile pour les schémas VQ.
entrez la description de l'image ici

VQ avec des vecteurs plus grands (par exemple 2bpp ARGB)

Inspirée par Beers et al, la console Dreamcast a utilisé VQ pour encoder des blocs de pixels 2x2 ou même 2x4 avec des octets simples. Alors que les "vecteurs" dans les textures de palette sont en 3 ou 4 dimensions, les blocs de 2 x 2 pixels peuvent être considérés comme 16 dimensions. Le schéma de compression suppose qu'il existe une répétition suffisante et approximative de ces vecteurs.

Même si VQ peut atteindre une qualité satisfaisante avec ~ 2bpp, le problème avec ces schémas est qu'il nécessite des lectures de mémoire dépendantes: une lecture initiale de la carte d'index pour déterminer le code du pixel est suivie d'une seconde pour réellement récupérer les données de pixel associées avec ce code. Des caches supplémentaires peuvent aider à réduire une partie de la latence encourue, mais ajoutent de la complexité au matériel.

L'image d'exemple compressée avec le schéma Dreamcast 2bpp est Résultat 2bpp VQ. La carte d'index est:Carte d'index 2bpp VQ

La compression des données VQ peut être effectuée de différentes manières, cependant, IIRC , ce qui précède a été fait en utilisant PCA pour dériver puis partitionner les vecteurs 16D le long du vecteur principal en 2 ensembles de sorte que deux vecteurs représentatifs minimisent l'erreur quadratique moyenne. Le processus s'est ensuite répété jusqu'à ce que 256 vecteurs candidats aient été produits. Une approche globale k-means / algorithme de Lloyd a ensuite été appliquée pour améliorer les représentants.

Transformations de l'espace colorimétrique

Les transformations de l'espace colorimétrique font également appel à l'ACP, notant que la distribution mondiale de la couleur est souvent répartie le long d'un axe principal et beaucoup moins répandue le long des autres axes. Pour les représentations YUV, les hypothèses sont que a) le grand axe est souvent dans la direction de la luma et que b) l'œil est plus sensible aux changements dans cette direction.

Le système 3dfx Voodoo a fourni "YAB" , un système de compression 8bpp, "Narrow Channel" qui a divisé chaque texel 8 bits en un format 322, et a appliqué une transformation de couleur sélectionnée par l'utilisateur à ces données pour les mapper en RVB. L'axe principal avait ainsi 8 niveaux et les axes plus petits, 4 chacun.

La puce S3 Virge avait un schéma légèrement plus simple, 4bpp, qui permettait à l'utilisateur de spécifier, pour la texture entière , deux couleurs de fin, qui devraient se trouver sur l'axe principal, ainsi qu'une texture monochrome de 4bpp. La valeur par pixel a ensuite mélangé les couleurs finales avec des poids appropriés pour produire le résultat RVB.

Schémas basés sur la CTB

En remontant un certain nombre d'années, Delp et Mitchell ont conçu un schéma de compression d'image simple (monochrome) appelé Block Truncation Coding (BTC) . Cet article comprenait également un algorithme de compression mais, pour nos besoins, nous nous intéressons principalement aux données compressées résultantes et au processus de décompression.

Dans ce schéma, les images sont divisées en blocs de pixels 4x4, qui peuvent être compressés indépendamment avec, en fait, un algorithme VQ localisé. Chaque bloc est représenté par deux "valeurs", a et b , et un ensemble 4x4 de bits d'index, qui identifient laquelle des deux valeurs utiliser pour chaque pixel.

S3TC : 4bpp RGB (+ 1 bit alpha)
Bien que plusieurs couleurs variantes de BTC pour la compression d'image ont été proposées, qui nous intéresse est Iourcha et S3TC de al , dont certains semble être une redécouverte de l'œuvre un peu oublié de Hoffert et al que a été utilisé dans Quicktime d'Apple.

Le S3TC d'origine, sans les variantes DirectX, comprime des blocs RVB ou RVB + Alpha 1 bit à 4 bpp. Chaque bloc 4x4 de la texture est remplacé par deux couleurs d'extrémité, A et B , desquelles jusqu'à deux autres couleurs sont dérivées par des mélanges linéaires à poids fixe. De plus, chaque texel du bloc a un index à 2 bits qui détermine comment sélectionner l'une de ces quatre couleurs.

Par exemple, ce qui suit est une section 4x4 pixels de l'image de test compressée avec l'outil AMD / ATI Compressenator. ( Techniquement, il est tiré d'une version 512x512 de l'image de test, mais pardonnez mon manque de temps pour mettre à jour les exemples ). Ceci illustre le processus de compression: la moyenne et l'axe principal des couleurs sont calculés. Un meilleur ajustement est ensuite effectué pour trouver deux points d'extrémité qui `` reposent '' sur l'axe qui, avec les deux mélanges dérivés 1: 2 et 2: 1 (ou dans certains cas, un mélange 50:50) de ces points d'extrémité, qui minimise l'erreur. Chaque pixel d'origine est ensuite mappé à l'une de ces couleurs pour produire le résultat.
entrez la description de l'image ici

Si, comme dans ce cas, les couleurs sont raisonnablement approximées par l'axe principal, l'erreur sera relativement faible. Cependant, si, comme dans le bloc 4x4 voisin illustré ci-dessous, les couleurs sont plus diverses, l'erreur sera plus élevée.
entrez la description de l'image ici

L'image d'exemple, compressée avec le compresseur AMD produit:
entrez la description de l'image ici

Étant donné que les couleurs sont déterminées indépendamment par bloc, il peut y avoir des discontinuités aux limites des blocs mais, tant que la résolution est maintenue suffisamment élevée, ces artefacts de bloc peuvent passer inaperçus:
entrez la description de l'image ici

ETC1 : 4bpp RGB
Ericsson Texture Compression fonctionne également avec des blocs 4x4 de texels mais fait l'hypothèse que, tout comme YUV, l'axe principal d'un ensemble local de texels est souvent très fortement corrélé avec "luma". L'ensemble des texels peut alors être représenté uniquement par une couleur moyenne et une «longueur» scalaire hautement quantifiée de la projection des texels sur cet axe supposé.

Étant donné que cela réduit les coûts de stockage de données par rapport, par exemple, au S3TC, cela permet à ETC d'introduire un schéma de partitionnement, par lequel le bloc 4x4 est subdivisé en une paire de sous-blocs horizontaux 4x2 ou verticaux 2x4. Ceux-ci ont chacun leur propre couleur moyenne. L'exemple d'image produit: La zone autour du bec illustre également la partition horizontale et verticale des blocs 4x4.
entrez la description de l'image ici
entrez la description de l'image ici

Global + Local

Il existe certains systèmes de compression de texture qui sont un croisement entre les schémas globaux et locaux, comme celui des palettes distribuées d' Ivanov et de Kuzmin ou la méthode du PVRTC .

PVRTC : 4 & 2 bpp RGBA
PVRTC suppose qu'une image mise à l'échelle (en pratique, bilinéairement) est une bonne approximation de la cible en pleine résolution et que la différence entre l'approximation et la cible, c'est-à-dire l'image delta, est localement monochromatique, c'est-à-dire a un axe principal dominant. En outre, il suppose que l'axe principal local peut être interpolé sur l'image.

(à faire: ajouter des images montrant la panne)

L'exemple de texture, compressé avec PVRTC1 4bpp produit: avec la zone autour du bec: par rapport aux schémas BTC, les artefacts de bloc sont généralement éliminés mais il peut parfois y avoir un "dépassement" s'il y a de fortes discontinuités dans l'image source, par exemple autour la silhouette de la tête du loriquet.
entrez la description de l'image ici

entrez la description de l'image ici

La variante 2bpp a, naturellement, une erreur plus élevée que la 4bpp (notez une perte de précision autour des zones bleues et hautes fréquences près du cou) mais sans doute toujours de qualité raisonnable:
entrez la description de l'image ici

Une note sur les coûts de décompression

Bien que les algorithmes de compression pour les schémas décrits ci-dessus aient un coût d'évaluation modéré à élevé, les algorithmes de décompression, en particulier pour les implémentations matérielles, sont relativement peu coûteux. ETC1, par exemple, ne nécessite guère plus que quelques MUX et additionneurs de faible précision; S3TC a effectivement légèrement plus d'unités d'addition pour effectuer le mélange; et PVRTC, encore un peu plus. En théorie, ces schémas TC simples pourraient permettre à une architecture GPU d'éviter la décompression juste avant l'étape de filtrage, maximisant ainsi l'efficacité des caches internes.

Autres schémas

Les autres modes TC courants à mentionner sont:

  • ETC2 - est un sur-ensemble (4 bpp) d'ETC1 qui améliore la gestion des régions avec des distributions de couleurs qui ne s'alignent pas bien avec la 'luma'. Il existe également une variante 4bpp qui prend en charge l'alpha 1 bit et un format 8bpp pour RGBA.

  • ATC - est effectivement une petite variation sur S3TC .

  • FXT1 (3dfx) était une variante plus ambitieuse du thème S3TC .

  • BC6 & BC7: un système basé sur des blocs de 8bpp prenant en charge ARGB. Outre les modes HDR, ceux-ci utilisent un système de partitionnement plus complexe que celui de l'ETC pour tenter de mieux modéliser la distribution des couleurs de l'image.

  • PVRTC2: ARGB 2 et 4 bpp. Cela introduit des modes supplémentaires, dont un pour surmonter les limitations avec de fortes limites dans les images.

  • ASTC: Il s'agit également d'un système basé sur des blocs, mais il est un peu plus compliqué en ce qu'il a un grand nombre de tailles de blocs possibles ciblant une large gamme de bpp. Il comprend également des fonctionnalités telles que jusqu'à 4 régions de partition avec un générateur de partition pseudo-aléatoire et une résolution variable pour les données d'index et / ou la précision des couleurs et les modèles de couleurs.

Simon F
la source
1
Wow, cela devrait être un article de blog quelque part! Très bonne réponse!
glampert
2
Heureux que ce soit utile. Quant à un blog, je l'ai écrit il y a une décennie mais je n'ai vraiment pas le temps de le faire.
Simon F
1
Le site Web hébergeant l'ancien blog est mort. Ceci est la dernière version archivée: web.archive.org/web/20160322090245/http://web.onetel.net.uk/…
ahcox