Je vois les fonctions ddx
et ddy
glsl et les équivalents hlsl apparaissent de temps en temps dans le code shader. Je les utilise actuellement pour faire du bump mapping sans tangente ni bitangente mais j'ai essentiellement copié-collé le code. Je ne comprends pas ce que sont réellement ces fonctions, ce qu'elles font et quand je chercherais à les utiliser.
Alors des questions:
- Quelles sont les fonctions dérivées de l'espace d'écran?
- Que font ces fonctions? Les valeurs d'entrée et les valeurs de sortie
- Pour quels effets sont-ils le plus souvent utilisés?
- Quels types d'effets nécessitent que vous regardiez ces fonctions?
Réponses:
Tout d'abord, il est utile de savoir que les GPU évaluent toujours les shaders fragment / pixel sur des blocs de 2x2 pixels à la fois. (Même si seuls certains de ces pixels doivent finalement être dessinés, tandis que d'autres sont en dehors du polygone ou occlus - les fragments inutiles sont masqués au lieu d'être écrits à la fin).
La dérivée de l'espace d'écran d'une variable (ou expression)
v
dans votre shader est la différence de valeurv
(à ce point dans le code) d'un côté de ce quad 2x2 pixels à l'autre. c'est à dire.ddx
est la valeur dev
dans le pixel droit moins la valeur dev
dans la gauche, et de même pourddy
la verticale.Cela répond "à quelle vitesse
v
augmente ou diminue lorsque nous nous déplaçons horizontalement (ddx) ou verticalement (ddy) sur l'écran?" - c'est à dire. en termes de calcul, il rapproche les dérivées partielles de votre variable (approximative car elle utilise des échantillons discrets à chaque fragment, plutôt que d'évaluer mathématiquement le comportement infinitésimal de la fonction)Pour les quantités scalaires, nous pouvons également voir cela comme un vecteur de gradient
∇v = float2(ddx(v), ddy(v))
qui pointe le long de la direction de l'espace d'écran dans lequelv
augmente le plus rapidement.Ce type d'informations est souvent utilisé en interne pour sélectionner une mipmap appropriée ou un noyau de filtrage anisotrope pour les recherches de texture. Par exemple, si mon appareil photo semble presque parallèle à la
uv
direction verticale d'un plan de sol texturé,ddy(uv.y)
il sera très grand par rapport àddx(uv.x)
(puisque l'axe vertical est raccourci sur l'écran - une foulée de pixels recouvre verticalement une plus longue étendue d'espace de texture), ce qui indique au matériel d'échantillonnage de texture que j'ai besoin d'un filtrage anisotrope pour brouiller la direction de texture verticale plus que l'horizontale pour éviter les artefacts d'alias.Pour la plupart des effets simples, vous n'avez pas besoin d'utiliser ces dérivés, car les méthodes d'échantillonnage de texture 2D de base le gèrent pour vous. Mais comme Le Comte du Merde-fou le mentionne dans un commentaire ci-dessus, lorsque vous déformez vos recherches de texture, vous devrez peut-être récupérer et / ou masser manuellement les dérivés de l'espace d'écran à utiliser, pour aider le matériel à sélectionner le filtrage approprié (par exemple via
tex2Dlod
en HLSL)Les décalcomanies de l'espace d'écran sont un de ces cas, où un seul bloc 2x2 peut couvrir une grande discontinuité de saut dans la coordonnée de texture calculée, conduisant à un bord taché ou aliasé si vous laissez le système calculer le niveau de filtrage naïvement. Cet article décrit en détail cet artefact et les approches pour l'atténuer .
Ces dérivés peuvent également être utiles lorsque vous utilisez des fonctions de bruit dans la génération de texture procédurale. Si, par exemple, vous vouliez transformer le bruit procédural en une carte normale, ddx & ddy donnent un moyen simple, si approximatif, de calculer comment la valeur du bruit change au voisinage du fragment actuel, et de quelle façon il est en pente, donc vous peut construire une normale appropriée.
Les techniques de rendu des lignes anticrénelées ou des reflets d'intersection peuvent également utiliser des dérivés d'espace d'écran, pour garantir que l'épaisseur / l'atténuation est cohérente et ne dépend pas de la géométrie ou de l'angle de vue.
Dans cet exposé sur le rendu du sable dans Journey , le conférencier mentionne qu'il aurait pu utiliser ces fonctions dérivées pour contrôler l'étincelle du sable le long des bords brillants ... s'ils l'avaient connu à l'époque (à la place, ils ont utilisé une astuce de mipmapping, qui sous le capot est alimenté par ces types de dérivés de toute façon)
Une dernière remarque à prendre en compte: les dérivés de l'espace d'écran peuvent être calculés à "grossier" / faible précision (ce qui signifie qu'une paire de dérivés est partagée par l'ensemble du quad) ou "fin" / haute précision (ce qui signifie que chaque pixel n'est comparé qu'à son immédiat voisins dans le quad, ce qui pourrait donner quatre paires de dérivées distinctes sur le quad). Le grossier est généralement suffisant, mais si vous remarquez que vous obtenez des blocs 2x2 visibles dans votre effet, c'est un bon indice que vous souhaitez passer à la précision fine / haute. ;)
(Dans le diagramme en haut, j'ai utilisé des calculs pour les dérivés fins, mais attention, juste ddx / ddy seuls peuvent par défaut être des dérivés grossiers)
la source
v
ici), et comme c'est un quad 2x2, il n'y a pas de pixels entre les deux. Donc, si nous ombrons le fragment en haut à gauche du quad, et v = 1 là-bas, et dans le fragment en haut à droite v = 4, alors ddx (v) = 3 (en disant "v augmente de 3 à mesure que nous nous déplaçons de gauche à droite ")