PDA

View Full Version : Problem Rendering Shadow Map



Niven07
12-29-2013, 11:44 AM
I'm attempting to add shadow mapping to my programs using a spotlight as the light source. I've set up enough to be able to render my shadow map, but whenever I look at it, it's just a black square. I'm certain that I'm rendering it correctly, so the problem is with actually storing depth values in the texture. Does anyone have any ideas what could be causing this?

Code Snippets:


void ShadowShader::Init(SpotLight Light)
{
...

Source = Light;
Projection = perspective(Source.Cutoff, 1.0f, 1.f, 20.f);
View = lookAt(Source.Position_WS, Source.Position_WS + Source.Direction_WS, vec3(0,1,0));

glGenFramebuffers(1, &FrameBufferID);
glBindFramebuffer(GL_FRAMEBUFFER, FrameBufferID);

glGenTextures(1, &DepthTextureID);
glBindTexture(GL_TEXTURE_2D, DepthTextureID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, 1024, 1024, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, DepthTextureID, 0);

glReadBuffer(GL_NONE);
glDrawBuffer(GL_NONE);

if( glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE )
{
WritetoLog("Failed to Initialize Framebuffer - " + FloatToString(glCheckFramebufferStatus(GL_FRAMEBUF FER)));
exit(0xBAD);
}

glBindFramebuffer(GL_FRAMEBUFFER, NULL);

...
}




void Display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

glEnable(GL_DEPTH_TEST);

...

//1st Pass
ShadowProgram.Bind();
glBindFramebuffer(GL_FRAMEBUFFER, ShadowProgram.GetFrameBufferID());
glViewport(0,0,1024,1024);
StandardRendering(); // Draw the scene
glBindFramebuffer(GL_FRAMEBUFFER, NULL);
ShadowProgram.UnBind();

//2nd Pass
glViewport(0,0,WINDOW_DIMENSIONS.x,WINDOW_DIMENSIO NS.y);
StandardProgram.Bind();

Texture Temp;
Temp.TextureID = ShadowProgram.GetTextureID();
Temp.ImgHeight = Temp.ImgWidth = Temp.TexHeight = Temp.TexWidth = 1024;

StandardProgram.Scale(30);
StandardProgram.TransformModel();
DrawUnitSquare(&Temp);
}


ShadowProgram's Shaders:


#version 330 core

layout(location = 0) in vec3 Position;

uniform mat4 depthMVP;

void main()
{
gl_Position = depthMVP * vec4(Position,1);
}




#version 330 core

layout(location = 0) out float fragmentdepth;

void main()
{
fragmentdepth = gl_FragCoord.z;
}

SwitchMan92
12-30-2013, 05:00 AM
Hi,

How do you set up your depthMVP ? have you tried to set up camera to light to be sure you're rendering the same position and direction as the light ?

Try to set glCullFace(GL_BACK); before //1st pass
and glCullFace(GL_FRONT); before //2nd pass

Niven07
12-30-2013, 08:30 AM
1208



Projection = perspective(Source.Cutoff, 1.0f, .1f, 30.f);
View = lookAt(Source.Position_WS, Source.Position_WS + Source.Direction_WS, vec3(0,1,0));


I set the camera to light, and it's rendering correctly. The shadowmap is still blank though (top-right corner). I also tried the cullfaces, but they didn't help.

SwitchMan92
12-30-2013, 01:34 PM
try this vertex shader for depth :

#version 330 core

layout(location = 0) in vec3 Position;


out vec4 pos;

uniform mat4 depthMVP;

void main()
{
gl_Position = depthMVP * vec4(Position,1);
pos = gl_Position();
}



///////////////////////////////////////////////////////////////////

and this fragment shader for depth :



#version 330 core

layout(location = 0) out float fragmentdepth;
in vec4 pos;

void main()
{
fragmentdepth = (pos.z/pos.w)*0.5+0.5;
}

Niven07
12-31-2013, 02:58 PM
I was able to fix the problem:



///1st Pass
ShadowProgram.Bind();
glBindFramebuffer(GL_FRAMEBUFFER, ShadowProgram.GetFrameBufferID());
glClear(GL_DEPTH_BUFFER_BIT); //I wasn't clearing the framebuffer's depth_buffer_bit before
glViewport(0,0,1024,1024);
StandardRendering();
glBindFramebuffer(GL_FRAMEBUFFER, NULL);
ShadowProgram.UnBind();