Els efectes de postprocessament són tècniques utilitzades per aplicar efectes visuals a les imatges renderitzades després que s'hagin generat. Aquestes tècniques poden millorar significativament la qualitat visual de les escenes i s'utilitzen àmpliament en la indústria dels videojocs i la producció de pel·lícules.

Conceptes Clau

  1. Framebuffers: Un framebuffer és una col·lecció de buffers que poden incloure un buffer de color, un buffer de profunditat i un buffer de plantilla. Els framebuffers s'utilitzen per emmagatzemar les imatges renderitzades abans de ser processades.
  2. Shaders de Fragment: Els shaders de fragment són programes que s'executen per cada píxel i s'utilitzen per aplicar efectes de postprocessament.
  3. Textures: Les textures s'utilitzen per emmagatzemar les imatges renderitzades i aplicar efectes de postprocessament.

Passos per Implementar Efectes de Postprocessament

  1. Crear un Framebuffer

Primer, hem de crear un framebuffer on renderitzarem la nostra escena.

GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

  1. Crear una Texture per al Framebuffer

Després, creem una textura que emmagatzemarà la imatge renderitzada.

GLuint textureColorbuffer;
glGenTextures(1, &textureColorbuffer);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0);

  1. Comprovar el Framebuffer

Comprovem si el framebuffer s'ha creat correctament.

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    std::cout << "Framebuffer is not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);

  1. Renderitzar l'Escena al Framebuffer

Renderitzem la nostra escena al framebuffer en lloc de la pantalla.

glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Renderitzar l'escena aquí

glBindFramebuffer(GL_FRAMEBUFFER, 0);

  1. Aplicar Efectes de Postprocessament

Utilitzem un shader de fragment per aplicar efectes de postprocessament a la textura renderitzada.

Shader de Fragment per a Postprocessament

#version 330 core
out vec4 FragColor;

in vec2 TexCoords;

uniform sampler2D screenTexture;

void main()
{
    vec3 col = texture(screenTexture, TexCoords).rgb;
    // Exemple d'efecte de postprocessament: escala de grisos
    float gray = dot(col, vec3(0.299, 0.587, 0.114));
    FragColor = vec4(vec3(gray), 1.0);
}

  1. Renderitzar la Quad

Finalment, renderitzem una quad que cobreix tota la pantalla i apliquem el shader de postprocessament.

glBindVertexArray(quadVAO);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer);
glDrawArrays(GL_TRIANGLES, 0, 6);

Exercici Pràctic

Objectiu

Implementar un efecte de postprocessament que converteixi la imatge renderitzada a escala de grisos.

Passos

  1. Crear el Framebuffer: Seguiu els passos anteriors per crear un framebuffer i una textura.
  2. Renderitzar l'Escena: Renderitzeu la vostra escena al framebuffer.
  3. Aplicar l'Efecte de Postprocessament: Utilitzeu el shader de fragment proporcionat per convertir la imatge a escala de grisos.
  4. Renderitzar la Quad: Renderitzeu una quad que cobreixi tota la pantalla i apliqueu el shader de postprocessament.

Solució

// Crear el framebuffer
GLuint framebuffer;
glGenFramebuffers(1, &framebuffer);
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);

// Crear la textura per al framebuffer
GLuint textureColorbuffer;
glGenTextures(1, &textureColorbuffer);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, screenWidth, screenHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0);

// Comprovar el framebuffer
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
    std::cout << "Framebuffer is not complete!" << std::endl;
glBindFramebuffer(GL_FRAMEBUFFER, 0);

// Renderitzar l'escena al framebuffer
glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Renderitzar l'escena aquí

glBindFramebuffer(GL_FRAMEBUFFER, 0);

// Aplicar l'efecte de postprocessament
glUseProgram(postProcessingShader);
glBindVertexArray(quadVAO);
glBindTexture(GL_TEXTURE_2D, textureColorbuffer);
glDrawArrays(GL_TRIANGLES, 0, 6);

Resum

En aquesta secció, hem après com implementar efectes de postprocessament utilitzant framebuffers i shaders de fragment. Hem creat un framebuffer, hem renderitzat la nostra escena a una textura i hem aplicat un efecte de postprocessament per convertir la imatge a escala de grisos. Aquestes tècniques són fonamentals per millorar la qualitat visual de les escenes renderitzades i s'utilitzen àmpliament en la indústria dels videojocs i la producció de pel·lícules.

© Copyright 2024. Tots els drets reservats