ejemplo - iluminacion opengl c++
El mapeo de sombras de mĂșltiples luces no funciona correctamente usando GLSL (1)
Resolví mi problema. En realidad, acabo de llenar la primera textura de profundidad (para la primera luz cargada). Entonces, para la segunda luz, el mapa de sombras no estaba lleno y esto es lo que explica el área negra en la tercera imagen de arriba.
Aquí está el resultado final:
Espero que esta publicación sea útil para alguien. Gracias por tu atención.
Implementé el algoritmo básico de mapeo de sombras pero funciona correctamente con solo una luz.
Quiero renderizar una escena con dos luces de punto siguientes:
- Light_1 - posición: vec3 (-8.0f, 5.0f, 8.0f), dirección: vec3 (1.3f, -1.0f, -1.0f)
- Light_2 - posición: vec3 (8.0f, 5.0f, 8.0f), dirección: vec3 (1.3f, -1.0f, -1.0f)
Si represento por separado las dos luces, tengo los siguientes resultados:
Renderizado con Light_1:
Renderizado con Light_2:
Pero las dos luces juntas se ven así:
Como puede ver, la primera sombra parece estar representada correctamente, pero está debajo de la sombra de la luz_2 que no es correcta. Para resumir la situación, tengo la textura de mi caja unida a la unidad de textura 0. La textura de profundidad de sombra está ligada a la unidad de textura 1 y si hay más de una textura de profundidad (por lo menos dos luces, como en este ejemplo), están vinculados a la unidad de textura 1 + 1 (GL_TEXTURE1 + 1). Aquí está el código que representa lo que dije:
for (int idy = 0; idy < this->m_pScene->getLightList().size(); idy++)
[...]
Light *light = this->m_pScene->getLightList()[idy];
FrameBuffer *frameBuffer = light->getFrameBuffer();
glActiveTexture(GL_TEXTURE1 + idy);
glBindTexture(GL_TEXTURE_2D, frameBuffer->getTexture()->getTextureId()); //To unbind
shaderProgram->setUniform(std::string("ShadowMatrix[").append(Convertor::toString<int> (idy)).append("]").c_str(), this->m_pScene->getLightList()[idy]->getBiasViewPerspectiveMatrix() * modelMatrix);
shaderProgram->setUniform(std::string("ShadowMap[").append(Convertor::toString<int>(idy)).append("]").c_str(), (int)idy + 1);
Corresponde en nuestro caso a:
shaderProgram->setUniform("ShadowMatrix[0]", <shadow_matrix_light_1>);
shaderProgram->setUniform("ShadowMap[0]", 1); (GL_TEXTURE1)
shaderProgram->setUniform("ShadowMatrix[1]", <shadow_matrix_light_2>);
shaderProgram->setUniform("ShadowMap[1]", 2); (GL_TEXTURE2)
El sombreador de vértices es el siguiente (disponible solo para 2 luces):
#version 400
#define MAX_SHADOW_MATRIX 10
#define MAX_SHADOW_COORDS 10
layout (location = 0) in vec4 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
layout (location = 2) in vec2 VertexTexture;
uniform mat3 NormalMatrix;
uniform mat4 ModelViewMatrix;
uniform mat4 ShadowMatrix[MAX_SHADOW_MATRIX];
uniform mat4 MVP;
uniform int lightCount;
out vec3 Position;
out vec3 Normal;
out vec2 TexCoords;
out vec4 ShadowCoords[MAX_SHADOW_COORDS];
void main(void)
{
TexCoords = VertexTexture;
Normal = normalize(NormalMatrix * VertexNormal);
Position = vec3(ModelViewMatrix * VertexPosition);
for (int idx = 0; idx < lightCount; idx++)
ShadowCoords[idx] = ShadowMatrix[idx] * VertexPosition;
gl_Position = MVP * VertexPosition;
}
Y una pieza de código del fragmento shader:
[...]
vec3 evalBasicFragmentShadow(vec3 LightIntensity, int idx)
{
vec3 Ambient = LightInfos[idx].La * MaterialInfos.Ka;
if (ShadowCoords[idx].w > 0.0f)
{
vec4 tmp_shadow_coords = ShadowCoords[idx];
tmp_shadow_coords.z -= SHADOW_OFFSET;
float shadow = textureProj(ShadowMap[idx], tmp_shadow_coords);
LightIntensity = LightIntensity * shadow + Ambient;
}
else
{
LightIntensity = LightIntensity + MaterialInfos.Ka;
}
return (LightIntensity);
}
vec3 getLightIntensity(vec3 TexColor)
{
vec3 LightIntensity = vec3(0.0f);
for (int idx = 0; idx < lightCount; idx++)
{
vec3 tnorm = (gl_FrontFacing ? -normalize(Normal) : normalize(Normal));
vec3 lightDir = vec3(LightInfos[idx].Position) - Position;
vec3 lightDirNorm = normalize(lightDir);
float lightAtt = getLightAttenuation(lightDir, LightInfos[idx]);
LightIntensity += Point_ADS_Shading(lightAtt, -tnorm, lightDirNorm, TexColor, idx);
LightIntensity = evalBasicFragmentShadow(LightIntensity, idx);
}
return (LightIntensity);
}
[...]
Parece un problema en la unidad de textura porque separadamente las dos sombras se han renderizado perfectamente y uso glActiveTexture correctamente (creo que sí). Además, noté que si cambio el orden de carga de las luces, la mala sombra es causada por "la otra luz" (es lo contrario). Parece que proviene de la unidad de textura 2, pero no entiendo por qué. ¿Alguien puede ayudarme, por favor? De antemano muchas gracias por tu ayuda.