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