OpenGL 阴影映射将所有内容染成黑色

问题描述 投票:0回答:1

我一直在尝试实现阴影贴图,但是整个场景是黑色的,而它绝对不应该是黑色的。

我在 (4, 1, 4) 处初始化一盏灯,方向为 (0, 0, 0)。这是我的主渲染循环的样子:

glfwMakeContextCurrent(window); // tell openGL we are outputting to this
target_scene->shadow_pass();    // create shadow maps
glViewport(0, 0, width, height); // swap back to our resolution
// render the scene
target_scene->render(target_camera, width / float(height));
// show the rendered scene
glfwSwapBuffers(window);

我知道渲染方法可以正确运行,因为它在实现阴影贴图之前确实工作得很好。

shadow_pass 方法如下所示:

void scene::shadow_pass() const {
    glCullFace(GL_FRONT);
    // resize the viewport to the shadow resolution
    glViewport(0, 0, SHADOW_RES, SHADOW_RES);
    // activate the super simple shader for the shadow pass
    light_pass_shader->use();
    for (const light *lght : lights) {
        lght->bind_depth_map(); // activate the framebuffer
        light_pass_shader->apply_uniform_mat4(lght->get_light_space(),
                                              "lightSpaceMatrix");
        // draw all the objects
        for (object *obj : objects) {
            light_pass_shader->apply_uniform_mat4(obj->get_model_matrix(),
                                                  "model");
            obj->draw();
        }
        // cleanup
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
    }
    glUseProgram(0);
    glCullFace(GL_BACK);
}

这是我计算光空间矩阵并激活帧缓冲区的方法:

const static glm::mat4 lightProjection =
    glm::perspective(90.0f, 1.0f, 1.0f, 10.0f);

const glm::mat4 light::get_light_space() const {
    return lightProjection * glm::lookAt(this->get_position(),
                                         this->get_direction(),
                                         glm::vec3(0.0f, 1.0f, 0.0f));
}

void light::bind_depth_map() const {
    glBindFramebuffer(GL_FRAMEBUFFER, depthMapFBO);
    glClear(GL_DEPTH_BUFFER_BIT);
}

这就是绘制的样子,它可能没问题,因为它在第二遍中使用。

void object::draw() const {
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, index_count, GL_UNSIGNED_INT, NULL);
    glBindVertexArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}

这是我的光通着色器的样子:

#version 430 core

layout(location = 0) in vec3 vertexPosition;
layout(location = 1) in vec3 vertexNormal;
layout(location = 2) in vec2 vertexTexCoord;    
layout(location = 3) in vec3 vertexTangent;
layout(location = 4) in vec3 vertexBitangent;

uniform mat4 lightSpaceMatrix;
uniform mat4 model;

void main()
{
    gl_Position = lightSpaceMatrix * model * vec4(vertexPosition, 1.0);
}

这是我的顶点和片段着色器在主渲染过程中的样子。

#version 430 core

layout(location = 0) in vec3 vertexPosition;
layout(location = 1) in vec3 vertexNormal;
layout(location = 2) in vec2 vertexTexCoord;    
layout(location = 3) in vec3 vertexTangent;
layout(location = 4) in vec3 vertexBitangent;

out vec2 texCoord;
out mat3 TBN;
out vec3 fragPos;
out vec3 normal;

out vec3 viewPos;
out vec3 shininess;

uniform mat4 model;
uniform mat4 viewProjection;

void main()
{
    // Transform the vertex position by the model and view-projection matrices
    gl_Position = viewProjection * model * vec4(vertexPosition, 1.0);
    texCoord = vertexTexCoord;

    // Transform the fragment position by the model matrix only
    fragPos = vec3(model * vec4(vertexPosition, 1.0));

    // Transform the normal by the model matrix only
    normal = mat3(model) * vertexNormal;

    // Calculate the TBN matrix using the model matrix only
    vec3 T = normalize(mat3(model) * vertexTangent);
    vec3 B = normalize(mat3(model) * vertexBitangent);
    vec3 N = normalize(mat3(model) * vertexNormal);
    TBN = mat3(T, B, N);
}
#version 430 core

#define MAX_LIGHTS 10
#define bias 0.005

in vec2 texCoord;
in vec3 fragPos;
in vec3 normal;
in mat3 TBN;

uniform sampler2D texture0;
uniform sampler2D normal0;

struct Light {
    vec3 direction;
    vec3 color;
    mat4 lightSpaceMatrix;
    sampler2D shadowMap;
};

uniform Light lights[MAX_LIGHTS];
uniform int numLights;

uniform vec3 viewPos;
uniform float shininess;
uniform vec3 ambientLight;

out vec4 out_color;

vec3 CalcDirectionalLight(Light light, vec3 norm)
{
    vec3 lightDir = normalize(-light.direction);
        
    // Diffuse shading
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * light.color;

    // Specular shading
    vec3 viewDir = normalize(viewPos - fragPos);
    vec3 reflectDir = reflect(-lightDir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), shininess);
    vec3 specular = spec * light.color;

    // Shadow calculation
    vec4 fragPosLightSpace = light.lightSpaceMatrix * vec4(fragPos, 1.0);
    vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
    projCoords = projCoords * 0.5 + 0.5;

    float closestDepth = texture(light.shadowMap, projCoords.xy).r;
    float currentDepth = projCoords.z;
    float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;

    return (1.0 - shadow) * (diffuse + specular);
}

void main()
{
    vec3 norm = texture(normal0, texCoord).rgb;
    norm = normalize(norm * 2.0 - 1.0);
    norm = normalize(TBN * norm);

    vec3 result = ambientLight;
    for (int i = 0; i < numLights; ++i) {
        result += CalcDirectionalLight(lights[i], norm);
    }

    vec4 color = texture(texture0, texCoord);
    out_color = vec4(result * color.rgb, color.a);
}

帮助我,我很困惑。

c++ opengl glfw glm-math shadow-mapping
1个回答
0
投票

我明白了。这只是我将阴影贴图以

depthMap
的形式传递给着色器,然后我尝试在着色器端以
shadowMap
的形式访问它,这当然是无稽之谈。该死的。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.