Monday, February 22, 2016

opengl - I can't make the cube map to use shadow mapping - or it seems so


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.




No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...