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
- 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; }
- 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); }
- 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); }
- 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
-
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.
-
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.
-
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.
Curs de Programació OpenGL
Mòdul 1: Introducció a OpenGL
- Què és OpenGL?
- Configurar el Teu Entorn de Desenvolupament
- Crear el Teu Primer Programa OpenGL
- Entendre el Pipeline d'OpenGL
Mòdul 2: Renderització Bàsica
- Dibuixar Formes Bàsiques
- Entendre les Coordenades i les Transformacions
- Coloració i Ombrejat
- Ús de Buffers
Mòdul 3: Tècniques de Renderització Intermèdies
- Textures i Mapeig de Textures
- Il·luminació i Materials
- Barreja i Transparència
- Prova de Profunditat i Prova de Plantilla
Mòdul 4: Tècniques de Renderització Avançades
Mòdul 5: Optimització del Rendiment
- Optimitzar el Codi OpenGL
- Ús d'Objectes de Matriu de Vèrtexs (VAOs)
- Gestió Eficient de la Memòria
- Perfilat i Depuració