Aidez-moi à saisir le filtrage anisotrope (AF)

8

Dernièrement, j'ai lu sur le filtrage de texture, à savoir le filtrage du plus proche voisin, le filtrage bilinéaire, le filtrage trilinéaire, le filtrage anisotrope, les cartes MIP, les cartes RIP, etc.

D'un point de vue de haut niveau, je pense que je peux comprendre ces techniques, comment le travail et pourquoi elles existent, à l'exception du filtrage anisotrope. Le filtrage anisotrope me rend fou.

Je peux voir le problème d'avoir à texturer une surface qui est à un angle par rapport à la caméra, mais je ne comprends pas comment l'échantillonnage des empreintes trapézoïdales pourrait résoudre ce problème (bien que je puisse voir le résultat). C'est probablement parce que je ne comprends PAS comment l'empreinte trapézoïdale est calculée et comment les télex fermés sont pondérés pour échantillonner la texture.

Cet article de Nvidia m'embrouille encore plus en utilisant des phrases comme " lorsqu'un texel est trapézoïdal " ou " le filtrage anisotrope met à l'échelle la hauteur ou la largeur d'une mipmap par un rapport par rapport à la distorsion en perspective de la texture ". Texel trapézoïdal? Mettre à l'échelle une MIPmap? Qu'est-ce que cela signifie même?

Pourriez-vous m'aider à comprendre comment fonctionnent les niveaux AF et AF?

Veuillez noter que mon objectif n'est PAS d'avoir une implémentation OpenGL ou DirectX AF, mais plutôt de comprendre comment fonctionne l'AF dans une perspective de haut niveau.

Nicola Masotti
la source

Réponses:

10

Pour comprendre la nature du filtrage anisotrope, vous devez bien comprendre ce que signifie réellement le mappage de texture.

Le terme "mappage de texture" signifie affecter des positions sur un objet à des emplacements dans une texture. Cela permet au rasterizer / shader de récupérer, pour chaque position sur l'objet, les données correspondantes de la texture. La méthode traditionnelle consiste à attribuer à chaque sommet d'un objet une coordonnée de texture, qui mappe directement cette position à un emplacement dans la texture. Le rasterizer interpolera cette coordonnée de texture sur les faces des différents triangles pour produire la coordonnée de texture utilisée pour extraire la couleur de la texture.

Maintenant, réfléchissons au processus de pixellisation. Comment ça marche? Il prend un triangle et le décompose en blocs de la taille d'un pixel que nous appellerons des "fragments". Maintenant, ces blocs de taille pixel sont de taille pixel par rapport à l'écran.

Mais ces fragments ne sont pas de la taille d'un pixel par rapport à la texture. Imaginez si notre rastériseur générait une coordonnée de texture pour chaque coin du fragment. Imaginez maintenant dessiner ces 4 coins, non pas dans l'espace écran, mais dans l' espace texture . Quelle forme cela aurait-il?

Eh bien, cela dépend des coordonnées de la texture. Autrement dit, cela dépend de la façon dont la texture est mappée au polygone. Pour tout fragment particulier, il peut s'agir d'un carré aligné sur l'axe. Il peut s'agir d'un carré non aligné sur l'axe. Ce pourrait être un rectangle. Ce pourrait être un trapèze. Ce pourrait être à peu près n'importe quelle figure à quatre côtés (ou au moins, des figures convexes).

Si vous utilisiez correctement l'accès à la texture, le moyen d'obtenir la couleur de texture d'un fragment serait de comprendre ce qu'est ce rectangle. Ensuite, récupérez chaque texel de la texture dans ce rectangle (en utilisant la couverture pour mettre à l'échelle les couleurs qui sont sur la bordure). Ensuite, faites-les tous ensemble. Ce serait une cartographie de texture parfaite.

Ce serait également extrêmement lent .

Dans l'intérêt de la performance, nous essayons plutôt d'approcher la vraie réponse. Nous basons les choses sur une coordonnée de texture, plutôt que sur les 4 qui couvrent la zone entière du fragment dans l'espace texel.

Le filtrage basé sur Mipmap utilise des images de résolution inférieure. Ces images sont essentiellement un raccourci pour la méthode parfaite, en pré-calculant à quoi ressembleraient de grands blocs de couleurs lorsqu'ils sont mélangés. Ainsi, lorsqu'il sélectionne un mipmap inférieur, il utilise des valeurs précalculées où chaque texel représente une zone de la texture.

Le filtrage anisotrope fonctionne en rapprochant la méthode parfaite (qui peut et doit être couplée à la cartographie par mip) en prenant jusqu'à un nombre fixe d'échantillons supplémentaires. Mais comment détermine-t-il la zone dans l'espace texel à extraire, car elle n'a toujours qu'une seule coordonnée de texture?

Fondamentalement, il triche. Étant donné que les shaders de fragments sont exécutés dans des blocs voisins 2x2, il est possible de calculer la dérivée de n'importe quelle valeur dans le shader de fragments dans l'espace d'écran X et Y. Il utilise ensuite ces dérivées, couplées à la coordonnée de texture réelle, pour calculer une approximation de quelle serait l'empreinte de texture du vrai fragment. Et puis il effectue un certain nombre d'échantillons dans cette zone.

Voici un schéma pour l'expliquer:

Empreinte du fragment et échantillons anisotropes.  FYI: si vous l'avez déjà vu, c'est le mien.

Les carrés en noir et blanc représentent notre texture. C'est juste un damier de 2x2 texels blancs et noirs.

Le point orange est la coordonnée de texture du fragment en question. Le contour rouge est l'empreinte du fragment, qui est centrée sur les coordonnées de la texture.

Les cases vertes représentent les texels auxquels une implémentation de filtrage anisotrope pourrait accéder (les détails des algorithmes de filtrage anisotrope sont spécifiques à la plate-forme, je ne peux donc expliquer que l'idée générale).

Ce diagramme particulier suggère qu'une implémentation pourrait accéder à 4 texels. Oh oui, les cases vertes couvrent 7 d'entre elles, mais la case verte au centre pourrait être récupérée à partir d'une mipmap plus petite, récupérant ainsi l'équivalent de 4 texels en une seule extraction. L'implémentation pèserait bien sûr la moyenne de cette extraction de 4 par rapport à celles du texel unique.

Si la limite de filtrage anisotrope était de 2 plutôt que de 4 (ou plus), alors l'implémentation choisirait 2 de ces échantillons pour représenter l'empreinte du fragment.

Nicol Bolas
la source
Merci d'avoir expliqué cela et désolé pour la réponse tardive, mais j'ai dû trouver le temps de lire ceci très attentivement. J'ai l'impression que le seul paragraphe que je ne comprends pas complètement est celui où vous parlez de shaders de fragments et de dérivés. Qu'est-ce qui est exactement dérivé dans l'espace d'écran X et Y? Est-ce la valeur des coordonnées de texture?
Nicola Masotti
@NicolaMasotti: "Derivative" est un terme de calcul. Dans ce cas, c'est le taux de changement de la coordonnée de texture, à travers la surface du triangle, dans l'espace d'écran X ou Y. Si vous ne connaissez pas le calcul, alors je ne vais pas pouvoir l'expliquer à vous dans un seul post.
Nicol Bolas
Heureusement, je sais ce qu'est un dérivé. Y a-t-il un endroit où je peux regarder pour le calcul exact?
Nicola Masotti
Aussi, je proposerais quelques changements à votre réponse, c'est-à-dire " cela dépend de la façon dont le polygone est mappé à la texture " au lieu de " cela dépend de la façon dont la texture est mappée au polygone ". De plus, lorsque vous dites: " utiliser la couverture pour mettre à l'échelle les couleurs qui sont à la frontière ", voulez-vous dire en fait " les couleurs de poids qui sont à la frontière "?
Nicola Masotti
3

Quelques points que vous connaissez probablement déjà, mais que je veux simplement mettre à la disposition des autres qui liront ceci. Dans ce cas, le filtrage fait référence au filtrage passe-bas comme vous pourriez l'obtenir à partir d'un flou gaussien ou d'un flou de boîte. Nous devons le faire parce que nous prenons des médias qui contiennent des fréquences élevées et les rendons dans un espace plus petit. Si nous ne le filtrions pas, nous obtiendrions des artefacts d'alias, ce qui serait mauvais. Nous filtrons donc les fréquences trop élevées pour être reproduites avec précision dans la version mise à l'échelle. (Et nous passons les basses fréquences, nous utilisons donc un filtre "passe-bas" comme un flou.)

Alors réfléchissons d'abord à cela du point de vue du flou. Un flou est un type de convolution. Nous prenons le noyau de convolution et le multiplions par tous les pixels d'une zone, puis nous les additionnons et divisons par le poids. Cela nous donne la sortie d'un pixel. Ensuite, nous le déplaçons et le faisons à nouveau pour le pixel suivant, et encore, etc.

C'est vraiment cher de le faire de cette façon, donc il y a un moyen de tricher. Certains noyaux de convolution (en particulier un noyau de flou gaussien et un noyau de flou en boîte) peuvent être séparés en un passage horizontal et vertical. Vous pouvez tout filtrer avec juste un noyau horizontal d'abord, puis prendre le résultat de cela et le filtrer avec juste un noyau vertical, et le résultat sera identique à faire le calcul le plus cher à chaque point. Voici un exemple:

Original:

Hawaii

Flou horizontal:

Hawaii floue horizontalement

Horizontal suivi d'un flou vertical:

Hawaï flouté horizontalement puis verticalement

On peut donc séparer le filtrage en un passage vertical et horizontal. Et alors? Eh bien, il s'avère que nous pouvons faire la même chose pour les transformations spatiales. Si vous pensez à une rotation en perspective, comme ceci:

Hawaii tourné autour de l'axe Y

Il peut être décomposé en échelle X:

entrez la description de l'image ici

suivi d'une échelle de chaque colonne d'un montant légèrement différent:

Hawaii mis à l'échelle en X puis proportionnellement en Y

Alors maintenant, vous avez 2 opérations de mise à l'échelle différentes. Pour obtenir le filtrage correct pour cela, vous allez vouloir filtrer plus fortement dans X que dans Y, et vous allez vouloir filtrer par une quantité différente pour chaque colonne. La première colonne ne reçoit aucun filtrage car elle est de la même taille que l'original. La deuxième colonne obtient juste un peu parce qu'elle est juste légèrement plus petite que la première, etc. La dernière colonne obtient le plus de filtrage de toutes les colonnes.

Le mot "anisotropie" vient du grec "un" qui signifie "pas", "isos" qui signifie égal et "tropos" qui signifie "direction". Cela signifie donc «pas égal dans toutes les directions». Et c'est exactement ce que nous voyons - la mise à l'échelle et le filtrage sont effectués dans des quantités différentes dans chaque direction.

user1118321
la source