Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 2 of 2 FirstFirst 12
Results 11 to 14 of 14

Thread: Deferred shading and light volumes

  1. #11
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,126
    Quote Originally Posted by saski View Post
    Code :
    ...
        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, dim[0], dim[1], 0,
                GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);

    ...I'm confused about the GL_UNSIGNED_INT_24_8. The depth texture sampling gives us a value between 0..1 yet the format is unsigned int. So how is this supposed to work? Does the shader internally converts the unsigned int to float when sampling with texture()?
    The format and type args are just used when you provide texel data as input via the last arg. You provided NULL, so in practice they don't matter.

    Internally the DEPTH24_STENCIL8 internal format is a 32-bit fixed-point format where 24-bits are fixed-point depth (0..2^24-1) and 8-bits are fixed-point stencil (0..2^8-1). How you end up with 0..1 depth values is that 0..24^-1 is mapped to 0..1 when the pipeline operates on it.

  2. #12
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,126
    Quote Originally Posted by saski View Post
    It seems that some floor and ceiling fragments covering the part of the sphere hat reaches below the floor/ceiling failed the stencil test. This is especially strange since it depends on the viewpount. How can I fix that?
    Not sure from a glance exactly what the problem is. Make sure that the eyepoint isn't inside the light source volume (or more correctly, ensure that no part of the near clip plane clips away part of the light source volume).

    This is in practice similar to shadow volume boundary counting with stencil shadows where you need a special case for when the eyepoint is inside a shadow volume (or more correctly, the near clip plane clips away any shadow volume face.

  3. #13
    Intern Newbie
    Join Date
    Jun 2001
    Posts
    34
    Hello,

    I'm still struggeling with the light volume artifacts described in my last post. stupid question: Why is the light volume only being culled by the depth-test? This seems to be the problem with my code.
    screenshot below shows that the sphere is still completely visible even when there are objects (wall on the right side) between the sphere and the viewpoint. The lightvolume produced by the stencil test is still a 3D object, right?
    Click image for larger version. 

Name:	Screenshot - 021413 - 12:46:15.jpg 
Views:	96 
Size:	4.2 KB 
ID:	984

    So what do I have to do to enable z-culling for the light volume?

    here are the code snippets:

    Render geometry to FBO:
    Code :
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ids[framebuffer]);
        GLenum buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
        glDrawBuffers(2, buffers); // attach albedo and normal/specular buffer to FBO
      // geometry pass updates the depth buffer
      SubSys_Set3DMode();
        SubSys_SetViewport(SubSys_GetVideoResolution());
        glEnable(GL_DEPTH_TEST);
        glDepthMask(GL_TRUE); // enable depth buffer for writing
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        // set depth buffer range from 0..1
        glDepthRange(0, 1);
        // disable blending
        glDisable(GL_ALPHA_TEST);
        glDisable(GL_BLEND);
        glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
        // set camera position
      SubSys_LookAt(eye, dir);
      // enable backface culling
      glEnable(GL_CULL_FACE);
        glCullFace(GL_BACK);
      SubSys_EnableShaderStage(shader_fillMRT, false);
        DR_Draw(dr_geometry, 0xffff); // populate geometry to gbuffer
      SubSys_DisableShaderStage();
      glDisable(GL_CULL_FACE);
      glDepthMask(GL_FALSE); // make depth buffer readonly
      glDisable(GL_DEPTH_TEST);

    Render the sphere in the stencil pass:
    Code :
     SubSys_EnableShaderStage(shader_null, false);
            glDrawBuffer(GL_NONE); // detach MRTs from FBO
            glEnable(GL_DEPTH_TEST); // we definately want to use the depth buffer
            glDisable(GL_CULL_FACE); // no culling during stencil pass!
          glEnable(GL_STENCIL_TEST);
          glStencilMask(0xff);
            glClear(GL_STENCIL_BUFFER_BIT); // clear stencil buffer
            glStencilFunc(GL_ALWAYS, 0, 0); // preset buffer to all-pass
            // increment stencil if we enter/leave a polyon on its backside
            glStencilOpSeparate(GL_BACK, GL_KEEP, GL_INCR, GL_KEEP);
            // decrement stencil if we enter/leave a polyon on its frontside
            glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR, GL_KEEP);
            GLS_Sphere();
            glDisable(GL_DEPTH_TEST);
      SubSys_DisableShaderStage();

    // bind the target buffer to write stencil/color into
    Code :
     // bind new target colorbuffer
      glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ids[framebuffer]);
      glDrawBuffer(GL_COLOR_ATTACHMENT2); // attach auxiliary color buffer
      glClearColor(0,0,1,1); // set fallback color for non touched fragments
      glClear(GL_COLOR_BUFFER_BIT); // set buffer color

    And the light pass:
    Code :
     // ******************* light pass *******************
      // activate MRTs
        glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, ids[colorbuffer]);
        glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, ids[normalbuffer]);
        glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, ids[depthbuffer]);
      SubSys_EnableShaderStage(shader_deferred, true);
            glStencilFunc(GL_NOTEQUAL, 0, 0xFF); // pass all stencil values > 1
            glEnable(GL_CULL_FACE); // enable culling
            glCullFace(GL_FRONT);
            GLS_Sphere();
            glCullFace(GL_BACK);
            glDisable(GL_BLEND);
            glDisable(GL_STENCIL_TEST);    // disable stencil
      SubSys_DisableShaderStage();
      // disable MRT TMUs
      glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, 0);
        glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0);
        glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0);

    blit FBO to screen
    Code :
        glMatrixMode(GL_PROJECTION); // reset projection
        glLoadIdentity();
        glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
      glBindFramebuffer(GL_READ_FRAMEBUFFER, ids[framebuffer]);
      glReadBuffer(GL_COLOR_ATTACHMENT2);
      int16* sdim = SubSys_GetVideoResolution();
      glBlitFramebuffer(0, 0, sdim[0], sdim[1], 0, 0, sdim[0], sdim[1],
              GL_COLOR_BUFFER_BIT, GL_LINEAR);
    Last edited by saski; 02-14-2013 at 05:58 AM.

  4. #14
    Intern Newbie
    Join Date
    Jun 2001
    Posts
    34
    Never mind! Found the solution. It is always a good Idea to watch the stencil buffer ranges when incrementing/decrementing

    Doing:
    Code :
       glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR_WRAP, GL_KEEP);
       glStencilOpSeparate(GL_BACK, GL_KEEP, GL_INCR_WRAP, GL_KEEP);

    instead of:
    Code :
       glStencilOpSeparate(GL_FRONT, GL_KEEP, GL_DECR, GL_KEEP);
       glStencilOpSeparate(GL_BACK, GL_KEEP, GL_INCR, GL_KEEP);

    did the trick.

    Best regards
    Saski

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •