2017-08-26 6 views
1

Ma question concerne spécifiquement Metal, car je ne sais pas si la réponse changerait pour une autre API.Comment les textures mipmapped sont-elles échantillonnées?

Ce que je crois que je comprends à ce jour est la suivante:

  • Une texture mipmappée a précalculées « niveaux de détail », où des niveaux plus détaillés sont créés par la texture originale sous-échantillonnage d'une manière significative.

  • Les niveaux de Mipmap sont référencés par niveau de détail descendant, où le niveau 0 est la texture d'origine, et les niveaux supérieurs sont des réductions de puissance de deux.

  • La plupart des GPU implémentent un filtrage trilinéaire, qui sélectionne deux niveaux de mipmap voisins pour chaque échantillon, des échantillons de chaque niveau utilisant un filtrage bilinéaire, puis fusionne linéairement ces échantillons.

Ce que je ne comprends pas très bien, c'est comment ces niveaux de mipmap sont sélectionnés. Dans le documentation pour la bibliothèque standard métallique, je vois que des échantillons peuvent être pris, avec ou sans spécifier une instance d'un type lod_options. Je suppose que cet argument modifie la façon dont les niveaux de mipmap sont sélectionnés, et il y a apparemment trois types de lod_options pour les textures 2D:

  • bias(float value)
  • level(float lod)
  • gradient2d(float2 dPdx, float2 dPdy)

Malheureusement, les la documentation ne prend pas la peine d'expliquer ce que font ces options. Je peux deviner que bias() préjuge un certain niveau de détail automatiquement choisi, mais alors qu'est-ce que le biais value signifie? Sur quelle échelle opère-t-il? De même, comment le lod de level() est-il traduit en niveaux de mipmap discrets? Et, opérant sous l'hypothèse que gradient2d() utilise le gradient de la coordonnée de texture, comment utilise-t-il ce gradient pour sélectionner le niveau mipmap? Plus important encore, si j'omets le lod_options, comment sont sélectionnés les niveaux de mipmap? Cela diffère-t-il selon le type de fonction en cours d'exécution? Et, si l'opération par défaut no-lod-options-specified de la fonction sample() est de faire quelque chose comme gradient2D() (au moins dans un fragment shader), utilise-t-elle de simples dérivées d'espace d'écran, ou fonctionne-t-elle directement? avec rasterizer et coordonnées interpolées de texture pour calculer un gradient précis?

Et enfin, quel est le degré de cohérence de ce comportement d'un périphérique à l'autre? Un vieil article (ancien comme dans DirectX 9) que j'ai lu se référait à la sélection de mipmap complexe spécifique au périphérique, mais je ne sais pas si la sélection de mipmap est mieux définie sur les nouvelles architectures.

Répondre

0

Ceci est un sujet relativement grand que vous pourriez être mieux demander à https://computergraphics.stackexchange.com/ mais, très brièvement, le document de Lance Williams "Pyramidal Parametrics" qui a introduit le filtrage trilinéaire et la « cartographie MIP » terme, a une suggestion qui venait de Paul Heckbert (voir page trois, première colonne) que je pense peut encore être utilisé, dans une certaine mesure, dans certains systèmes.En effet, les approches de calcul des niveaux de carte MIP reposent généralement sur l'hypothèse que votre pixel d'écran est un petit cercle et que ce cercle peut être mappé sur la texture pour obtenir, approximativement, une ellipse. Vous estimez la longueur de l'axe le plus long exprimée en texels de la carte de plus haute résolution. Cela vous indique alors quelles cartes MIP vous devriez échantillonner. Par exemple, si la longueur était de 6, c'est-à-dire entre 2^2 et 2^3, vous voudriez mélanger entre les niveaux de carte MIP 2 et 3.