glsl - Explicación de dFdx
derivative (1)
Para comprender cómo funcionan estas instrucciones, es útil comprender la arquitectura de ejecución básica de las GPU y cómo se relacionan los programas de fragmentación con esa arquitectura.
Las GPU ejecutan varios subprocesos en ''paso de bloqueo'' sobre el mismo programa, y cada subproceso tiene su propio conjunto de registros. Por lo tanto, obtiene una instrucción, luego ejecuta esa instrucción N veces, una vez por cada hilo en ejecución. Para tratar con ramas condicionales y tal, también tienen una ''máscara activa'' para el grupo de hilos que se está ejecutando actualmente. Los subprocesos que no están activos en la máscara en realidad no se ejecutan (por lo que sus registros no cambian). Siempre que haya una rama condicional o una unión (sucursal), la máscara del hilo se cambiará de manera apropiada.
Ahora, cuando se ejecuta un programa de fragmentos, los fragmentos que se ejecutarán se organizan en "cuadrantes": 2x2 cuadrados de 4 píxeles que siempre se ejecutan juntos en un grupo de hilos. Cada hilo en el grupo conoce su propia coordenada de píxel, y puede encontrar fácilmente la coordenada del píxel adyacente en el cuadrilátero volteando el bit más bajo de la coordenada x (o y).
Cuando la GPU ejecuta una instrucción DDX o DDY, lo que sucede es que se asoma a los registros de la secuencia para el píxel adyacente y hace un resta con el valor del píxel actual, restando el valor de la coordenada más alta (bit más bajo 1 ) desde el bit más bajo (más bajo 0).
Esto tiene implicaciones si usas dFdx
o dFdy
en una rama condicional: si uno de los hilos en un quad está activo mientras que el otro no, la GPU seguirá mirando el registro del hilo inactivo, que podría tener cualquier valor anterior. en ella, por lo que el resultado podría ser cualquier cosa.
Estoy tratando de entender las funciones dFdx y dFdy en GLSL.
Entiendo lo siguiente:
- La derivada es la tasa de cambio
- La derivada parcial de una función con dos parámetros es cuando se diferencia la función manteniendo constante uno de los parámetros.
- dFdx y dFdy encuentran la velocidad a la que cambia un valor entre el fragmento actual y un fragmento vecino.
No entiendo a qué se refiere la tasa de cambio. ¿Es la tasa de cambio de las coordenadas de los fragmentos?
¿Es posible que puedas encontrar la tasa de cambio de una variable arbitraria entre dos invocaciones del fragmento sombreador? ¿Las invocaciones del sombreador "leen" variables de invokations vecinas? Para un ejemplo (simplista):
// invokation for fragment 1
float x = 1.0;
float d = dFdx(x);
// invokation for fragment next to fragment 1 along the x axis.
float x = 2.0;
float d = dFdx(x);
Sería d -1.0 y 1.0 respectivamente?