PDA

View Full Version : Shadow mapping problem.



Alberto García
05-10-2015, 05:32 AM
Hi all, I am trying to implement a shadow mapping in my scene, but I am having problems, the problem is that the shadow is projected in the back face of the object where the light emit shadow. And this should be in the front face, I attach an image to understand this issue better:

http://s4.postimg.org/3zshai64t/shadow.png

The steps that I follow to generate the shadow are the following:

1º I create a render buffer where I render the depth texture ( The size is the same that the viewport ).
2º I have two pass in my scene:

The first one, is a depth render from the light source, that creates the depth texture.
The second one is the render where in the shader I use the depth texture to test the shadow.

And now some of code of mi program:

Here is where i create the FBO:



void Scene:: InitShadowTexture( )
{
int m_width = 800;
int m_height = 600;

glGenFramebuffers(1, &this->m_fbo);
glGenRenderbuffers(1, &this->m_depthBufferRT);


// Bind the FBO so that the next operations will be bound to it
glBindFramebuffer(GL_FRAMEBUFFER, this->m_fbo);

// Bind the depth buffer
glBindRenderbuffer(GL_RENDERBUFFER, this->m_depthBufferRT);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, m_width, m_height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, this->m_depthBufferRT);

// Generate and bind the OGL texture for diffuse
glGenTextures(1, &this->m_depthTexture);
glBindTexture(GL_TEXTURE_2D, this->m_depthTexture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_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);

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_width, m_height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);

// Attach the texture to the FBO
glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, this->m_depthTexture, 0);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);

if ( status != GL_FRAMEBUFFER_COMPLETE )
{
cout << "Can't initialize an FBO render texture. FBO initialization failed." << endl;
}

glBindFramebuffer(GL_FRAMEBUFFER, 0);
}


Here is where I save the matrix in order to produce the shadow coords in the shader, ( the position is the light position ):


void Scene:: setTextureMatrix(void)
{
static double modelView[16];
static double projection[16];

// Moving from unit cube [-1,1] to [0,1]
const GLdouble bias[16] = {
0.5, 0.0, 0.0, 0.0,
0.0, 0.5, 0.0, 0.0,
0.0, 0.0, 0.5, 0.0,
0.5, 0.5, 0.5, 1.0};

// Grab modelview and transformation matrices
glGetDoublev(GL_MODELVIEW_MATRIX, modelView);
glGetDoublev(GL_PROJECTION_MATRIX, projection);


glActiveTexture(GL_TEXTURE4);
glMatrixMode(GL_TEXTURE);


glLoadIdentity();
glLoadMatrixd( bias );

// concatating all matrices into one.
glMultMatrixd( projection );
glMultMatrixd( modelView );

// Go back to normal matrix mode
glMatrixMode(GL_MODELVIEW);
}



Here the piece of the vertex shade where I set the shadow texture coords:



vec4 texCoord = gl_TextureMatrix[4] * gl_Vertex;
ShadowCoord = texCoord / texCoord.w;


Here the piece of the fragment shader where I test the shadow:



float lookup(float x, float y )
{
return texture( shadowMap, vec3( ShadowCoord.x, ShadowCoord.y, 0 ) + vec3(x, y, 0) ).x;
}

float shadeFactor = lookup( 0.0, 0.0 );

float shade = 1;

if ( shadeFactor < ShadowCoord.z ) shade = 0.25;

gl_FragColor = ( diffuse + spec ) * color * shade;


PD: I have skip the part of code that no affect to the shadow generation.

Thanks in advance!

Alberto García
05-10-2015, 12:15 PM
I have solved it by myself, the problem was that I didn't transform the texture matrix by the object transformation.