¿Cómo sabe el sombreador de fragmentos qué variable usar para el color de un píxel?


Veo muchos sombreadores de fragmentos diferentes,

#version 130

out vec4 flatColor;

void main(void)
{
    flatColor = vec4(0.0,1.0,0.0,0.5);
}

Y todos ellos usan una variable diferente para el "out color" (en este caso flatColor). Entonces, ¿cómo sabe OpenGL lo que estás tratando de hacer?

Supongo que esto funciona porque flatColor es la única variable definida como out, pero se le permite agregar más out variables ¿no es así? ¿O simplemente se estrellaría?


En realidad, como prueba, acabo de ejecutar esto:

#version 330

in vec2 TexCoord0;

uniform sampler2D TexSampler;

out vec4 x;
out vec4 y;

void main()
{
    y = texture2D(TexSampler, TexCoord0.xy);
}

Funcionó bien si usé x o y.


Además, tenemos un gl_FragColor predefinido. ¿Cuál es la diferencia, y por qué la gente suele insistir en el uso de sus propias variables?

 68
Author: mpen, 2012-02-10

2 answers

Además, tenemos un gl_FragColor predefinido.

Comencemos con esto. No, tú no tienes el gl_FragColor predefinido. Eso se eliminó del núcleo de OpenGL 3.1 y superior. A menos que estés usando compatibilidad (en cuyo caso, tus shaders 3.30 deberían decir #version 330 compatibility en la parte superior), nunca deberías usar esto.

Ahora, de vuelta a las salidas de sombreado de fragmentos definidas por el usuario. Pero primero, una rápida analogía.

¿Recuerdas cómo, en los sombreadores de vértices, tienes entradas? Y estas entradas representan índices de atributos de vértices, los números que pasa a glVertexAttribPointer y glEnableVertexAttribArray y así sucesivamente? Configura qué entrada extrae de qué atributo. En GLSL 3.30, se utiliza esta sintaxis:

layout(location = 2) in color;

Esto establece que la entrada del sombreador de vértices color provenga de la ubicación del atributo 2. Antes de la versión 3.30 (o sin ARB_explicit_attrib_location), tendría que configurar esto explícitamente con glBindAttrbLocation antes de enlazar o consultar el programa para el índice de atributos con glGetAttribLocation. Si si no proporciona explícitamente una ubicación de atributo, GLSL asignará una ubicación arbitrariamente (es decir: de una manera definida por la implementación).

Configurarlo en el sombreador es casi siempre la mejor opción.

En cualquier caso, las salidas del sombreador de fragmentos funcionan casi exactamente de la misma manera. Los sombreadores de fragmentos pueden escribir en múltiples colores de salida, que a su vez se asignan a múltiples búferes en el framebuffer. Por lo tanto, debe indicar qué salida va a qué color de salida de fragmento.

Este proceso comienza con el valor de ubicación de salida del fragmento. Se establece de manera muy similar a las ubicaciones de entrada de vertex shader:

layout(location = 1) out secColor;

Hay también las funciones de la API glBindFragDataLocation y glGetFragDataLocation, que son análogos a glBindAttribLocation y glGetAttribLocation.

Si no realiza ninguna asignación explícita, las implementaciones generalmente asignarán una de sus variables de salida a la ubicación 0. Sin embargo, el estándar OpenGL no requiere este comportamiento, por lo que no debe depender de él tampoco.

Ahora, para ser justos, su programa debería tener falló para enlazar cuando usó dos salidas que no obtuvieron diferentes ubicaciones de salida. Lo que probablemente sucedió fue que tu compilador optimizó el que no escribiste, por lo que se olvidó de él cuando llegó el momento de verificar los errores del enlazador.

 127
Author: Nicol Bolas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-22 03:15:38

Me gustaría especificar esto para OpenGLES 3.1 que usa GLSL_ES_3. 10 link :

§4.4.2

Si solo hay una salida única [en el sombreador de fragmentos], el no es necesario especificar la ubicación, en cuyo caso el valor predeterminado es cero.

 7
Author: Lorenzo Belli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-26 11:56:38