Почему неправильно рисуются тени (shadow mapping)?

Рейтинг: 1Ответов: 0Опубликовано: 26.05.2023

Обзор программы:

  • Есть два треугольника. Треугольник слева ближе к источнику света. Треугольник справа дальше от другого треугольника на 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);
}

Ответы

Ответов пока нет.