El mapeig d'entorn és una tècnica de renderització que permet simular reflexions realistes en superfícies. Aquesta tècnica és àmpliament utilitzada en la creació de materials com el metall, el vidre i altres superfícies reflectants. En aquest tema, aprendrem com implementar el mapeig d'entorn utilitzant OpenGL.

Objectius del Tema

  • Entendre el concepte de mapeig d'entorn.
  • Configurar i utilitzar textures de cub (cube maps).
  • Implementar shaders per a mapeig d'entorn.
  • Aplicar el mapeig d'entorn a objectes 3D.

Conceptes Clau

Què és el Mapeig d'Entorn?

El mapeig d'entorn és una tècnica que utilitza una textura especial anomenada "cube map" per simular reflexions en una superfície. Un cube map és una col·lecció de sis imatges que representen les vistes des d'un punt central en les sis direccions (positiva i negativa dels eixos X, Y i Z).

Textures de Cub (Cube Maps)

Les textures de cub són essencials per al mapeig d'entorn. Aquestes textures contenen sis imatges que formen un cub al voltant d'un objecte, permetent que les reflexions es calculin correctament des de qualsevol angle.

Shaders per a Mapeig d'Entorn

Els shaders són programes que s'executen en la GPU per calcular els efectes visuals. Per al mapeig d'entorn, necessitarem un vertex shader i un fragment shader que utilitzin la textura de cub per calcular les reflexions.

Implementació Pràctica

  1. Configuració de la Textura de Cub

Primer, hem de carregar les sis imatges que formen la nostra textura de cub i configurar-la en OpenGL.

GLuint loadCubemap(std::vector<std::string> faces) {
    GLuint textureID;
    glGenTextures(1, &textureID);
    glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

    int width, height, nrChannels;
    for (unsigned int i = 0; i < faces.size(); i++) {
        unsigned char *data = stbi_load(faces[i].c_str(), &width, &height, &nrChannels, 0);
        if (data) {
            glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 
                         0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data
            );
            stbi_image_free(data);
        } else {
            std::cout << "Failed to load cubemap texture at path: " << faces[i] << std::endl;
            stbi_image_free(data);
        }
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

    return textureID;
}

  1. Vertex Shader

El vertex shader calcula les coordenades de textura per a la textura de cub.

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;

out vec3 WorldPos;
out vec3 Normal;

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main() {
    WorldPos = vec3(model * vec4(aPos, 1.0));
    Normal = mat3(transpose(inverse(model))) * aNormal;  

    gl_Position = projection * view * vec4(WorldPos, 1.0);
}

  1. Fragment Shader

El fragment shader utilitza la textura de cub per calcular les reflexions.

#version 330 core
out vec4 FragColor;

in vec3 WorldPos;
in vec3 Normal;

uniform samplerCube skybox;
uniform vec3 cameraPos;

void main() {
    vec3 I = normalize(WorldPos - cameraPos);
    vec3 R = reflect(I, normalize(Normal));
    FragColor = texture(skybox, R);
}

  1. Aplicar el Mapeig d'Entorn

Finalment, hem d'aplicar el mapeig d'entorn als nostres objectes 3D.

// Carregar les imatges per a la textura de cub
std::vector<std::string> faces {
    "right.jpg",
    "left.jpg",
    "top.jpg",
    "bottom.jpg",
    "front.jpg",
    "back.jpg"
};
GLuint cubemapTexture = loadCubemap(faces);

// Configurar els shaders
shader.use();
shader.setInt("skybox", 0);

// Renderitzar l'objecte amb mapeig d'entorn
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapTexture);

// Renderitzar el teu objecte aquí

Exercicis Pràctics

  1. Carregar i Configurar una Textura de Cub Diferent:

    • Troba un conjunt diferent d'imatges per a una textura de cub i carrega-les en el teu programa.
    • Assegura't que les imatges estiguin correctament alineades per formar un cub.
  2. Implementar Reflexions en un Objecte Diferent:

    • Aplica el mapeig d'entorn a un objecte diferent, com una esfera o un cilindre.
    • Observa com canvien les reflexions en funció de la forma de l'objecte.
  3. Afegir Refracció:

    • Modifica el fragment shader per afegir un efecte de refracció en lloc de reflexió.
    • Experimenta amb diferents índexs de refracció per veure com afecta el resultat.

Errors Comuns i Consells

  • Error en la Càrrega de Textures: Assegura't que les rutes de les imatges són correctes i que les imatges estan en el format esperat.
  • Coordenades de Textura Incorrectes: Verifica que les coordenades de textura es calculen correctament en el vertex shader.
  • Configuració de la Textura de Cub: Assegura't que els paràmetres de la textura de cub estan configurats correctament per evitar artefactes visuals.

Conclusió

El mapeig d'entorn és una tècnica poderosa per crear reflexions realistes en superfícies. En aquest tema, hem après a configurar textures de cub, implementar shaders per a mapeig d'entorn i aplicar aquestes tècniques a objectes 3D. Amb la pràctica, podràs crear materials reflectants impressionants per als teus projectes de renderització.

En el següent tema, explorarem els Shaders de Càlcul, una eina avançada per realitzar càlculs paral·lels en la GPU.

© Copyright 2024. Tots els drets reservats