Je suis un peu confus. La documentation officielle ( http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588(v=vs.85).aspx ) dit que ddx (entrée) est la dérivée partielle de l'entrée avec respect à la "coordonnée x de l'espace d'écran".
Mon calcul est très bien, mais comment peut-il savoir d'où vient l'entrée? Si je lui passais une fonction, très bien, je peux imaginer ce que ça ferait, mais la dérivée d'un nombre est toujours nulle ...?
Est-ce juste une mise à l'échelle? Comme, cela serait redimensionné à un dixième de sa taille à cette distance, donc il renvoie un dixième? Mais alors il n'a pas besoin d'une entrée ...
Quelqu'un peut-il expliquer rapidement ce qui se passe réellement?
ddx
etddy
faites de la magie que vous ne pouvez pas faire vous-même. Ils ont accès à des informations supplémentaires à partir du pipeline de pixellisation que vous ne pouvez pas acquérir à partir d'un pixel shader. Je ne sais pas exactement quelle formule ils utilisent; J'ai été amené à croire qu'ils utilisent une technique d'estimation, mais je n'en suis pas sûr.ddx(5)
est un peu inutile. Utilisez-le avec une valeur d'entrée, et cela vous donnera la dérivée de cette valeur par rapport aux pixels voisins dans un bloc. Encore une fois, je ne sais pas avec précision comment il calcule les valeurs, mais demander la dérivée d'une non-entrée peut bien être un comportement non défini et produire des ordures. Voir fgiesen.wordpress.com/2011/07/10/… pour plus d'informations que je ne peux fournir.Réponses:
En interne, les GPU n'exécutent jamais une instance d'un pixel shader à la fois. Au niveau de granularité le plus fin, ils exécutent toujours 32 à 64 pixels en même temps en utilisant une architecture SIMD. Dans ce cadre, les pixels sont en outre organisés en 2x2 quads, de sorte que chaque groupe de 4 pixels consécutifs dans le vecteur SIMD correspond à un bloc de 2x2 pixels à l'écran.
Les dérivés sont calculés en prenant les différences entre les pixels d'un quadruple. Par exemple,
ddx
soustraira les valeurs des pixels du côté gauche du quadruple des valeurs du côté droit etddy
soustraira les pixels du bas des pixels du haut. Les différences peuvent ensuite être renvoyées sous forme de dérivée aux quatre pixels du quadruple.Étant donné que le pixel shader s'exécute dans SIMD, il est garanti que la valeur correspondante est dans le même registre en même temps pour tous les pixels du quad. Donc, quelle que soit l'expression ou la valeur que vous mettez
ddx
ouddy
, elle sera évaluée dans les quatre pixels du quad, puis les valeurs des différents pixels soustraites comme décrit ci-dessus.Donc, prendre la dérivée d'une valeur constante donnera zéro (comme vous vous attendez du calcul, non?) Parce que c'est la même valeur constante dans les quatre pixels.
Notez également qu'il existe des dérivés "grossiers" et "fins",
ddx_coarse
/ddy_coarse
etddx_fine
/ddy_fine
. Une explication de la distinction est donnée ici . Tout simplementddx
/ddy
sont des alias pour les versions grossières.BTW, la raison pour laquelle cette fonctionnalité existe est que les GPU doivent prendre en interne des dérivées des coordonnées de texture afin de faire une sélection mipmap et un filtrage anisotrope. Comme le matériel a quand même besoin de la capacité (vous pouvez utiliser n'importe quelle expression arbitraire pour les coordonnées de texture dans un shader), il était assez facile de l'exposer directement aux programmeurs de shader.
la source
ddx
fonctionne comme toutes les autres fonctions d'un langage de programmation traditionnel; vous évaluez l'entrée, la transformez en un flottant ou autre, puis vous lui faites la fonction extérieure (ddx
). Mais c'est différent: il prend la chaîne d' entrée , l'évalue à plusieurs endroits, calcule une dérivée et rapporte le résultat. C'est à peu près ça?ddx
à opérer sur l' expression que vous lui passez plutôt que sur la valeur .