在制作用于阴影贴图的立方体贴图时遇到问题

时间:2018-12-20 11:16:09

标签: c++ opengl mapping shadow

我设法只向一个方向执行阴影映射,这意味着我创建了2D纹理深度图。现在使用全向阴影贴图,我遇到了一些麻烦。这是我的代码的主要部分:

首先渲染-创建立方体贴图

glUseProgram(cubeShader);
    glViewport(0, 0, 1024, 1024);
    glBindFramebuffer(GL_FRAMEBUFFER, depthCubeMapFBO);
    glClear(GL_COLOR_BUFFER_BIT);
    glBindFramebuffer(GL_FRAMEBUFFER, depthCubeMapFBO);
    glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubeMap, 0);


    mat4 modelMatrix = mat4(1);
    glUniform3f(lightLocationCube, lightPos.x, lightPos.y, lightPos.z);
    glUniform1f(farPlaneCubeLoc, 25.0f);
    mat4 shadowProj = perspective(double(radians(90.0f)), 4.0 / 4.0, 1.0, 10.0);
    lightTransforms.clear();
    lightTransforms.push_back(shadowProj *
        glm::lookAt(lightPos, lightPos + glm::vec3(1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
    lightTransforms.push_back(shadowProj *
        glm::lookAt(lightPos, lightPos + glm::vec3(-1.0, 0.0, 0.0), glm::vec3(0.0, -1.0, 0.0)));
    lightTransforms.push_back(shadowProj *
        glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 1.0, 0.0), glm::vec3(0.0, 0.0, 1.0)));
    lightTransforms.push_back(shadowProj *
        glm::lookAt(lightPos, lightPos + glm::vec3(0.0, -1.0, 0.0), glm::vec3(0.0, 0.0, -1.0)));
    lightTransforms.push_back(shadowProj *
        glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, 1.0), glm::vec3(0.0, -1.0, 0.0)));
    lightTransforms.push_back(shadowProj *
        glm::lookAt(lightPos, lightPos + glm::vec3(0.0, 0.0, -1.0), glm::vec3(0.0, -1.0, 0.0)));

    for (int i = 0; i < 6; ++i) {
        mat4 nowT = lightTransforms[i];
        glUniformMatrix4fv(shadowMatricesCubeLoc[i], 1, GL_FALSE, &nowT[0][0]);
    }


    glBindVertexArray(objVAO);
    glBindFramebuffer(GL_FRAMEBUFFER, depthCubeMapFBO);
    glUniformMatrix4fv(modelMatrixCubeLoc, 1, GL_FALSE, &modelMatrix[0][0]);
    glDrawArrays(GL_TRIANGLES, 0, objVertices.size());
    modelMatrix *= translate(mat4(), vec3(0, 0, 5))*rotate(mat4(), 3.14f, vec3(0, 1, 0));
    glUniformMatrix4fv(modelMatrixCubeLoc, 1, GL_FALSE, &modelMatrix[0][0]);
    glDrawArrays(GL_TRIANGLES, 0, objVertices.size());

    // Drawing a cube
    glBindVertexArray(planeVAO);
    glBindFramebuffer(GL_FRAMEBUFFER, depthCubeMapFBO);
    modelMatrix = scale(mat4(), vec3(10, 10, 0));
    modelMatrix = rotate(mat4(), radians(0.0f), vec3(0, 1, 0));
    glUniformMatrix4fv(modelMatrixCubeLoc, 1, GL_FALSE, &modelMatrix[0][0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    modelMatrix = scale(mat4(), vec3(10, 10, 0));
    modelMatrix = rotate(mat4(), radians(90.0f), vec3(0, 1, 0));
    glUniformMatrix4fv(modelMatrixCubeLoc, 1, GL_FALSE, &modelMatrix[0][0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    modelMatrix = scale(mat4(), vec3(10, 10, 0));
    modelMatrix = rotate(mat4(), radians(180.0f), vec3(0, 1, 0));
    glUniformMatrix4fv(modelMatrixCubeLoc, 1, GL_FALSE, &modelMatrix[0][0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);
    modelMatrix = scale(mat4(), vec3(10, 10, 0));
    modelMatrix = rotate(mat4(), radians(270.0f), vec3(0, 1, 0));
    glUniformMatrix4fv(modelMatrixCubeLoc, 1, GL_FALSE, &modelMatrix[0][0]);
    glDrawArrays(GL_TRIANGLES, 0, 6);


    glBindFramebuffer(GL_FRAMEBUFFER, 0);

}

之前,我已经为多维数据集映射完成了相对的“声明”(如果我使用正确的词):

glGenFramebuffers(1, &depthCubeMapFBO);
glGenTextures(1, &depthCubeMap);
glBindTexture(GL_TEXTURE_CUBE_MAP, depthCubeMap);
for (unsigned int i = 0; i < 6; i++) {
    glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, NULL);

}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);


glBindFramebuffer(GL_FRAMEBUFFER, depthCubeMapFBO);
glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthCubeMap, 0);
glDrawBuffer(GL_NONE);
glReadBuffer(GL_NONE);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

//CubeMapLocs

lightLocationCube = glGetUniformLocation(cubeShader, "lightPos");
modelMatrixCubeLoc = glGetUniformLocation(cubeShader, "M");
farPlaneCubeLoc = glGetUniformLocation(cubeShader, "far_plane");
for (int i = 0; i < 6; i++) {
    string added = "shadowMatrices[" + std::to_string(i) + "]";
    shadowMatricesCubeLoc[i] = glGetUniformLocation(cubeShader, added.c_str());

}

现在,我将不会在第二个渲染循环中包含所有内容,因为您可能会看到一些奇怪的东西,它会很长,但这是我将纹理发送到着色器的地方:

glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, diffuseTexture);
    glUniform1i(diffuceColorSampler, 0);

    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, specularTexture);
    glUniform1i(specularColorSampler, 1);

    glActiveTexture(GL_TEXTURE2);
    glBindTexture(GL_TEXTURE_CUBE_MAP , depthCubeMap);
    glUniform1i(shadowMapLoc, 2);

我正在为此循环使用第二个着色器,现在我将把所有内容都包含在两个着色器中

第一循环顶点着色器:

    #version 330 core

uniform mat4 M;
layout(location = 0) in vec3 vertexPosition_modelspace;

void main()
{
    gl_Position=M*vec4(vertexPosition_modelspace,1.0);

}

第一循环几何着色器:

#version 330 core
layout (triangles) in;
layout (triangle_strip, max_vertices=18) out;

uniform mat4 shadowMatrices[6];

out vec4 FragPos; 

void main()
{
    for(int face = 0; face < 6; ++face)
    {
        gl_Layer = face;
        for(int i = 0; i < 3; ++i) 
        {
            FragPos = gl_in[i].gl_Position;
            gl_Position = shadowMatrices[face] * FragPos;
            EmitVertex();
        }    
        EndPrimitive();
    }
} 

第一循环片段着色器

    #version 330 core
in vec4 FragPos;


uniform vec3 lightPos;
uniform int far_plane;


void main()
{
    // get distance between fragment and light source
    float lightDistance = length(FragPos.xyz - lightPos);
    // map to [0;1] range by dividing by far_plane
    lightDistance = lightDistance / 25.0;
    // write this as modified depth
    gl_FragDepth = lightDistance;
    //col=gl_FragDepth*vec4(1,1,1,1);
    //col.w=1;
    //col=vec4(0.5,0,1.0,1.0);
    //fragment_color = vec4(vec3(closestDepth / 25.0), 1.0);
}

第二循环顶点着色器

#version 330 core

// construct input layout for the corresponding attributes
// (vertexPosition_modelspace, vertexNormal_modelspace, vertexUV)
layout(location = 0) in vec3 vertexPosition_modelspace;
layout(location = 1) in vec3 vertexNormal_modelspace;
layout(location = 2) in vec2 vertexUV;

// Output variables (position_modelspace, normal_modelspace and UV coordinates), 
// that will be interpolated for each fragment
out vec3 vertex_position_modelspace;
out vec3 vertex_normal_modelspace;
out vec2 vertex_UV;

out vec3 vertexWorldspace;

// uniforms (P, V, M)
uniform mat4 P;
uniform mat4 V;
uniform mat4 M;

uniform mat4 lightSpaceTransform;

out vec4 vertex_LightSpace;

void main()
{

    vertex_LightSpace=lightSpaceTransform*M*vec4(vertexPosition_modelspace,1.0);

    gl_Position =  P * V * M * vec4(vertexPosition_modelspace, 1);

    // propagate the position of the vertex to fragment shader
    vertex_position_modelspace = vertexPosition_modelspace;

    //propagte vertex in world space
    vec4 vm=M*vec4(vertexPosition_modelspace, 1);
    vertexWorldspace=vm.xyz;


    //propagate the normal of the vertex to fragment shader
    vertex_normal_modelspace = vertexNormal_modelspace; 

    // propagate the UV coordinates   
    vertex_UV = vertexUV;
}

在这里,我将跳过照明计算,因为它们可以正常工作。我在末尾添加了额外的行,以使对象以与立方体图中的深度相对应的颜色显示: 2n渲染循环片段着色器

uniform sampler2D diffuseColorSampler;
uniform sampler2D specularColorSampler;
uniform samplerCube shadowMap;

float ShadowCalculation(vec3 fragPos)
{
    vec3 lightPos=light_position_worldspace;
    vec3 fragToLight = fragPos - lightPos;

    float closestDepth = texture(shadowMap, fragToLight).r;
    closestDepth *= 25.0;
    float currentDepth = length(fragToLight);
    float bias = 0.05;
    float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0;
    return shadow;
}

//skipping to the end of the main loop
//fragment_color is the output

vec3 fragToLight = vertexWorldspace - light_position_worldspace;


    float closestDepth = texture(shadowMap, fragToLight).r;
    if(closestDepth>0){
        fragment_color = vec4(1.0,0,0, 1.0);
    }
    fragment_color = vec4(vec3(closestDepth / 25.0), 1.0);

运行此命令,每个对象都是黑色的。我认为这意味着您在右上方看到的变量“ closestDepth”始终为零,这意味着多维数据集映射有问题……

0 个答案:

没有答案