• Advertisement
Sign in to follow this  

Help with Stencil Test and Deferred Shading [SOLVED]

This topic is 1449 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm having real trouble getting my stencil test to work correctly with a basic deferred shading implementation. I'm aware there are other options, but I really need to get the stencil test working because I plan to try and use stencil volume shadows. I've done pretty much this exact implementation before, and it worked fine, so I'm really at a loss for what the problem is.
 
In any case, the real problem is that the stencil test doesn't seem to properly take account of the first pass depth buffer, even though depth test is on during the stencil pass. In addition, the stencil test seems corrupted when it's behind the geometry. Three screenshots below and then stencil and depth buffer grab.
 
[attachment=19744:stencil test ex 1.png]
In this first image, the light volume that I'm rendering to the stencil buffer and then again in the light pass is behind terrain geometry. So why is it visible? 
 
[attachment=19745:stencil test ex 2.png]
This second image looks alright from the other side, although you can see underneath the geometry a bit again.

 

[attachment=19746:stencil test ex 3.png]

The third image shows the output of the stencil past, so clearly the geometry is ok. 

 

[attachment=19747:FrameStencil_0021_0099_Pre.png] [attachment=19748:FrameDepth_0021_0099_Pre.png]
Sorry they're so small. It's too slow to capture with any larger framebuffer size.

 

Here's the rendering code:

// geometry pass
m_gbuffer->bindWrite();    // binds fbo
m_gbuffer->setDrawBuffers(0, m_num_drawbuffers); // glDrawBuffers(num_buffers, buffers)

glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

glEnable(GL_CULL_FACE);

updateCameraInformation(m_camera_information);

world->geometryRender(m_camera_information);

glDepthMask(GL_FALSE);


// light pass
glDrawBuffer(GL_COLOR_ATTACHMENT0 + m_num_drawbuffers);   // same fbo, so same depth buffer, but different texture for light pass
m_gbuffer->bindToTextures();    // bind fbo textures for shaders

glEnable(GL_STENCIL_TEST);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

// stencil pass
        glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);

	glEnable(GL_DEPTH_TEST);
	glDisable(GL_CULL_FACE);

	glStencilFunc(GL_ALWAYS, 0, 0);
	glStencilOpSeparate(GL_BACK, GL_KEEP, GL_INCR, GL_KEEP);
	glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR, GL_KEEP);

	m_point_light.render();

	glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);

// light pass
        glStencilFunc(GL_NOTEQUAL, 0, 0xFF);

	glDisable(GL_DEPTH_TEST);
	
	glEnable(GL_BLEND);
	glBlendEquation(GL_FUNC_ADD);
	glBlendFunc(GL_ONE, GL_ONE);

	glEnable(GL_CULL_FACE);
	glCullFace(GL_FRONT);

	m_point_light.render();

	glCullFace(GL_BACK);

glDisable(GL_STENCIL_TEST);
glDisable(GL_CULL_FACE);

m_ambient_light.render();

glDisable(GL_BLEND);

Thanks for your time. I appreciate any suggestions.

 

 

EDIT:

 

I swear, posting on these forums just makes me think differently and I solve it easily. The glStencilOpSeparate needs to be set to GL_INCR_WRAP or GL_DECR_WRAP respectively. The WRAP portion means that decrementing at 0 will wrap the buffer to 255, and incrementing at 255 will wrap the buffer to 0. Very useful, yet my previous code that worked did not use WRAP. It must be somewhat platform dependent. Hope this can help someone.

glStencilOpSeparate(GL_BACK, GL_KEEP, GL_INCR_WRAP, GL_KEEP);
glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR_WRAP, GL_KEEP);

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement