PDA

View Full Version : ShadowMap not rendering, FBO full white



giordi
05-24-2016, 03:34 PM
Hi guys, I have been trying to get shadow mapping working for the past couple of days and no luck, I tried pretty much every tutorial I could find on the internet, even though I am mostly following the glsl cook book and code (https://github.com/daw42/glslcookbook/blob/master/chapter07/sceneshadowmap.cpp)

I setted up the shaders and FBO and everything is rendering as before, but looks like I cannot make the shadow map to render, I keep getting a full white texture. Here is the normal result without shadows:
2269

I am using NSight to debug, if I go and check the draw calls for the shadow map I keep getting full white, aka the value set from the clear buffer.

2270

There is one thing that strikes me as odd. The function call works properly ( I am using the exact same draw calls i use for drawing the normal render, but there is no wireframe highlighted as NSight doesnt see any
poly being drawn, now I don't know if is because is a depth map or what, but I get no wireframe shown as I was expecting:

http://s33.postimg.org/5xjmwa2lb/image.jpg

To note that the depth map rendered with the normal rendering pass works as expected, I am using the same matrix as the camera matrix for the shadow so I would expect two identical shadow maps to be rendered:
http://s33.postimg.org/95o49bov3/image.jpg

Number 28 is the depthMap I am rendering in the first pass. Here is the code, I know is quite a bit of code to check but i hope you guys can help.

Initalizing the FBO:



void ShadowBuffer::init()
{
GLfloat border[] = { 1.0f, 0.0f,0.0f,0.0f };
// The depth buffer texture
glGenTextures(1, &depthTex);
glBindTexture(GL_TEXTURE_2D, depthTex);
glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH_COMPONENT24, 640, 480);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, border);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);

// Assign the depth buffer texture to texture channel 0
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, depthTex);

// Create and set up the FBO
glGenFramebuffers(1, &m_buffer_index);
glBindFramebuffer(GL_FRAMEBUFFER, m_buffer_index);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
GL_TEXTURE_2D, depthTex, 0);

GLenum drawBuffers[] = { GL_NONE };
glDrawBuffers(1, drawBuffers);

GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (result == GL_FRAMEBUFFER_COMPLETE) {
printf("Framebuffer is complete.\n");
}
else {
printf("Framebuffer is not complete.\n");
}

glBindFramebuffer(GL_FRAMEBUFFER, 0);
}



Here is the render loop for the shadow pass:


glEnable(GL_DEPTH_TEST);
glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0);
//draw shadows
m_shadow_buff.bind();
glClear( GL_DEPTH_BUFFER_BIT);
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT);

is_shadow_pass = true;
auto shadowH = ShaderManager::get_instance()->get_program("shadows");
auto* shadow_p = ShaderManager::get_instance()->get_program(shadowH);
shadow_p->use();
for (auto prog : m_resources_map)
{
//lets check on the size , if there are no objects
//no point in shader switching
if (prog.second.size() > 0)
{
//prog.first->use();
for (auto obj : prog.second)
{
//this is wrong?
obj->render(this,shadow_p );
}
}
}
glFlush();
glFinish();
glBindTexture(GL_TEXTURE_2D, 0);

m_shadow_buff.unbind()


Finally the two shaders:


#version 430
layout (location = 0) in vec3 VertexPosition;

uniform mat4 ShadowMatrix;
out vec4 ShadowCoord;
void main()
{
//converting world position in shadow map coordinates
ShadowCoord= ShadowMatrix* vec4(VertexPosition,1.0);
}


#version 430
in vec4 ShadowCoord;
layout(location = 0) out float FragColor;


void main()
{
FragColor = ShadowCoord.z;
}



Again to render I am using the same exact code and matrices, for the shadow pass I am just not binding color texture, uv and normals, just postion, but I cannot get the render map to draw properly, next I want to try to render the texture on a quad and see for myself what is in there rather than using nsight, although I trust enough that tool.

PS: here the code i use to kick the actual render for each geo:


if (renderer->is_shadow_pass)
{

auto proj = RenderingManager::get_reference().get_camera()->view_to_proj_matrix;
mat = (proj* mat);
program->set_shader_attribute("ShadowMatrix", mat);

m_vtx.bind();
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GL_FLOAT), nullptr);

m_idxs.bind();
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(m_idxs.get_size()), GL_UNSIGNED_INT, nullptr);

}



Any help or hint would be much much appreciated. I am running on latest nvidia driver and using opengl 4.5

M.