Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 6 of 6

Thread: Problem accessing MRT samples in deferred shading

  1. #1
    Intern Newbie
    Join Date
    Jun 2001
    Posts
    34

    Problem accessing MRT samples in deferred shading

    Hello,

    I've played around with deferred shading recently and during several optimization approaches I've tried to pack additional values like specular or ambient factors in already existing buffers.
    So I came up with the Idea of using the fourth alpha-channel in my normal buffer for that as suggested by several papers. The Problem however is that whenever I try to access the alpha channel of the normal buffer to light up some pixels, the whole scene gets partially transparent. It seems that the deferred fragment shader mixes alpha values from different buffers (normal and albedo).

    During geometry processing my fragment shader does this:
    Code :
    // albedo
    lo_fragcolor1 = texture(u_texture, gs_texcoord);
    // normal with ambient light factor attached
    lo_fragcolor2 = vec4(normalize(gs_normal) * 0.5 + 0.5, gs_ambient.r);
    During deferred shading my fragment shader does this:
    Code :
    vec4 c = texture(u_colormap, gs_texcoord);
    vec4 n = texture(u_normalmap, gs_texcoord);
    // this causes objects to be partially transparent but I'm only touching RGB!
    lo_fragcolor1 = vec4(c.rgb * n.a, 1);
    // however this causes NO transparency
    //lo_fragcolor1 = vec4(c.rgb * .3, 1);
    My FBO setup looks like this:
    Code :
    // color / albedo
      glGenTextures(1, &ids[colorbuffer]);
        glBindTexture(GL_TEXTURE_2D, ids[colorbuffer]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, dim[0], dim[1], 0, GL_RGBA,
                GL_UNSIGNED_BYTE, NULL);
        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);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                GL_TEXTURE_2D, ids[colorbuffer], 0);
      glBindTexture(GL_TEXTURE_2D, 0);
     
      // normal
      glGenTextures(1, &ids[normalbuffer]);
        glBindTexture(GL_TEXTURE_2D, ids[normalbuffer]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, dim[0], dim[1], 0, GL_RGBA,
                GL_FLOAT, NULL);
        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);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
                GL_TEXTURE_2D, ids[normalbuffer], 0);
        glBindTexture(GL_TEXTURE_2D, 0);


    Could someone point out the flaw in my thinking?

    Regards
    Saski
    Last edited by saski; 01-28-2013 at 02:58 AM.

  2. #2
    Member Regular Contributor Nowhere-01's Avatar
    Join Date
    Feb 2011
    Location
    Novosibirsk
    Posts
    251
    is your shader compiling correctly? double check it. everything goes semi-transparent or randomly colored if your shader failed to compile. and you should post full shaders with the code where you supply uniforms.

    also,
    lo_fragcolor2 = vec4(normalize(gs_normal) * 0.5 + 0.5, gs_ambient.r);
    you are using float render target. it supports negative values. so there's no need for "* 0.5 + 0.5".

  3. #3
    Intern Newbie
    Join Date
    Jun 2001
    Posts
    34
    hi,
    well I assume that the shader compiles correctly. glGetShaderiv() always returns a good status and there are no warnings whatsoever. And there is no random "jittering" in the scene. the depth issue remains constant. I also checked the shader on two different platforms (i965 and nvidia 8600) both show the same output (screenshot attached).
    Ok, I'm going ahead and post some more details here:

    complete FBO setup:
    Code :
     
        // create main framebuffer object
      glGenFramebuffers(1, &ids[framebuffer]);
      glBindFramebuffer(GL_FRAMEBUFFER, ids[framebuffer]);
     
      // create MRT textures
    // color / diffuse
      glGenTextures(1, &ids[colorbuffer]);
        glBindTexture(GL_TEXTURE_2D, ids[colorbuffer]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, dim[0], dim[1], 0, GL_RGBA,
                GL_UNSIGNED_BYTE, NULL);
        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);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                GL_TEXTURE_2D, ids[colorbuffer], 0);
      glBindTexture(GL_TEXTURE_2D, 0);
     
      // normal
      glGenTextures(1, &ids[normalbuffer]);
        glBindTexture(GL_TEXTURE_2D, ids[normalbuffer]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, dim[0], dim[1], 0, GL_RGBA,
                GL_FLOAT, NULL);
        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);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1,
                GL_TEXTURE_2D, ids[normalbuffer], 0);
        glBindTexture(GL_TEXTURE_2D, 0);
     
      // position
      glGenTextures(1, &ids[posbuffer]);
        glBindTexture(GL_TEXTURE_2D, ids[posbuffer]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB16F, dim[0], dim[1], 0, GL_RGB,
                GL_FLOAT, NULL);
        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);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2,
                GL_TEXTURE_2D, ids[posbuffer], 0);
        glBindTexture(GL_TEXTURE_2D, 0);
     
        // depth
        glGenTextures(1, &ids[depthbuffer]);
        glBindTexture(GL_TEXTURE_2D, ids[depthbuffer]);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, dim[0], dim[1], 0,
                GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
        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);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                GL_TEXTURE_2D, ids[depthbuffer], 0);
        glBindTexture(GL_TEXTURE_2D, 0);
     
       // populate textures to framebuffer (color and normals)
      GLenum buffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1,
              GL_COLOR_ATTACHMENT2};
        glDrawBuffers(3, buffers);
     
      // extra status check
      GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
      if(status!= GL_FRAMEBUFFER_COMPLETE) {
      C_Print(LOG_ERROR, "CreateMRTBuffers(): failed with [%i]!\n", status);
      }
     
      glBindFramebuffer(GL_FRAMEBUFFER, 0); // unbind fbo for now

    The shader program setup binds the output fragments and sets the texture units:

    Code :
      glBindFragDataLocation(si->pgm, 0, fcolor1_id); // color
      glBindFragDataLocation(si->pgm, 1, fcolor2_id); // normal
      glBindFragDataLocation(si->pgm, 2, fcolor3_id); // position
      glUniform1i(si->loc[colormap_loc], 0);
      glUniform1i(si->loc[normalmap_loc],1);
      glUniform1i(si->loc[depthmap_loc], 2);
      glUniform1i(si->loc[posmap_loc],   3);


    The geometry pass (quite messy right now) looks like this:

    Code :
     // enable for writing to FBO
     glBindFramebuffer(GL_DRAW_FRAMEBUFFER, ids[framebuffer]);
      // Only the geometry pass updates the depth buffer
      SubSys_Set3DMode();
      glPushAttrib(GL_VIEWPORT_BIT);
      SubSys_SetViewport(SubSys_GetVideoResolution());
      glClearColor(0,0,1,1);
      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
      glEnable(GL_DEPTH_TEST);
      glDepthRange(0.0, 1.0);
      glDisable(GL_ALPHA_TEST);
      SubSys_LookAt(eye, dir);
      SubSys_SetState(r_cull, true);
      SubSys_SetState(r_blend, true);
      SubSys_EnableShaderStage(shader_fillMRT);
      DR_Draw(dr_geometry, 0xffff);
      SubSys_DisableShaderStage();
      SubSys_SetState(r_blend, false);
      SubSys_SetState(r_cull, false);
      glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // disable writing
      glPopAttrib();

    The code to draw the FullScreenQuad and to fire up the deferred shader:

    Code :
      glMatrixMode(GL_MODELVIEW);
      glPushMatrix();
      glDisable(GL_DEPTH_TEST);
      glDisable(GL_ALPHA_TEST);
        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]);
        glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, ids[posbuffer]);
        SubSys_EnableShaderStage(shader_deferred);
        ....draw the quad...
      SubSys_DisableShaderStage();
      glActiveTexture(GL_TEXTURE3); glBindTexture(GL_TEXTURE_2D, 0);
        glActiveTexture(GL_TEXTURE2); glBindTexture(GL_TEXTURE_2D, 0);
        glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0);
        glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0);
      glEnable(GL_DEPTH_TEST);
      glPopMatrix();

    The VS/FS Shader to fill the MRT Buffers:
    Code :
    #version 130 
    precision mediump float;
     
    uniform mat4 u_pjmatrix;
    uniform mat4 u_mvmatrix;
     
    in vec4 li_vtx;
    in vec3 li_normal;
    in vec2 li_texcoord;
    in vec4 li_ambient;
     
    out vec2 gs_texcoord;
    out vec4 gs_ambient;
    out vec3 gs_normal;
    out vec3 gs_position;
     
    void main(void) {
      gs_ambient  = li_ambient;
      gs_texcoord = li_texcoord;  
      gs_normal   = vec3(u_mvmatrix * vec4(li_normal, 0.0));
      gs_position = vec3(u_mvmatrix * li_vtx);
      gl_Position = u_pjmatrix * u_mvmatrix * li_vtx;
    }

    Code :
    #version 130 
    precision mediump float;
     
    uniform sampler2D u_texture;
    in vec2 gs_texcoord;
    in vec4 gs_ambient;
    in vec3 gs_normal;
    in vec3 gs_position;
     
    out vec4 lo_fragcolor1; // diffuse
    out vec4 lo_fragcolor2; // normal
    out vec3 lo_fragcolor3; // position
     
    void main(void) {
        lo_fragcolor1 = texture(u_texture, gs_texcoord);
        lo_fragcolor2 = vec4(normalize(gs_normal), gs_ambient.r); // using alpha channel to store ambient factor
        lo_fragcolor3 = gs_position;    
    }

    And finally the deferred VS/FS code:
    Code :
    #version 130 
    precision mediump float;
     
    uniform mat4 u_mvmatrix;
    uniform vec3 u_lightpos;
     
    in vec2 li_vtx;
    in vec2 li_texcoord;
     
    out vec2 gs_texcoord;
    out vec3 gs_lightpos;
     
    void main(void) {
      gs_texcoord = li_vtx;
      gs_lightpos = vec3(u_mvmatrix * vec4(u_lightpos, 1));
      gs_viewpos  = vec3(u_mvmatrix * vec4(u_viewpos, 1));
      gl_Position = vec4(li_vtx, 0, 1) * 2.0 - 1.0;
    }

    Code :
    #version 130 
    precision mediump float;
     
    uniform sampler2D u_colormap;
    uniform sampler2D u_normalmap;
    uniform sampler2D u_depthmap;
    uniform sampler2D u_posmap;
     
    in vec2 gs_texcoord;
    in vec3 gs_fragpos;
    in vec3 gs_lightpos;
     
    out vec4 lo_fragcolor1;
     
    void main(void) {
      vec4 c = texture(u_colormap, gs_texcoord);
      vec4 n = texture(u_normalmap, gs_texcoord); // stores ambient factor in alpha channeö
      vec3 p = texture(u_posmap, gs_texcoord).xyz;
      float d = texture(u_depthmap, gs_texcoord).r; 
     
      lo_fragcolor1 = vec4(c.rgb * n.a, 1);
    }

    Any Ideas?

    Thx and Regards
    Saski
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	Screenshot - 012813 - 13:33:38.jpg 
Views:	49 
Size:	12.4 KB 
ID:	961  
    Last edited by saski; 01-28-2013 at 05:41 AM.

  4. #4
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    3,190
    Quote Originally Posted by saski View Post
    I've played around with deferred shading... came up with the Idea of using the fourth alpha-channel in my normal buffer ... whenever I try to access the alpha channel of the normal buffer to light up some pixels, the whole scene gets partially transparent.
    When rasterizing your G-buffer, ensure that not only ALPHA_TEST but BLEND and SAMPLE_ALPHA_TO_COVERAGE as well is disabled, as you're "overloading" what the pipeline would otherwise do with alpha (translucency processing).

    Then provide a debug mode where you just read the G-buffer and blast the specified channel to the screen so you can verify what's in there is correct. ...before you try to debug the lighting output.

  5. #5
    Member Regular Contributor Nowhere-01's Avatar
    Join Date
    Feb 2011
    Location
    Novosibirsk
    Posts
    251
    SubSys_SetState(r_blend, true);
    you have blending enabled. and you are writing values to alpha channel. see the problem? can you imagine, what happening? yes, your normal-map texture, generated by geometry pass is blended using that value as a factor.

    you don't really need blending for G-Buffer pass. you will handle semi-transparent objects different way. but you can still use alpha-channel for binary transparency using conditional discard;(it will work for foliage, for example, or rugged cloth.)
    Last edited by Nowhere-01; 01-28-2013 at 05:56 AM.

  6. #6
    Intern Newbie
    Join Date
    Jun 2001
    Posts
    34
    oh yeah now I see my mistake! the GL_BLEND totally slipped me.

    Thanks very guys much for the quick help!!!!

Posting Permissions

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