0
\$\begingroup\$

Basically, I'm following tutorials as I'm very new to OpenGL. I managed to perform shadow mapping towards just one direction, meaning I created 2D texture depth map. Now with omnidirectional shadow mapping I'm having some trouble. Here are the main parts of my code:

First render-creating the cube map

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);

}

Earlier I've done the relative 'declarations' (if I'm using the right word) for the cube map :

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());

}

Now I will not include everything in the second rendering loop as you'll probably see some weird stuff and it's gonna be very long but here is where I send the textures to the shader :

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);

I'm using a second shader for this loop and now I will include everything in the two shaders

1st loop vertex shader :

    #version 330 core

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

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

}

1st loop geometry shader :

#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();
    }
} 

1st loop fragment shader

    #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);
}

2nd loop vertex shader

#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;
}

Here I will skip the lighting computations as they work fine. I add the extra lines at the end so that the objects appear in a color respective to their depth in the cube map: 2n render loop fragment shader

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);

Running this, every object is black. I think this means that the variable 'closestDepth' which you see right above, is always zero, meaning something is wrong with the cube map...

I can upload anything else you might need. I've been looking at all this all night and I can't find what's wrong. Any help is greatly appreciated.

Edit: Checking my cube map in renderDoc I found out that it's all black.

\$\endgroup\$
0
\$\begingroup\$

First step is to verify if the cubemap actually gets rendered properly. You can use tools such as RenderDoc to inspect the contents of the cubemap.

\$\endgroup\$
  • \$\begingroup\$ It me some time but I checked and the cube map is indeed all black. \$\endgroup\$ – John Katsantas Dec 20 '18 at 22:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.