Почему неправильно рисуются тени (shadow mapping)?
Обзор программы:
- Есть два треугольника. Треугольник слева ближе к источнику света. Треугольник справа дальше от другого треугольника на 0.5 юнитов;
- Собственный цвет треугольников — белый;
- Места с тенью программа должна красить в красный цвет, но из за её неправильной работы оба треугольника абсолютно красные
Ошибок с шейдерами нет. Ошибок рисования тоже нет. Что не так и как исправить это?
Источник света находится слева от камеры.
Shadow Mapping.cpp
// draw the shadow map
GLuint depthMapFBO;
glGenFramebuffers(1, &depthMapFBO);
const unsigned int SHADOW_WIDTH = 1024, SHADOW_HEIGHT = 1024;
GLuint depthMap;
glGenTextures(1, &depthMap);
glBindTexture(GL_TEXTURE_2D, depthMap);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, SHADOW_WIDTH, SHADOW_HEIGHT, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depthMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glClear(GL_DEPTH_BUFFER_BIT);
depthShader.use();
glm::mat4 lightProjection, lightView;
glm::mat4 lightSpaceMatrix;
lightProjection = glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, 1.0f, 7.5f);
lightView = glm::lookAt(glm::vec3(0.0, 0.0, 5.0), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));
lightSpaceMatrix = lightProjection * lightView;
depthShader.setMat4("lightSpaceMatrix", lightSpaceMatrix);
depthShader.setMat4("model", firstModel);glViewport(0, 0, SHADOW_WIDTH, SHADOW_HEIGHT);
glClear(GL_DEPTH_BUFFER_BIT);
glDrawArrays(GL_TRIANGLES, 0, 6);
depthShader.setMat4("model", secondModel);
glDrawArrays(GL_TRIANGLES, 0, 6);
// drawing time ...
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
glClearColor(0.0, 0.0, 0.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
regularShader.use();
glm::mat4 cameraProjection = glm::perspective(glm::radians(45.0f), WINDOW_WIDTH / WINDOW_HEIGHT, 0.1f, 100.0f);
glm::mat4 cameraView = glm::lookAt(glm::vec3(3.0, 0.0, 5.0), glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0, 1.0, 0.0));
glm::mat4 cameraSpcaeMatrix = cameraProjection * cameraView;
regularShader.setMat4("cameraSpcaeMatrix", cameraSpcaeMatrix);
regularShader.setMat4("lightSpaceMatrix", lightSpaceMatrix);
regularShader.setMat4("model", firstModel);
regularShader.setInt("shadowMap", depthMap);
glDrawArrays(GL_TRIANGLES, 0, 6);
regularShader.setMat4("cameraSpcaeMatrix", cameraSpcaeMatrix);
regularShader.setMat4("lightSpaceMatrix", lightSpaceMatrix);
regularShader.setMat4("model", secondModel);
regularShader.setInt("shadowMap", depthMap);
glDrawArrays(GL_TRIANGLES, 0, 6);
regular_shader.vs (рисует сцену на экран)
#version 330 core
out vec4 FragPosLightSpace;
in vec2 position;
uniform mat4 cameraSpcaeMatrix;
uniform mat4 lightSpaceMatrix;
uniform mat4 model;
void main()
{
FragPosLightSpace = lightSpaceMatrix * model * vec4(position, 0.0, 1.0);
gl_Position = cameraSpcaeMatrix * model * vec4(position, 0.0, 1.0);
}
regular_shader.fs
#version 330 core
in vec4 FragPosLightSpace;
uniform sampler2D shadowMap;
void main()
{
vec3 projectedCoords = FragPosLightSpace.xyz / FragPosLightSpace.w;
projectedCoords = projectedCoords * 0.5 + 0.5;
float shadowDepth = texture(shadowMap, projectedCoords.xy).r;
float currentDepth = projectedCoords.z;
if (currentDepth > shadowDepth) // draw shadow
{
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
else // there is no shadow
{
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
}
}
depth_shader.vs (рисует карту теней)
#version 330 core
layout (location = 0) in vec2 aPos;
uniform mat4 lightSpaceMatrix;
uniform mat4 model;
void main()
{
gl_Position = lightSpaceMatrix * model * vec4(aPos, 0.0, 1.0);
}
Источник: Stack Overflow на русском