Карта теней OpenGL

Я пытаюсь сделать базовую карту теней, но по какой-то причине она не отображается должным образом.

Видео проблемы

Я визуализирую дом с помощью плоского шейдера:

int shadowMapWidth = WINDOW_SIZE_X * (int)SHADOW_MAP_RATIO;
int shadowMapHeight =  WINDOW_SIZE_Y * (int)SHADOW_MAP_RATIO;

// Rendering into the shadow texture.
glActiveTexture(GL_TEXTURE0);
CALL_GL(glBindTexture(GL_TEXTURE_2D, shadowTexture));
// Bind the framebuffer.
CALL_GL(glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO));
//Clear it
CALL_GL(glClear(GL_DEPTH_BUFFER_BIT));
CALL_GL(glViewport(0, 0, shadowMapWidth, shadowMapHeight));
CALL_GL(glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE));
//Render stuff
flatShader.use();
flatShader["baseColor"] = glm::vec4(1.0f,1.0f,1.0f,1.0f);
flatShader["pvm"] = projectionMatrix*pointLight.viewMatrix*cursor.modelMatrix;
cursor.draw(); //binds the vao and draws

// Revert for the scene.
CALL_GL(glBindFramebuffer(GL_FRAMEBUFFER, 0));
CALL_GL(glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE));
CALL_GL(glViewport(0, 0, WINDOW_SIZE_X, WINDOW_SIZE_Y));

Обратите внимание, что я визуализирую только дом. Я не визуализирую пол в проходе буфера глубины.

После этого я визуализирую четырехугольник, представляющий пол, используя следующую пару шейдеров:

/* [VERT] */ 
#version 330

in vec3 in_Position;
in vec2 in_TexCoord;

uniform mat4 shadowMatrix;
uniform mat4 mvp;

out vec2 UV;
out vec4 shadowProj;

void main()
{
    gl_Position = mvp*vec4(in_Position,1.0);
    shadowProj = shadowMatrix*vec4(in_Position,1.0);
    UV = in_TexCoord;
}

И фрагментный шейдер:

/* [FRAG] */ 
#version 330

in vec2 UV;
in vec4 shadowProj;

out vec4 fragColor;

uniform sampler2D texturex;
uniform sampler2DShadow shadowMap;

void main()
{
    fragColor = vec4(texture(texturex, UV).rgb,1);

    float shadow = 1.0;
    shadow = textureProj(shadowMap,shadowProj);

    fragColor *= shadow;

}

Затем я снова рисую дом в цвете и... пол:

textureShader.use();

glUniform1i(baseImageLoc, 0); //Texture unit 0 is for base images.
glUniform1i(shadowMapLoc, 1); //Texture unit 1 is for shadow maps.

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, floorTexture);

glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, shadowTexture);
textureShader["shadowMatrix"] = projectionMatrix*pointLight.viewMatrix*floorMatrix;
textureShader["mvp"] = projectionMatrix*viewMatrix*floorMatrix;
CALL_GL(glBindVertexArray(floorVAO));
CALL_GL(glDrawArrays(GL_TRIANGLES,0,18));

glfwSwapBuffers();

Кто-нибудь видел такое поведение раньше? Есть идеи, что может быть не так? Кстати, координаты источника света помещают его прямо над домом, поэтому тень должна быть прямо под домом на полу (но заканчивается сбоку).

Для справки, вот как я генерирую теневой FBO:

int shadowMapWidth = WINDOW_SIZE_X * (int)SHADOW_MAP_RATIO;
int shadowMapHeight =  WINDOW_SIZE_Y * (int)SHADOW_MAP_RATIO;

glGenTextures(1, &shadowTexture);
glBindTexture(GL_TEXTURE_2D, shadowTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, shadowMapWidth, shadowMapHeight, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
glTexImage2D(GL_TEXTURE_2D,0,GL_DEPTH_COMPONENT,shadowMapWidth,shadowMapHeight,0,GL_DEPTH_COMPONENT,GL_FLOAT,NULL);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_COMPARE_MODE,GL_COMPARE_R_TO_TEXTURE);
glBindTexture(GL_TEXTURE_2D, 0); //unbind the texture

glGenFramebuffers(1, &shadowFBO);
glBindFramebuffer(GL_FRAMEBUFFER, shadowFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, shadowTexture, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{ printf("GL_FRAMEBUFFER_COMPLETE error 0x%x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); }

glClearDepth(1.0f); glEnable(GL_DEPTH_TEST);
// Needed when rendering the shadow map. This will avoid artifacts.
glPolygonOffset(1.0f, 0.0f); glBindFramebuffer(GL_FRAMEBUFFER, 0);
//to convert the texture coordinates to -1 ~ 1
   GLfloat biasMatrixf[] = {
    0.5f, 0.0f, 0.0f, 0.0f,
    0.0f, 0.5f, 0.0f, 0.0f,
    0.0f, 0.0f, 0.5f, 0.0f,
    0.5f, 0.5f, 0.5f, 1.0f };

biasMatrix = glm::make_mat4(biasMatrixf);

person Jubei    schedule 01.04.2013    source источник


Ответы (1)


Похоже, вы забыли умножить матрицу теней на матрицу смещения.

person bwroga    schedule 01.04.2013
comment
Спасибо!!! Вот в чем проблема! Кроме того, моя матрица смещения была неправильной! 0.5f должно быть в нижней строке, а не в самом правом столбце (я отредактировал код, чтобы отразить это). GLfloatbiasMatrixf[] = {0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 0.5f, 0.5f , 1.0f }; - person Jubei; 02.04.2013
comment
Между прочим, хорошая работа. Ваш домик выглядит довольно забавно :). Картирование теней — одна из вещей в моем списке дел. Боюсь этого на самом деле. - person Robinson; 02.04.2013