Ma question concerne spécifiquement Metal, car je ne sais pas si la réponse changerait pour une autre API.
Ce que je crois comprendre jusqu'à présent est le suivant:
Une texture mipmappée a des "niveaux de détail" précalculés, où des niveaux de détail inférieurs sont créés en sous-échantillonnant la texture d'origine de manière significative.
Les niveaux Mipmap sont référencés dans un niveau de détail décroissant, 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 mipmap voisins pour chaque échantillon, des échantillons de chaque niveau à l'aide du filtrage bilinéaire, puis fusionne linéairement ces échantillons.
Ce que je ne comprends pas vraiment, c'est comment ces niveaux de mipmap sont sélectionnés. Dans la documentation de la bibliothèque standard Metal, je constate que des échantillons peuvent être prélevés, avec ou sans spécification d'une instance d'un lod_options
type. Je suppose que cet argument change la façon dont les niveaux de mipmap sont sélectionnés, et il existe apparemment trois types de lod_options
textures 2D:
bias(float value)
level(float lod)
gradient2d(float2 dPdx, float2 dPdy)
Malheureusement, la documentation ne prend pas la peine d'expliquer ce que font ces options. Je peux deviner que cela bias()
biaise un niveau de détail choisi automatiquement, mais alors qu'est-ce que le biais value
signifie? À quelle échelle fonctionne-t-il? De même, comment le lod
of est-il level()
traduit en niveaux mipmap discrets? Et, fonctionnant sous l'hypothèse qui gradient2d()
utilise le dégradé de la coordonnée de texture, comment utilise-t-il ce dégradé pour sélectionner le niveau mipmap?
Plus important encore, si j'omets le lod_options
, comment les niveaux mipmap sont-ils alors sélectionnés? Cela diffère-t-il selon le type de fonction en cours d'exécution?
Et, si l'opération par défaut spécifiée par no-lod-options sample()
est de faire quelque chose comme gradient2D()
(au moins dans un shader de fragments), utilise-t-elle de simples dérivées d'espace d'écran ou fonctionne-t-elle directement avec un rastériseur et des coordonnées de texture interpolées calculer un gradient précis?
Et enfin, quelle est la cohérence de ce comportement d'un appareil à l'autre? Un vieil article (ancien comme dans DirectX 9) que j'ai lu faisait référence à une sélection mipmap complexe spécifique à un périphérique, mais je ne sais pas si la sélection mipmap est mieux définie sur les architectures plus récentes.