Comment le filtrage anisotrope est-il généralement implémenté dans les GPU modernes?

14

Le filtrage anisotrope "conserve la netteté d'une texture normalement perdue par les tentatives de texture de carte MIP pour éviter l'aliasing". L'article de Wikipedia donne des conseils sur la façon dont il peut être mis en œuvre ("sonder la texture (...) pour toute orientation de l'anisotropie"), mais il ne me semble pas très clair.

Il semble y avoir diverses implémentations, comme le suggèrent les tests illustrés dans les notes de la présentation Modèles approximatifs pour le rendu basé physiquement : entrez la description de l'image ici

Quels sont les calculs concrets effectués par les GPU (modernes) pour choisir le niveau MIP correct lors de l'utilisation du filtrage anisotrope?

essuyer
la source
3
La spécification GL_EXT_texture_filter_anisotropicest très détaillée. Cela pourrait peut-être vous aider à mieux comprendre le processus.
glampert

Réponses:

14

Le matériel de filtrage de texture prend plusieurs échantillons des différents niveaux de mipmap (la quantité maximale d'échantillons est indiquée par le niveau de filtrage anisotrope, bien que la quantité exacte d'échantillons prélevés dans une opération de filtrage donnée dépendra de la proportion entre les dérivés sur le fragment. ) Si vous projetez le cône en regardant une surface à un angle oblique sur l'espace de texture, il en résultera approximativement une projection de forme ovale, qui est plus allongée pour des angles plus obliques. Des échantillons supplémentaires sont prélevés le long de l'axe de cet ovale (à partir des niveaux de mip corrects, pour profiter du pré-filtrage qu'ils offrent) et combinés pour donner un échantillon de texture plus nette.

Une autre technique connue sous le nom de rip-mapping (mentionnée dans l'article Wikipedia sur le mipmapping), qui n'est pascouramment utilisé dans les GPU contemporains, utilise le préfiltrage des textures. Contrairement aux mips, la texture n'est pas réduite uniformément mais en utilisant divers rapports hauteur-largeur (jusqu'à un rapport dépendant du niveau de filtrage anisotrope que vous avez choisi). La variante - ou peut-être deux variantes si vous utilisez le filtrage trilinéaire - de la texture est alors choisie en fonction de l'angle de la surface pour minimiser la distorsion. Les valeurs des pixels sont extraites en utilisant des techniques de filtrage par défaut (bilinéaire ou trilinéaire). Les rip-maps ne sont utilisées dans aucun matériel que je connaisse en raison de leur taille prohibitive: alors que les mipmaps utilisent 33% de stockage supplémentaire, les ripmaps en utilisent 300%. Cela peut être vérifié en notant que les exigences d'utilisation de la texture n'augmentent pas lors de l'utilisation de l'AF, mais uniquement la bande passante.

Pour une lecture ultérieure, vous voudrez peut-être jeter un œil aux spécifications de l' extension OpenGL EXT_texture_filter_anisotropic . Il détaille les formules utilisées pour calculer les échantillons et comment les combiner lors de l'utilisation du filtrage anisotrope.

yuriks
la source
5
Les cartes RIP ne sont probablement pas non plus utilisées car elles n'aident pas le cas diagonal plutôt commun. FWIW, si vous pouvez trouver le code du Microsoft Refrast, l'implémentation du filtre anistropique dans ce document est probablement une bonne référence pour la façon dont le HW d'aujourd'hui le fait.
Simon F
1
"Cela peut être vérifié en notant que les exigences d'utilisation de la texture n'augmentent pas lors de l'utilisation de l'AF, mais uniquement la bande passante." Argument tueur. Bonne réponse!
David Kuri
Le lien "Rastérisation logicielle hautes performances sur GPU" ne mentionne qu'une seule fois le filtrage anisotrope et ne mentionne aucun détail. Je vais donc le supprimer de la réponse parce que je ne pense pas que ce soit utile d'une manière utile.
yuriks
@SimonF nous pouvons également ajouter que l'exigence de bande passante supplémentaire est assez effrayante.
v.oddou
9

Les exigences de l'API peuvent être trouvées dans l'une des spécifications ou extensions. En voici un: https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt

Tous les fournisseurs de GPU s'écartent probablement de la spécification car la qualité AF faisait partie de nombreux benchmarks. Et les implémentations actuelles continueront d'évoluer à mesure que les nouvelles charges de travail mettront l'accent sur les approximations existantes. Malheureusement, pour savoir exactement ce que l'un ou l'autre fait, vous devrez faire partie de l'une des sociétés. Mais vous pouvez évaluer le spectre des possibilités à partir des articles suivants, classés par ordre croissant de qualité et de coût de mise en œuvre:

Citant de la spécification:

 Anisotropic texture filtering substantially changes Section 3.8.5.
 Previously a single scale factor P was determined based on the
 pixel's projection into texture space.  Now two scale factors,
 Px and Py, are computed.

   Px = sqrt(dudx^2 + dvdx^2)
   Py = sqrt(dudy^2 + dvdy^2)

   Pmax = max(Px,Py)
   Pmin = min(Px,Py)

   N = min(ceil(Pmax/Pmin),maxAniso)
   Lamda' = log2(Pmax/N)

 where maxAniso is the smaller of the texture's value of
 TEXTURE_MAX_ANISOTROPY_EXT or the implementation-defined value of
 MAX_TEXTURE_MAX_ANISOTROPY_EXT.

 It is acceptable for implementation to round 'N' up to the nearest
 supported sampling rate.  For example an implementation may only
 support power-of-two sampling rates.

 It is also acceptable for an implementation to approximate the ideal
 functions Px and Py with functions Fx and Fy subject to the following
 conditions:

   1.  Fx is continuous and monotonically increasing in |du/dx| and |dv/dx|.
       Fy is continuous and monotonically increasing in |du/dy| and |dv/dy|.

   2.  max(|du/dx|,|dv/dx|} <= Fx <= |du/dx| + |dv/dx|.
       max(|du/dy|,|dv/dy|} <= Fy <= |du/dy| + |dv/dy|.

 Instead of a single sample, Tau, at (u,v,Lamda), 'N' locations in the mipmap
 at LOD Lamda, are sampled within the texture footprint of the pixel.

 Instead of a single sample, Tau, at (u,v,lambda), 'N' locations in
 the mipmap at LOD Lamda are sampled within the texture footprint of
 the pixel.  This sum TauAniso is defined using the single sample Tau.
 When the texture's value of TEXTURE_MAX_ANISOTROPHY_EXT is greater
 than 1.0, use TauAniso instead of Tau to determine the fragment's
 texture value.

                i=N
                ---
 TauAniso = 1/N \ Tau(u(x - 1/2 + i/(N+1), y), v(x - 1/2 + i/(N+1), y)),  Px > Py
                /
                ---
                i=1

                i=N
                ---
 TauAniso = 1/N \ Tau(u(x, y - 1/2 + i/(N+1)), v(x, y - 1/2 + i/(N+1))),  Py >= Px
                /
                ---
                i=1


 It is acceptable to approximate the u and v functions with equally spaced
 samples in texture space at LOD Lamda:

                i=N
                ---
 TauAniso = 1/N \ Tau(u(x,y)+dudx(i/(N+1)-1/2), v(x,y)+dvdx(i/(N+1)-1/2)), Px > Py
                /
                ---
                i=1

                i=N
                ---
 TauAniso = 1/N \ Tau(u(x,y)+dudy(i/(N+1)-1/2), v(x,y)+dvdy(i/(N+1)-1/2)), Py >= Px
                /
                ---
                i=1 
ap_
la source