¿Qué hace realmente ddx (hlsl)?

17

Estoy un poco confundido. La documentación oficial ( http://msdn.microsoft.com/en-us/library/windows/desktop/bb509588(v=vs.85).aspx ) dice que ddx (input) es la derivada parcial de la entrada con respecto a la "coordenada x del espacio de pantalla".

Mi cálculo está bien, pero ¿cómo puede saber de dónde proviene la entrada? Si le pasara una función, bien, puedo imaginar lo que haría, pero la derivada de un número siempre es cero ...

¿Es solo una escala? Como, esto se escalará a una décima parte de su tamaño a esta distancia, ¿entonces devuelve una décima parte? Pero entonces no necesita una entrada ...

¿Alguien puede dar una explicación rápida de lo que realmente está sucediendo?

Richard Rast
fuente
2
ddxy ddyhaz magia que no puedes hacer tú mismo. Tienen acceso a información adicional de la canalización de rasterización que no puede adquirir desde un sombreador de píxeles. No estoy seguro exactamente qué fórmula usan; Me han hecho creer que usan una técnica de estimación, pero no estoy seguro.
Sean Middleditch
Eso es profundamente extraño, pero aún así. ¿Qué representa realmente ddx (5)? Si dice .1, ¿cómo debo interpretar eso? O -6?
Richard Rast
1
ddx(5)Es un poco inútil. Úselo con un valor de entrada, y eso le dará la derivada de ese valor con respecto a los píxeles vecinos en un bloque. Nuevamente, no sé con qué precisión calcula los valores, pero pedir la derivada de una no entrada puede ser un comportamiento indefinido y generar basura. Consulte fgiesen.wordpress.com/2011/07/10/… para obtener más información de la que puedo proporcionar.
Sean Middleditch
No estoy seguro, pero bien podría ser que el compilador HLSL realmente esté haciendo una diferenciación simbólica completa de la expresión que pasa a ddx / ddy. blogs.msdn.com/b/chuckw/archive/2011/03/08/… research.microsoft.com/pubs/146019/…
Ziriax
¿Qué hace? La ÚNICA cosa un poco razonable, obviamente.
MickLH

Respuestas:

32

Internamente, las GPU nunca ejecutan una instancia de un sombreador de píxeles a la vez. Al mejor nivel de granularidad, siempre ejecutan 32-64 píxeles al mismo tiempo utilizando una arquitectura SIMD. Dentro de esto, los píxeles se organizan en cuadrículas de 2x2, por lo que cada grupo de 4 píxeles consecutivos en el vector SIMD corresponde a un bloque de píxeles de 2x2 en la pantalla.

Los derivados se calculan tomando las diferencias entre los píxeles en un quad. Por ejemplo, ddxrestará los valores en los píxeles en el lado izquierdo del quad de los valores en el lado derecho, y ddyrestará los píxeles inferiores de los superiores. Las diferencias se pueden devolver como la derivada a los cuatro píxeles en el quad.

Dado que el sombreador de píxeles se ejecuta en SIMD, se garantiza que el valor correspondiente esté en el mismo registro al mismo tiempo para todos los píxeles en el quad. Entonces, sea cual sea la expresión o el valor que coloque ddxo ddy, se evaluará en los cuatro píxeles del quad, luego los valores de los diferentes píxeles se restarán como se describe anteriormente.

Por lo tanto, tomar la derivada de un valor constante dará cero (como es de esperar del cálculo, ¿verdad?) Porque es el mismo valor constante en los cuatro píxeles.

También tenga en cuenta que hay derivados "gruesos" y "finos", ddx_coarse/ ddy_coarsey ddx_fine/ ddy_fine. Aquí se da una explicación de la distinción . Simplemente liso ddx/ ddyson alias para las versiones burdas.

Por cierto, la razón por la que existe esta funcionalidad es que las GPU tienen que tomar internamente derivadas de coordenadas de textura para hacer la selección de mapas MIP y el filtrado anisotrópico. Como el hardware necesita la capacidad de todos modos (puede usar cualquier expresión arbitraria para coordenadas de textura en un sombreador), fue bastante fácil exponerlo directamente a los programadores de sombreadores.

Nathan Reed
fuente
+1; He encontrado esto útil al aplicar un efecto de perturbación a una textura; los texcoords perturbados dieron cierta distorsión de color, pero el uso de tex2Dgrad con derivados de los texcoords originales (no perturbados) dio un resultado sin distorsiones.
Maximus Minimus
Muy bien, después de pensarlo, creo que descubrí mi confusión. En mi opinión, ddxfunciona como cualquier otra función en un lenguaje de programación tradicional; evalúa la entrada, la convierte en flotante o lo que sea, luego realiza la función externa ( ddx). Pero esto es diferente: toma la cadena de entrada , la evalúa en varios lugares, calcula una derivada e informa el resultado. ¿Eso es correcto?
Richard Rast
1
@RichardRast Derecha. Puede pensar ddxque opera en la expresión que le pasa, en lugar del valor .
Nathan Reed
Pero mira, eso es lo suficientemente extraño como para que esté en la documentación. No puedo pensar en ningún otro momento en mi vida de programación donde ese haya sido el caso.
Richard Rast
Nathan Reed mencionó que las GPU usan estas funciones para la selección de mipmap. También puede usarlos para forzar a la GPU a seleccionar un nivel de mipmap deseado o para evitar que los artefactos seleccionen incorrectamente el nivel de mip. El proceso se describe en las páginas 163 y 164 de Shader X3.
JamesHoux