# OpenGL Depth Cubemap with Geometry Shader Not Rendering Correctly

I was having some trouble with cubemaps in OpenGL, and was hoping to get some help. I've been following a tutorial about point light shadow mapping using cubemaps, where a geometry shader is used to render to all faces of the cubemap once instead of 6 times (once per face). Apparently because of my low reputation, I can't post more than 2 links, so I will edit this question with the site once I gain the reputation for it.

After following the tutorial, I've encountered a few problems. The first is that the different sides of the cubemap don't seem to line up, and the positive and negative y sides render at a very different-looking perspective. Here's a screenshot to illustrate this:

Sorry for the dark image. This was generated by simply projecting the rendered cubemap to the geometry. You can clearly see where the three sides intersect, they don't line up. There is also a problem with incorrect depth values, seen better by the final render:

Everything's a bit reversed. The shadowed parts are unshadowed and vice-versa for the positive and negative y faces, and no shadows are seen on any of the other 4 faces.

So those are the problems I'm experiencing. Code-wise, I start by creating the cubemap:

glGenTextures(1, &cubemapID);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubemapID);

for (int i = 0; i < 6; i++) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_DEPTH_COMPONENT, texture.width, texture.height, 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);


Then I update the projection and view matrices for the light, and pass them to a render function:

// rendering for shadowmap
if (meshes.size() > 0) {
glBindFramebuffer(GL_FRAMEBUFFER, depthFBO);
glClear(GL_DEPTH_BUFFER_BIT);

// create the depth projection matrix - shared among all 6 sides
float farPlane = 25.0f;
depthProjectionMatrix = Matrix4::Perspective(90.0f, 1.0f, 1.0f, farPlane);

// create the depth view matrices - different for each side
vector<Matrix4> depthViewMatrices;
depthViewMatrices.push_back(depthProjectionMatrix * Matrix4::LookAt(transform.position, transform.position + Vector3(1, 0, 0), Vector3(0, -1, 0))); // positive x
depthViewMatrices.push_back(depthProjectionMatrix * Matrix4::LookAt(transform.position, transform.position + Vector3(-1, 0, 0), Vector3(0, -1, 0)));    // negative x
depthViewMatrices.push_back(depthProjectionMatrix * Matrix4::LookAt(transform.position, transform.position + Vector3(0, 1, 0), Vector3(0, 0, 1)));  // positive y
depthViewMatrices.push_back(depthProjectionMatrix * Matrix4::LookAt(transform.position, transform.position + Vector3(0, -1, 0), Vector3(0, 0, -1)));    // negative y
depthViewMatrices.push_back(depthProjectionMatrix * Matrix4::LookAt(transform.position, transform.position + Vector3(0, 0, 1), Vector3(0, -1, 0))); // positive z
depthViewMatrices.push_back(depthProjectionMatrix * Matrix4::LookAt(transform.position, transform.position + Vector3(0, 0, -1), Vector3(0, -1, 0)));    // negative z

for (int i = 0; i < meshes.size(); i++) {
}

glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
}


// point light shadowmap rendering
glBindBuffer(GL_ARRAY_BUFFER, vbo);                 // vertex buffer
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_vbo);   // Index buffer

// buffer the vertex attributes
glEnableVertexAttribArray(0);   // position
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, (void*)0);

// Draw the triangles !
glDrawElements(GL_TRIANGLES, numberOfIndices, GL_UNSIGNED_INT, NULL);

glDisableVertexAttribArray(0);
}


#version 330 core

layout (location = 0) in vec4 position;

uniform mat4 model;

void main()
{
// transform to world space for geometry shader
gl_Position = model * vec4(position.xyz, 1.0);
}


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

out vec4 FragPos;   // FragPos from geometry shader (output per emitvertex)

void main()
{
// iterate through each face on the cubemap
// for each face, render each triangle, transforming it by the relevant shadow view matrix
// also send the result to the fragment shader (FragPos)
for (int face = 0; face < 6; face++) {
gl_Layer = face;    // built-in variable that specifies which face of the cubemap we render
for (int i = 0; i < 3; i++) {   // for each triangle's vertices
FragPos = gl_in[i].gl_Position;
EmitVertex();
}
EndPrimitive();
}
}


#version 330 core

in vec4 FragPos;

uniform vec3 lightPos;
uniform float 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 / far_plane;

// write this as modified depth
gl_FragDepth = lightDistance;
}


Finally, in my point light fragment shader, I have a debug function, used to produce the first screenshot, and the actual shadow amount function, used for the final render. The first is:

vec3 fragToLight = worldPos.xyz - pointLight.baseLight.Transform.Position;

float closestDepth = texture(pointLight.DepthTexture, fragToLight).r;



And the second is:

vec3 fragToLight = worldPos.xyz - pointLight.baseLight.Transform.Position;
// Use the light to fragment vector to sample from the depth map
float closestDepth = texture(pointLight.DepthTexture, fragToLight).r;
// It is currently in linear range between [0,1]. Re-transform back to original value