Formes de filtrage:
On a grosso modo, deux techniques orthogonales pour réduire l'aliasing (spatial, un petit peu temporel) qui sont le supersampling (ou sa forme rapide le multisampling), et le mipmapping (associé au filtrage trilinéaire pour limiter la transition abrupte entre les niveaux de mip mapping).
Je passe sur le supersampling (multisampling) qui a l'efficacité qu'on lui demande. (modulo les problèmes de flou apportées par des formes de filtrage pas optimales mais qui font le boulot précité)
Reste le mipmapping.
Cette solution est très rapide mais assez peu satisfaisante pour diverses raisons.
La premiere c'est la position des différents niveaux de mipmapping. Entre deux niveaux différents de mip mapping il y a souvent une grande distance à l'écran parce que la gradation entre les niveaux n'est pas "continue" mais va par puissances de deux pour des raisons pratiques. Chaque niveau de mipmapping a donc une seule et unique position (orientation, niveau d'agrandissement) ou elle est "parfaite" (sans prendre en compte les problèmes liés à la génération des mipmaps ce qui est une autre discussion). Partout ailleurs elle est soit trop floue, soit ne réduit pas assez l'aliasing (y compris temporel -> effets de vaguelettes).
Quand je dis que c'est soit l'un soit l'autre, c'est exactement cela, il y a des compromis possibles mais où l'on souffre des deux effets simultanément!
Le deuxième problème bien connu depuis l'arrivée des Voodoo, c'est l'effet de séparation entre les niveaux de mip mapping, la solution actuelle adoptée par tous les hardware graphiques c'est de faire un fondu linéaire entre deux niveaux successifs, ajoutant un niveau trop filtré et un niveau pas assez filtré sur une bande plus ou moins large (sélectionnée par ce qu'on appelle la "rampe trilinéaire" programmable sur les derniers hardware suivant la nature de la texture).
Une autre solution aurait été de rajouter des niveaux de mip mapping (2/3 de la taille par exemple à la place de 1/2). Cela pose plusieurs problèmes. Il faut plus de mémoire pour stocker potentiellement plus de niveaux différents, les calculs sont plus compliqués et la cohérence des caches est moins préservée (puisque l'autre intéret du mipmapping est la performance).
Pour réduire le problème de l'orientation, on a inventé le filtrage anisotropique. Cette forme de filtrage calcule l'empreinte du pixel samplé sur la texture. Cette empreinte est souvent rapportée à une ellipse pour réduire le nombre de texels et de niveaux de mipmaps potentiellement concernés. Le niveau maximal lit 8 fois plus de samples par pixel en fonction de l'empreinte calculée ce qui correspond au ratio entre le petit axe et le grand axe de l'ellipse.
Je n'ai rien de particulier à redire contre cette technique, elle commence à être bien maitrisée même si son coût global peut être réduit par une bonne analyse globale des textures et un algo adaptatif qui limite les plus hauts rapports d'anisotropie aux triangles observés sous un angle fort.
Ceci dit ça n'élimine pas entièrement le problème lié au mip mapping. Par exemple l'observation de n'importe quelle texture avec des lignes fines en mouvement va provoquer un sentiment désagréable et ceci sous n'importe quel angle (amplifié avec l'anisotropic filtering). Tout simplement parce que le biais générique privilégie la précision du texturing contre l'effet d'élimination de l'aliasing (et que son élimination totale requererait des niveaux de flous généralement considérés comme inacceptables).
Ceci dit la plupart des lignes abruptes présentes à l'écran sont généralement issues de la géométrie plutôt que des textures et ce problème n'est soluble par aucune méthode de filtrage mais plutot par le super(multi)-sampling (avec ou sans perte).
Quelle serait donc une bonne forme de filtrage ?
Question difficile pour laquelle on n'aura probablement pas de réponse avant quelques temps.
L'autre grand probleme du mip mapping c'est qu'il est pensé en terme de transfert purement linéaire (éventuellement modulé par le gamma lors du filtering mais les niveaux de mip mapping ne sont généralement pas affecté par le gamma).
Autrement dit, lorsque je lis un texel au niveau 1, c'est sensé être la combinaison linéaire de texels correspondant du niveau 0.
Ce qui est vrai pour la diffusion (modele le plus couramment utilisé avant l'arrivée des pixel shaders) et encore uniquement si on adopte un transfert linéaire entre la l'illumination d'un pixel entre son écriture dans le frame buffer et l'affichage sur l'écran (hors HDR donc).
Pour toute autre utilisation des textures (normal map, gloss map, iridescence, fresnel etc..) cela n'est plus correct.
Par exemple si j'ai une texture qui une perturbation des normales d'une surface pour une réfraction. La version rétrécie du niveau 1 correspondra a une moyenne pondérée des normales mais le résultat à l'écran ne correspondra à rien par rapport au même modèle affiché avec le niveau zéro de la mipmap.
De meme si j'ai une texture diffuse que j'utilise dans un modèle HDR (high dynamic range), la combinaison linéaire entre blanc et noir peut très bien être blanche ou noire alors que gris serait la bonne réponse.
S'il devait y avoir un mipmap il ne devrait donc pas stocker la donnée source mais la donnée résultat qui détermine la couleur finale du pixel (si jamais cela était possible avec tous les traitements intérmédiaires y compris traitements NPR (imagerie non photorealiste) )
Je continue avec la liste des doléances avec la fameuse bavure des couleurs. Si j'ai un triangle texturé en noir, la texture d'où il provient est bien noire sur l'empreinte du triangle sur la texture et blanc partout ailleurs (parce que la texture sert à texturer d'autres objets). Cela n'est malheureusement plus vrai au niveau 1, 2 et encore moins 3. La réduction n'a pas tenu compte des informations de géométrie et a fait baver les couleurs destinées à d'autres triangles dans mon triangle noir.
La liste des problèmes est assez importante et contraint pas mal la production d'art dans les jeux et limite la qualité visuelle maximale que l'on puisse attendre d'un simple polygone texturé.
LeGreg