Buffers

Anuncio
Introducción
Buffer
Definimos un buffer por su resolución espacial (nxm) y su
profundidad (o precisión) k, la cantidad de bits/pixel
Buffers
pixel
S. Castro, D. Urribarri
Introducción
Tradicionalmente el Framebuffer de OpenGL comprende
los siguientes buffers:

Introducción
Frame Buffer de OpenGL

La implementación particular de OpenGL determina qué buffers
están disponibles y cuántos bits por pixel puede almacenar cada
uno de ellos.

Mediante glGetIntegerv(parámetro) y seteando el valor apropiado
del parámetro, se le puede preguntar a OpenGL cuántos bits por
pixel puede almacenar un buffer en partiular.

Veamos ahora cuál es la característica de cada uno de los buffers
que podemos manipular
De Color. Su contenido puede mostrarse.
– front-left, front-right, back-left, back-right, y buffers de
color auxiliares que pueden estar acivos

De Profundidad

Stencil
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
Los Buffers
CG 2015
Los Buffers
El doble buffering es una técnica para engañar al ojo para que
vea animaciones suaves que se generan de escenas
renderizadas.
Buffers de Color

Son aquéllos en los que usualmente se dibuja

Contienen información del color como índice o como valor RGB y
también el A.

Si la versión de OpenGL soporta estereoscopía, se cuenta con los
buffers de color izquierdo y derecho; si no, sólo se tiene el
izquierdo.

Si se tiene doble buffering se tiene el front y back buffers; si no, sólo
se tiene el front.
Opcionalmente se pueden soportar buffers de color auxiliares cuyo
contenido no puede mostrarse directamente.
S. Castro, D. Urribarri
CG 2015
CG 2015
El front buffer (fb) se muestra
mientras
la
aplicación
renderiza en el back buffer
(bb). Cuando se completa el
rendering en el bb, se pide al
hardware que se haga un
swap de los roles de los
buffers, haciendo que se
muestre el bb y el fb previo
sea ahora el bb.
S. Castro, D. Urribarri
CG 2015
1
Los Buffers
Los Buffers
Buffer de profundidad
Buffer de Profundidad

Este buffer almacena el valor de profundidad para cada pixel

Éste es medida en función de la distancia al ojo, de modo que
pixels con mayores valores de profundidad se sobreescriben con
valores menores

A menudo se denomina z-buffer.

El comportamiento en profundidad puede alterarse modificando la
función de comparación (glDepthFunc(GLenum valor) donde valor
puede ser GL_LESS, GL_EQUAL, ...). Por defecto es GL_LESS
que significa que el fragmento que se comparará pasa el test si su
valor de z es menor que el ya almacenado en el buffer.
S. Castro, D. Urribarri
CG 2015
El buffer de profundidad se usa para determinar cómo se ocluyen entre
sí las primitivas de la escena..
Los valores del buffer de profundidad de OpenGL están en el rango
[0,1].
S. Castro, D. Urribarri
Los Buffers
CG 2015
Operaciones sobre los buffers
Hay distintas operaciones que pueden realizarse:
Stencil Buffer

Un uso de este buffer es restringir el dibujado a ciertas porciones de
la pantalla (no ocupadas por el stencil).

Se puede almacenar una imagen determinada en una región (por
ejemplo un tablero de auto). Entonces, al renderizarse toda la
escena, este buffer impedirá que sea visible en el lugar ocupado
por lo almacenado en esa región.
Limpiarlos
– Se pueden limpiar uno o más buffers a la vez; antes de limpiarlos se
establece el valor que se guardará.
Seleccionar los buffers de color para leer y escribir
– Los resultados de una operación de lectura o escritura sobre los buffers
pueden ir o venir de cualquiera de los buffers de color (glDrawBuffer() y
glReadBuffer()).
Enmascaramiento
– Antes de que OpenGL escriba en los buffers habilitados de color,
profundidad o stencil, se aplica sobre los datos una operación de
enmascaramiento. Se lleva a cabo una operación AND de cada máscara
con el dato correspondiente a ser escrito.
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
Operaciones sobre los buffers
CG 2015
Operaciones sobre los buffers
Modelo de escritura
Escribiendo en los buffers
Conceptualmente, podemos considerar toda la memoria como un gran
arreglo bi-dimensional de pixels
Se lee el pixel destino antes de escribir el fuente
Podemos leer y escribir bloques rectangulares de pixels
– Operaciones Bit block transfer (bitblt)
El frame buffer es parte de esta memoria
memoria
fuente
frame buffer
(destino)
Escribiendo en el frame buffer
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
CG 2015
2
Operaciones sobre los buffers
Modos de escritura
Testeo y Operaciones sobre los fragmentos
CO
Los bits fuente y destino se combinan bit a bit
Hay 16 funciones posibles (una por columna en la tabla)
CO
T.Model
.
CM
T.Mundo
COjo
T.Vista
COjo
Iluminación
XOR
reemplazo
T.Perspectiva
CClip
OR
Procesamiento Geométrico (de vértices)
División
Perspectiva (/w)
Pantalla 3D (CND)
T. Viewport
Procesamiento de Fragmentos
Proc.fragmento,
Texturado, Ilum
fragmento, …
Operaciones
Raster
S. Castro, D. Urribarri
CG 2015
Testeo y Operaciones sobre los fragmentos
Luego que OpenGL determina que un fragmento individual debe generarse y
cuál es su color, hay varios tests que debe atravesar para determinar si el
fragmento se convertirá en un pixel en el frame buffer y, si esto ocurre, cómo
se hará.
El conjunto de tests y las operaciones a las que debe ser sometido un
fragmento son:
CP
CP
CP
CP
Rasterización
S. Castro, D. Urribarri
CG 2015
Testeo y Operaciones sobre los fragmentos
fragmentos
Test
Recortado
Test alpha
Test stencil
Test
Profundidad
– Test de recortado
Blending
– Test alpha
Dithering
– Test stencil
Operac.
lógicas
– Test de profundidad
al framebuffer
– Blending
Test de Recortado
– Dithering
– Operaciones lógicas
Los tests y las operaciones están listados en orden; si un fragmento se elimina
en un determinado momento, no tiene lugar sobre el mismo ninguno de los
tests u operaciones posteriores.
S. Castro, D. Urribarri
CG 2015
Testeo y Operaciones sobre los fragmentos
Se puede definir una porción rectangular en la ventana y restringir a
ésta el dibujado mediante el comando glScissor().
S. Castro, D. Urribarri
Testeo y Operaciones sobre los fragmentos
fragmentos
Test
Recortado
fragmentos
Test alpha
Blending
CG 2015
Test stencil
Dithering
Test
Recortado
Test
Profundidad
Operac.
lógicas
Test alpha
Blending
al framebuffer
Test stencil
Dithering
Test
Profundidad
Operac.
lógicas
al framebuffer
Test Alfa
Test Stencil
En modo RGBA, este test permite aceptar o rechazar un fragmento basándose
en su valor de alfa. Si está habilitado, el test compara el valor de alfa del
segmento con un valor de referencia. El fragmento es aceptado o rechazado
dependiendo del resultado de esta comparación. Tanto el valor de referencia
como la función de comparación pueden setearse con glAlphaFunc().
Se compara un valor de referencia con el almacenado en el pixel en el stencil
buffer. Este test se realiza si este buffer está presente; si no, siempre pasa.
Dependiendo del resultado del test se modifica o no el valor en el stencil buffer.
Se puede elegir una función de comparación en particular, el valor de referencia
y la modificación que se lleva a cabo.
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
CG 2015
3
Testeo y Operaciones sobre los fragmentos
Testeo y Operaciones sobre los fragmentos
fragmentos
Test
Recortado
fragmentos
Test alpha
Blending
Test stencil
Dithering
Test
Recortado
Test
Profundidad
Operac.
lógicas
Test alpha
Blending
Test stencil
Dithering
al framebuffer
Test
Profundidad
Operac.
lógicas
al framebuffer
Test de Profundidad
Para cada pixel en la pantalla, este buffer guarda la distancia entre el punto de
vista y el objeto que ocupa ese pixel.
Si el test pasa, el valor que entra reemplaza el valor en el buffer. Este buffer se
usa principalmente para cara oculta.
S. Castro, D. Urribarri
CG 2015
Blending
Combina fragmentos con pixels ya almacenados en el frame buffer para
producir un nuevo color para dicho pixel. Se pueden aplicar distintas
operaciones de blending y el blending que ocurra depende del valor de alfa del
segmento que ingresa y del valor de alfa (si hay alguno) del pixel almacenado.
S. Castro, D. Urribarri
CG 2015
Blending
Blending
Las imágenes pueden ser de 1, 2, 3 ó 4 dimensiones. La cuarta
dimensión es la componente α y es una medida de la opacidad del
fragmento. Como las otras componentes de color, el rango de los
valores es desde 0.0 (completamente transparente) a 1.0
(completamente opaco).
Opacidad y transparencia
Los valores de α son importantes en distintos contextos:
Las superficies translúcidas permite que pase algo de luz
Las superficies transparentes permiten que toda la luz pase a través de
ellas
transparencua = 1 – opacidad (a)
- Simular objetos translúcidos como el vidrio, el agua, etc
-Blending y composición de
Las superficies opacas permiten que la luz no pase a través de ellas
imágenes
-Antialiasing de primitivas geométricas
Superficie opacca a =1
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
CG 2015
Blending
Blending
El blending combina fragmentos con pixels ya almacenados en el frame
buffer para producir un nuevo color para dicho pixel.
Tanto el fragmento como el pixel tienen asociado un factor que controla
su contribución al color final del pixel. Estos factores de blending se
setean con la primitiva:
Se pueden aplicar distintas operaciones de blending y el blending que
ocurra depende del valor alfa del segmento que ingresa y del valor alfa
(si hay alguno) del pixel almacenado.
glBlendFunct(src,dst)
Cr = src Cf + dst Cp
Los factores comunes de blending que se usan en OpenGL son
GL_ONE,
GL_ZERO,
GL_ONE_MINUS_SRC_ALPHA
y
GL_SRC_ALPHA,.
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
CG 2015
4
Blending
Debe habilitarse el blending y tomar los factores fuente y destino
Ejemplo
Suponer que comenzamos con un color de fondo opaco (R0,G0,B0,1)
– Este color es el color destino inicial
glEnable(GL_BLEND)
Ahora queremos hacer un blend de un polígono translúcido de color
(R1,G1,B1,a1)
glBlendFunc(src_factor, dst_factor)
Seleccionamos GL_SRC_ALPHA y GL_ONE_MINUS_SRC_ALPHA como
los factores de blending de fuente y destino
Sólo se soportan ciertos factores
R’1 = a1 R1 +(1- a1) R0, ……
– GL_ZERO, GL_ONE
Notar que esta fórmula es correcta si el polígono es opaco o
transparente
– GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
– GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA
En el Redbook hay una lista de éstos
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
Blending
CG 2015
Blending
Dependencia del orden
Polígonos opacos y translúcidos
¿Es correcta esta imagen?
Supongamos que tenemos un grupo de polígonos algunos de los
cuales son opacos y algunos transparentes
– En OpenGL, los polígonos se renderizaron en el orden que iban
apareciendo en el pipeline
¿Cómo removemos las caras ocultas?
– Las funciones de Blending son dependientes del orden
Los polígonos opacos bloquean todos los polígonos que están detrás
de ellos y afectan el buffer de profundidad
Los polígonos transparentes no deberían afectar el buffer de
profundidad
– Renderizar con glDepthMask(GL_FALSE) que permite que el
buffer de profundidad sea de sólo lectura
Ordenar los polígonos primero para eliminar cualquier dependencia del
orden
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
Testeo y Operaciones sobre los fragmentos
fragmentos
Test
Recortado
Test alpha
Blending
Test stencil
Dithering
CG 2015
Dithering
Los sistemas con poca cantidad de bits dedicada a los colores pueden
mejorar la resolución de color a expensas de la resolución espacial
mediante el dithering.
Test
Profundidad
Operac.
lógicas
al framebuffer
Dithering
Es el proceso de aplicación de cierto tipo de ruido con el objetivo de randomizar
el error de cuantización.
De este modo se evitan los patrones de gran escala tales como la generación
de bandas de color (en imágenes).
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
CG 2015
5
Dithering
Dithering
Los sistemas con poca cantidad de bits dedicada a los colores pueden
mejorar la resolución de color a expensas de la resolución espacial
mediante el dithering. Con blanco y negro, por ejemplo, se pueden
generar distintos tonos de grises.
Los sistemas con poca cantidad de bits dedicada a los colores pueden
mejorar la resolución de color a expensas de la resolución espacial
mediante el dithering.
Imagen Original
Paleta 256 col.
S. Castro, D. Urribarri
CG 2015
Paleta web-safe
Test
Recortado
CG 2015
Operaciones lógicas
Las operaciones lógicas constituyen la última operación a llevarse a
cabo sobre un fragmento y se llevan a cabo mediante la primitiva:
Test alpha
Test stencil
Test
Profundidad
glLogicOp(GLenum CodOperación)
reemplazo
Blending
Paleta 16 col. con
dithering
S. Castro, D. Urribarri
Testeo y Operaciones sobre los fragmentos
fragmentos
Paleta 16 col.
Dithering
XOR
OR
Operac.
lógicas
al framebuffer
Operaciones lógicas
Las operaciones lógicas (tales como OR, XOR, INVERT,…) son la última
operación que se realiza sobre un fragmento. Ésta es aplicada a los valores de
los fragmentos de entrada (source) y/o a los que se encuentran en ese
momento en el buffer de color (destination).
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
CG 2015
Framebuffer Object (FBO)
Aplicaciones usando los
Buffers
El framebuffer que se provee con el sistema de ventanas usado es el
único framebuffer que puede verse en pantalla. Hay framebuffers que
pueden crearse en una aplicación y su contenido no puede verse en el
monitor pero soportan off-screen rendering.
Otra diferencia entre los framebuffers creados por el sistema de
ventanas y los framebuffers que se crean especialmente desde la
aplicación es que los primeros alocan sus propios buffers -color,
profundidad y stencil - cuando se crea la ventana. Cuando se crean
framebuffers manejados por la aplicación, es necesario que se le
adicionen los renderbuffers que se quiera asociarles a los FBOs
creados.
Los buffers provistos cuando se crean con el sistema de ventanas
nunca podrán asociarse al FBO creado por la aplicación y viceversa.
S. Castro, D. Urribarri
CG 2015
6
Framebuffer Object (FBO)
Primero debe alocarse un nombre al FBO creado en la aplicación. Para
esto se usa glGenFramebuffers(), que permite alocar un identificador
no usado para el FBO.
Luego,se utiliza glBindFramebuffer() – que opera de manera similar a
las otras primitivas glBind*() vistas-. La primera vez que se usa para un
framebuffer particular, hace que el objeto sea alocado e inicializado.
Las llamadas posteriores al mismo harán del mismo un objeto activo.
Una vez creado el FBO, es necesario proveer un lugar donde se
renderizará y desde donde se leerá; estos son los framebuffer
attachments.
Los renderbuffers son los tipo de buffer que se pueden adicionar al
FBO.
S. Castro, D. Urribarri
CG 2015
Framebuffer Object (FBO)
Renderbuffers
Los Renderbuffers son manejados eficientemente por OpenGL. Los
datos almacenados en un renderbuffer tienen significado una vez que
éste ha sido adicionado a un FBO, asumiendo que el formato del buffer
coincide con lo que OpenGL espera renderizar en él (e.g., no se pueden
renderizar colores en un buffer de profundidad).
Como con cualquiera de los otros buffers en OpenGL, el proceso de
alocar y borrar buffers es similar al visto.
Para crear un nuevo renderbuffer, se debe usar glGenRenderbuffers().
Una llamada a glDeleteRenderbuffers() liberará el almacenamiento
asociado con el renderbuffer.
Cuando se usa por primera vez glBindRenderbuffer(), OpenGL crea
un renderbuffer con su información de estado seteada a valores por
defecto.
S. Castro, D. Urribarri
CG 2015
Framebuffer Object (FBO)
Framebuffer Object (FBO)
Renderbuffers
Adicionar el/los renderbuffers al FBO
Hasta ahora no se reservó memoria para guardar información sobre la
imagen. Antes de adicionar un renderbuffer a un framebuffer y
renderizar en él, es necesario alocar memoria y especificar el formato
de la imagen.
Cuando se renderiza, es posible enviar los resultados del rendering a
distintos buffers. Las distintas alternativas son:
Esto se realiza mediante glRenderbufferStorage() o
• Uno o múltiples buffers de color simultáneamente
• Buffer de profundidad para almacenar información de oclusión.
• Stencil buffer para almacenar máscaras por pixel para controlar el
rendering.
glRenderbufferStorageMultisample().
Para crear un renderbuffer color de 256 × 256 RGBA:
glGenRenderbuffers(1, &color);
glBindRenderbuffer(GL_RENDERBUFFER, color);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, 256, 256);
Cada uno de estos buffers representa un framebuffer que puede
adicionarse. A estos pueden adicionarse buffers de imágenes en los
cuales puede renderizarse o desde los cuales puede leerse.
Ahora sólo falta adicionarlo al FBO antes de renderizar en él.
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
Renderizado a una Textura
Renderizado a una textura
Algunas veces es necesario generar o modificar texturas durante la
ejecución de un programa. La textura puede ser, por ejemplo, la escena
o una parte de la misma.
CG 2015
Renderizado a una Textura
Para renderizar a una textura y aplicar esa textura a una escena en una
segunda pasada deben seguirse los pasos mencionados.
1.
Seteo del FBO.
GLuint fboHandle; // Handler del FBO
El proceso involucra los siguientes pasos cuando se renderiza:
// Generar y enlazar el framebuffer
1.
Seteo del FBO. Crear un target de rendering particular (FBO) y
adicionar a éste la textura
glGenFramebuffers(1, &fboHandle);
2.
Renderizar la textura T al FBO
// Crear el objeto textura
3.
Desafectar el contexto de rendering del FBO y ponerlo nuevamente
en el framebuffer
GLuint renderTex;
4.
Renderizar la escena normalmente usando la textura T generada
glActiveTexture(GL_TEXTURE0); // Usar la unidad de textura 0
glBindFramebuffer(GL_FRAMEBUFFER, fboHandle);
glGenTextures(1, &renderTex);
glBindTexture(GL_TEXTURE_2D, renderTex);
glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA,512,512,0,GL_RGBA,GL_UNSIGNED
_BYTE,NULL); …
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
CG 2015
7
Renderizado a una Textura
Renderizado a una Textura
// Crear el buffer de profundidad
Para que el programa de fragmentos sea siempre el mismo (cuando
renderizo a textura una textura blanca no afecta el color y cuando
renderizo con la textura se usa la textura generada) se define una
textura blanca en la unidad de textura 1.
GLuint depthBuf;
// Bind a la textura del FBO
glGenRenderbuffers(1, &depthBuf);
glBindFramebuffer(GL_FRAMEBUFFER, fboHandle);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuf);
glViewport(0,0,512,512); // Viewport para la textura
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT,
// Usar la textura “blanca"
512, 512);
int loc = glGetUniformLocation(programHandle, "Texture");
// Bind la textura al FBO
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_TEXTURE_2D, renderTex, 0);
glUniform1i(loc, 1);
// Bind el buffer de profundidad al FBO
// Setup matrices para renderizar escena a textura.
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
…
GL_RENDERBUFFER, depthBuf);
renderTextureScene();
// Setear el target para la salida del shader de fragmentos
glBindFramebuffer(GL_FRAMEBUFFER, 0);
GLenum drawBufs[] = {GL_COLOR_ATTACHMENT0};
glDrawBuffers(1, drawBufs);
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
Renderizado a una Textura
Para que el programa de fragmentos sea siempre el mismo (cuando
renderizo a textura una textura blanca no afecta el color y cuando
renderizo con la textura se usa la textura generada) se define una
textura blanca en la unidad de textura 1.
Sombreado diferido (Deferred shading)
Sombreado diferido (Deferred shading)
El sombreado diferido es una técnica que pospone la etapa de
iluminación/sombreado a una segunda pasada para evitar calcular el
sombreado de un pixel más de una vez.
La idea básica es la siguiente:
glViewport(0,0,width,height); // Viewport para la ventana
principal
1.
Primera pasada. Se renderiza la escena pero en lugar de evaluar el
modelo de reflexión para determinar el color de un fragmento, se
almacena la información geométrica (posición, normal y además
coordenadas de textura, reflectividad, etc) en un conjunto
intermedio de buffers denominados colectivamente g-buffer
2.
Segunda pasada. Se lee del g-buffer, se evalúa el modelo de
reflexión y se produce el color final de cada pixel
/ Usar la textura asociada con el FBO
int loc = glGetUniformLocation(programHandle, "Texture");
glUniform1i(loc, 0);
// Resetear las matrices de proyección y vista
…
renderScene();
¿Puede utilizar lo visto para renderizar en un espejo? Si es así, ¿cómo?
S. Castro, D. Urribarri
CG 2015
CG 2015
Sombreado diferido (Deferred shading)
Guardaremos, para cada pixel del g-buffer la posición, la normal y el
color difuso.
S. Castro, D. Urribarri
Sombreado diferido (Deferred shading)
Sombreado diferido (Deferred shading)
Sombreado diferido (Deferred shading)
En la primera pasada, en la aplicación, se debe::
El FBO deberá contener nuestro g-buffer.
1.
Hacer el binding al FBO.
2.
Limpiar los buffers de color/profundidad, habilitar el test de
profundidad y utilizar los shaders desarrollados para la pasada 1.
3.
Renderizar la escena normalmente
CG 2015
Se deberá crear el FBO y a éste se le deberá adicionar el buffer de
profundidad, el de posición, el de normales y el de reflectividad.
GLuint depthBuf, posTex, normTex, colorTex;
glGenFramebuffers(1, &deferredFBO);
glBindFramebuffer(GL_FRAMEBUFFER, deferredFBO);
// Buffer de profundidad
glGenRenderbuffers(1, &depthBuf);
glBindRenderbuffer(GL_RENDERBUFFER, depthBuf);
En la pasada dos:
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT,
1.
Revertir el FBO al framebuffer por defecto
2.
Limpiar el buffer de color, deshabilitar el test de profundidad (si se
quiere) y utilizar los shaders para esta pasada.
3.
Renderizar en un rectángulo (2 triángulos) con coordenadas de
textura que vayan de 0 a 1 en cada direccción.
S. Castro, D. Urribarri
CG 2015
width, height);
// Buffer de posición
glActiveTexture(GL_TEXTURE0); // Use texture unit 0 for position
glGenTextures(1, &posTex);
glBindTexture(GL_TEXTURE_2D, posTex);
S. Castro, D. Urribarri
CG 2015
8
Sombreado diferido (Deferred shading)
Sombreado diferido (Deferred shading)
Sombreado diferido (Deferred shading)
Sombreado diferido (Deferred shading)
El FBO deberá contener nuestro g-buffer.
El shader de vértices es el siguiente: …
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB32F, width, height, 0,
GL_RGB, GL_UNSIGNED_BYTE, NULL);
layout( location = 0 ) in vec3 VertexPosition;
layout( location = 1 ) in vec3 VertexNormal;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,GL_NEAREST);
…
layout( location = 2 ) in vec2 VertexTexCoord;
out vec3 Position;
uniform mat4 ModelViewMatrix;
out vec3 Normal;
uniform mat3 NormalMatrix;
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_RENDERBUFFER, depthBuf);
out vec2 TexCoord;
uniform mat4 ProjectionMatrix;
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
void main()
GL_TEXTURE_2D, posTex, 0);
…
{ Normal = normalize( NormalMatrix * VertexNormal);
y luego se deben adicionar las imágenes al framebuffer:
uniform mat4 MVP;
Position = vec3( ModelViewMatrix *
GLenumdrawBuffers[] = {GL_NONE, GL_COLOR_ATTACHMENT0,
vec4(VertexPosition,1.0) );
GL_COLOR_ATTACHMENT1,GL_COLOR_ATTACHMENT2};
glDrawBuffers(4, drawBuffers);
TexCoord = VertexTexCoord;
gl_Position = MVP * vec4(VertexPosition,1.0);
}
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
Sombreado diferido (Deferred shading)
CG 2015
Sombreado diferido (Deferred shading)
Sombreado diferido (Deferred shading)
Sombreado diferido (Deferred shading)
El código común a ambos shaders de fragmentos:
El código común a ambos shaders de fragmentos:
// Texturas del g-buffer
uniform sampler2D PositionTex, NormalTex, ColorTex;
struct LightInfo {
in vec3 Position;
vec4 Position; // Light position in eye coords.
vec3 Intensity; // Diffuse intensity
in vec3 Normal;
in vec2 TexCoord;
};
layout (location = 0) out vec4 FragColor;
uniform LightInfo Light;
struct MaterialInfo {
layout (location = 1) out vec3 PositionData;
layout (location = 2) out vec3 NormalData;
vec3 Kd; // Diffuse reflectivity
layout (location = 3) out vec3 ColorData;
};
vec3 diffuseModel( vec3 pos, vec3 norm, vec3 diff )
{ vec3 s = normalize(vec3(Light.Position) - pos);
uniform MaterialInfo Material;
float sDotN = max( dot(s,norm), 0.0 );
subroutine void RenderPassType();
vec3 diffuse = Light.Intensity * diff * sDotN;
return diffuse;
subroutine uniform RenderPassType RenderPass;
…
}:
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
CG 2015
Sombreado diferido (Deferred shading)
Sombreado diferido (Deferred shading)
Antialiasing
El antialiasing es un proceso que permite, en la primitivas geométricas,
remover los jaggies. Esto puede hacerse en OpenGL
Shader de fragmentos, pasada 1:
// Almacenar posición, normal color difuso en el g-buffer
glEnable(modo)
PositionData = Position;
NormalData = Normal;
ColorData = Material.Kd;
- modo GL_POINT_SMOOTH
GL_LINE_SMOOTH
Shader de fragmentos, pasada 2:
// Recuperar posición, normal color difuso
// texturas del g-buffer
GL_POLYGON_SMOOTH
de las
vec3 pos = vec3( texture( PositionTex, TexCoord ) );
vec3 norm = vec3( texture( NormalTex, TexCoord ) );
vec3 diffColor = vec3( texture(ColorTex, TexCoord) );
- valores de alpha calculados teniendo en cuenta el cubrimiento a nivel
de sub-pixel
FragColor = vec4( diffuseModel(pos,norm,diffColor), 1.0 );
- disponible en los modos RGBA y colormaps
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
CG 2015
9
Antialiasing
Antialiasing
Puede tratar de pintar un pixel adicionando una fracción de su color al
frame buffer
Aliasing de líneas
La línea raster ideal tiene un pixel de ancho
Todos los segmentos de línea que no sean los verticales y los
horizontales, cubren pixels parcialmente
– Esta fracción depende del porcentaje de pixel que es cubierto por
el fragmento
– Esta fracción depende de si hay solapamiento (overlap)
Los algoritmos simples pintan sólo pixels completos
Estos conduce a aliasing
Situaciones similares se
presentan con los polígonos
no overlap
S. Castro, D. Urribarri
CG 2015
S. Castro, D. Urribarri
overlap
CG 2015
Antialiasing
Antialiasing en OpenGL
Puede habilitarse separadamente para puntos, líneas o polígonos
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
glEnable(GL_POLYGON_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
S. Castro, D. Urribarri
CG 2015
10
Descargar