View Full Version : Shadow Map not working. Whole mesh is in shadow

12-09-2014, 05:51 AM
First time trying to implement shadow map using openGL and glsl shader language. I think the first pass where I render to a texture is correct but when I compare the depth values it seems to shadow everything.


My perspective projection matrix looks like this:

FOV = 90
Aspect = According to the programs window size. (I also tried to put different values here)
Near = 2;
Far= 10000;

Function to initialize the frame buffer

void OpenGLWin::initDepthMap()
m_glFunctions->glGenFramebuffers(1, &m_frameBuffer);
m_glFunctions->glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer);

//Texture to render scene to
m_glFunctions->glGenTextures(1, &m_renderToTexture);
//Bind created texture to make it current
m_glFunctions->glBindTexture(GL_TEXTURE_2D, m_renderToTexture);

//Creates an empty texture of specified size.
//m_glFunctions->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 1024, 768, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
m_glFunctions->glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);

m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

m_glFunctions->glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);


// Always check that our framebuffer is ok
if (m_glFunctions->glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE){
qDebug() << "FrameBuffer not OK";

m_glFunctions->glBindFramebuffer(GL_FRAMEBUFFER, 0);

Draw function for each mesh. Model matrix is passed as argument from a Transform class draw function

void Mesh::draw(const Matrix4x4& projection, const Matrix4x4& view, const Matrix4x4& model)
//Shadow map pass 1
if (m_shadowMapFirstpass){
//Pass 1 Shaders

//Light view matrix
m_depthMVP = projection*view*model;
//Get the location of the uniform name mvp
GLuint depthMVPLocation = m_glFunctions->glGetUniformLocation(m_depthRTTShaderProgram, "depthMVP");
m_glFunctions->glUniformMatrix4fv(depthMVPLocation, 1, GL_TRUE, &m_depthMVP[0][0]);

m_shadowMapFirstpass = false;
//Shadow map pass 2
else if(m_shadowMapFirstpass == false){
//Pass 2 Shader
//Gets the model matrix which is then multiplied with view and projection to form the mvp matrix
Matrix4x4 mvp = projection * view * model;

//Get the location of the uniform name mvp
GLuint mvpLocation = m_glFunctions->glGetUniformLocation(m_shaderProgram, "mvp");

//Send the mvp matrix to the vertex shader
m_glFunctions->glUniformMatrix4fv(mvpLocation, 1, GL_TRUE, &mvp[0][0]);

Matrix4x4 depthBiasMVP = m_depthMVP;// biasMatrix*m_depthMVP;
GLuint depthBiasMVPLocation = m_glFunctions->glGetUniformLocation(m_shaderProgram, "depthBiasMVP");

m_glFunctions->glUniformMatrix4fv(depthBiasMVPLocation, 1, GL_TRUE, &depthBiasMVP[0][0]);

m_shadowMapFirstpass = true;

//Bind this mesh VAO
//Draw the triangles using the index buffer(EBO)
glDrawElements(GL_TRIANGLES, m_indices.size(), GL_UNSIGNED_INT, 0);

//Unbind the VAO

//Calls the childrens' update
if (!m_children.empty())
for (int i = 0; i < m_children.size(); i++)
if (m_children[i] != NULL)
m_children[i]->draw(frustumCheck, projection, view, bvScaleFactor, model);

My render loop

void OpenGLWin::paintGL()
// m_glFunctions->glBindFramebuffer(GL_FRAMEBUFFER, m_frameBuffer);
m_glFunctions->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_frameBuffer);

glViewport(0, 0, 1024, 1024);
// Clear the buffer with the current clearing color

//Light View Matrix
Matrix4x4 lightView;
lightView.lookAt(Vector3(0, 0, 0), Vector3(0, 0, -1), Vector3(0, 1, 0));

//Draw scene to Texture
m_root->draw(m_projection, lightView);

//Draw to real scene
m_glFunctions->glBindFramebuffer(GL_FRAMEBUFFER, 0);
// m_glFunctions->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);

// Clear the screen
//Bind Pass 2 shader

GLuint shadowMapLocation = m_glFunctions->glGetUniformLocation(m_shadowMapShaderProgram->getShaderProgramID(), "shadowMap");

//Shadow Texture
m_glFunctions->glBindTexture(GL_TEXTURE_2D, m_renderToTexture);
m_glFunctions->glUniform1i(shadowMapLocation, 0);

//Updates matrices and view matrix for player camera

//Render scene to main frame buffer
m_root->draw(m_projection, m_view);


Pass 1 Vertex Shader

#version 330 core
//Passthrough vertex shader

uniform mat4 depthMVP;

//Vertex received from the program
layout(location = 0) in vec3 vertexPosition_modelspace;

void main(void)
//Output position of vertex in clip space
gl_Position = depthMVP * vec4(vertexPosition_modelspace, 1);

Pass 1 Fragment Shader

#version 330 core
//Render to texture

// Ouput data
layout(location = 0) out float depthValue;

void main(void)
depthValue = gl_FragCoord.z;

Pass 2 Vertex Shader

#version 330 core

layout(location = 0) in vec3 vertexPosition_modelspace;

out vec4 ShadowCoord;

// Values that stay constant for the whole mesh.
uniform mat4 mvp;
uniform mat4 depthBiasMVP;

void main(){

// Output position of the vertex, in clip space : MVP * position
gl_Position = mvp * vec4(vertexPosition_modelspace,1);

ShadowCoord = depthBiasMVP * vec4(vertexPosition_modelspace,1);


Pass 2 Fragment Shader

#version 330 core

in vec4 ShadowCoord;

// Ouput data
layout(location = 0) out vec3 color;

// Values that stay constant for the whole mesh.
uniform sampler2D shadowMap;

void main(){

float visibility=1.0;

vec3 ProjCoords = ShadowCoord.xyz / ShadowCoord.w;
vec2 UVCoords;
UVCoords.x = 0.5 * ProjCoords.x + 0.5;
UVCoords.y = 0.5 * ProjCoords.y + 0.5;
float z = 0.5 * ProjCoords.z + 0.5;
float Depth = texture(shadowMap, UVCoords).z;//or x
if (Depth < (z + 0.00001)){
visibility = 0.1;

color = visibility*vec3(1,0,0);


12-09-2014, 10:58 AM

you need to calculate the projection matrix for the depth map onto the normal szene.
m_depthMVP << this is not enough.


12-10-2014, 01:44 AM
I fixed the issue

Disabled that
plus I sampled .z but now i changed to .x

float Depth = texture(shadowMap, UVCoords).x;

I think it has to be .x because the depth value is a single float component and not a vector. (Correct me if i'm wrong)