rojo que primarios mezclar los hacer hace forman con como colores color cafe azul amarillo opengl shader glsl fragment-shader

opengl - primarios - que colores forman el amarillo



¿Cómo obtengo el color actual de un fragmento? (7)

Debe muestrear la textura en las coordenadas de píxel actuales, algo como esto

vec4 pixel_color = texture2D(tex, gl_TexCoord[0].xy);

Tenga en cuenta que, como he visto que texture2D está en desuso en la especificación GLSL 4.00, simplemente busque texturas similares ... funciones de búsqueda.

También a veces es mejor proporcionar tus propias coordenadas de píxeles en lugar de gl_TexCoord [0] .xy - en ese caso escribe el sombreador de vértices algo así como:

varying vec2 texCoord; void main(void) { gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0 ); texCoord = 0.5 * gl_Position.xy + vec2(0.5); }

Y en el sombreador de fragmentos use esa variable texCoord en lugar de gl_TexCoord [0] .xy.

Buena suerte.

Estoy tratando de entender los sombreadores en GLSL, y he encontrado algunos recursos útiles y tutoriales, pero me sigo tropezando con una pared por algo que debería ser fundamental y trivial: ¿cómo recupera el color el sombreador de fragmentos? el fragmento actual?

Estableces el color final diciendo gl_FragColor = whatever , pero aparentemente ese es un valor solo de salida. ¿Cómo se obtiene el color original de la entrada para que pueda realizar cálculos sobre ella? Eso tiene que ser una variable en alguna parte, pero si alguien conoce su nombre, parece que no lo han grabado en ningún tutorial o documentación con la que haya tropezado hasta ahora, y eso me está volviendo loco.


El punto entero de su sombreador de fragmentos es decidir cuál es el color de salida. Cómo lo haces depende de lo que estás tratando de hacer.

Puede optar por configurar las cosas para obtener un color interpolado basado en la salida del sombreador de vértices, pero un enfoque más común sería realizar una búsqueda de textura en el sombreador de fragmentos utilizando las coordenadas de textura pasadas en los vertex shader interpolants . Luego modificaría el resultado de la búsqueda de textura de acuerdo con los cálculos de iluminación elegidos y cualquier otra cosa que su sombreador debe hacer y luego lo escribirá en gl_FragColor.


El sombreador de fragmentos recibe gl_Color y gl_SecondaryColor como atributos de vértice. También obtiene cuatro variables variables: gl_FrontColor , gl_FrontSecondaryColor , gl_BackColor y gl_BackSecondaryColor que puede escribir valores. Si quieres pasar los colores originales directamente, harías algo como:

gl_FrontColor = gl_Color; gl_FrontSecondaryColor = gl_SecondaryColor; gl_BackColor = gl_Color; gl_BackSecondaryColor = gl_SecondaryColor;

La funcionalidad fija en la tubería que sigue al sombreador de vértices los fijará al rango [0..1] y determinará si el vértice está orientado hacia adelante o hacia atrás. Luego, interpolará el color elegido (frontal o posterior) como siempre. El sombreador de fragmentos recibirá entonces los colores elegidos, gl_Color e interpolados como gl_Color y gl_SecondaryColor .

Por ejemplo, si dibujaste el "triángulo de la muerte" estándar como:

glBegin(GL_TRIANGLES); glColor3f(0.0f, 0.0f, 1.0f); glVertex3f(-1.0f, 0.0f, -1.0f); glColor3f(0.0f, 1.0f, 0.0f); glVertex3f(1.0f, 0.0f, -1.0f); glColor3f(1.0f, 0.0f, 0.0f); glVertex3d(0.0, -1.0, -1.0); glEnd();

Entonces un sombreador de vértices como este:

void main(void) { gl_Position = ftransform(); gl_FrontColor = gl_Color; }

con un sombreador de fragmentos como este:

void main() { gl_FragColor = gl_Color; }

transmitirá los colores, como si estuvieras usando la tubería de funcionalidad fija.


La interconexión de GPU tiene acceso a la información de píxeles subyacente inmediatamente después de que se ejecutan los sombreadores. Si su material es transparente, la etapa de fusión de la tubería combinará todos los fragmentos.

En general, los objetos se mezclan en el orden en que se agregan a una escena, a menos que hayan sido ordenados por un algoritmo z-buffering. Primero debe agregar sus objetos opacos, luego agregue cuidadosamente sus objetos transparentes en el orden en que se mezclarán.

Por ejemplo, si desea una superposición de HUD en su escena, debe simplemente crear un objeto quad de pantalla con una textura transparente apropiada y agregarlo a su escena al final.

Configurar las funciones de fusión de SRC y DST para objetos transparentes le da acceso a la combinación anterior de muchas maneras diferentes.

Puede usar la propiedad alfa de su color de salida aquí para hacer mezclas realmente sofisticadas. Esta es la forma más eficiente de acceder a las salidas del framebuffer (píxeles), ya que funciona en una sola pasada (Fig. 1) de la tubería de la GPU.


Fig. 1 - Pase único

Si realmente necesita múltiples pasadas (Fig. 2), debe apuntar las salidas del framebuffer a una unidad de textura extra en lugar de a la pantalla, y copie esta textura objetivo a la próxima pasada, y así sucesivamente, apuntando a la pantalla en el pase final . Cada pase requiere al menos dos conmutadores de contexto.

La copia adicional y el cambio de contexto degradarán severamente el rendimiento del renderizado. Tenga en cuenta que las tuberías de GPU de subprocesos múltiples no son de mucha ayuda aquí, ya que el paso múltiple se serializa intrínsecamente.


Fig. 2 - Pase múltiple

He recurrido a una descripción verbal con diagramas de tuberías para evitar la desaprobación, ya que el lenguaje de sombreado (jerga / GLSL) está sujeto a cambios.


Si desea hacer una renderización de múltiples pasos, es decir, si ha renderizado en el framebuffer y quiere un segundo pase de renderizado donde usa el renderizado anterior, la respuesta es:

  1. Renderiza el primer pase a una textura
  2. Enlaza esta textura para el segundo pase
  3. Acceda al píxel prestado privelyus en el sombreador

Código de sombreado para 3.2:

uniform sampler2D mytex; // texture with the previous render pass layout(pixel_center_integer) in vec4 gl_FragCoord; // will give the screen position of the current fragment void main() { // convert fragment position to integers ivec2 screenpos = ivec2(gl_FragCoord.xy); // look up result from previous render pass in the texture vec4 color = texelFetch(mytex, screenpos, 0); // now use the value from the previous render pass ... }

Otro método para procesar una imagen renderizada sería OpenCL con OpenGL -> OpenCL interoperabilidad. Esto permite más CPU como cálculo.


Si lo que está llamando "valor actual del fragmento" es el valor del color del píxel que estaba en el destino del renderizado antes de que se ejecute el sombreador de fragmentos, entonces no, no está disponible.

La razón principal de esto es que potencialmente, en el momento en que se ejecuta el sombreador de fragmentos, aún no se conoce. Los sombreadores de fragmentos se ejecutan en paralelo, potencialmente (dependiendo de qué hardware) afectan al mismo píxel, y un bloque separado, leyendo de algún tipo de FIFO, generalmente es responsable de combinarlos más adelante. Esa fusión se llama "Mezcla", y aún no es parte de la tubería programable. Es una función fija, pero tiene varias formas diferentes de combinar lo que generó el sombreador de fragmentos con el valor de color anterior del píxel.


cómo-hacer-obtener-el-actual-color-de-un-fragmento

Algunos dicen que no se puede hacer, pero digo que esto funciona para mí:

//Toggle blending in one sense, while always disabling it in the other. void enableColorPassing(BOOL enable) { //This will toggle blending - and what gl_FragColor is set to upon shader execution enable ? glEnable(GL_BLEND) : glDisable(GL_BLEND); //Tells gl - "When blending, change nothing" glBlendFunc(GL_ONE, GL_ZERO); }

Después de esa llamada, gl_FragColor igualará el color claro del búfer de color la primera vez que el sombreador se ejecuta en cada píxel, y la salida de cada ejecución será la nueva entrada en cada ejecución sucesiva.

Bueno, al menos funciona para mí.