Saturday, 30 July 2011

Using FrameBufferObjects in shaders

Using FrameBufferObjects in shaders would go something like this:
  • Set up your FBO (see here)
  • Render scene while writing values to gl_FragColor and gl_FragDepth (in our case). You could also have more draw buffers, then you could also write to gl_FragData[0-9].
    Keep in mind, that values will be clamped to [0,1] unless you use glClampColor to turn that behaviour off. e.g.
    glClampColor(GL_CLAMP_FRAGMENT_COLOR, GL_FALSE);
    glClampColor(GL_CLAMP_VERTEX_COLOR, GL_FALSE);
    glClampColor(GL_CLAMP_READ_COLOR, GL_FALSE);
  • Use FBO texture(s) as shader input:
    //set up textures for postprocessing, color int unit 0, depth in 1
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, fboInfo.color);
    glActiveTexture(GL_TEXTURE1);
    glBindTexture(GL_TEXTURE_2D, fboInfo.depth);
    //sample depth like regular texture and values are in all channels (x,x,x,x)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
    glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
    //use compiled post-processing shader
    glUseProgram(postProcHandle);
    //set up texture unit uniforms / texture samplers
    glUniform1i(glGetUniformLocation(postProcHandle, "color"), 0);
    glUniform1i(glGetUniformLocation(postProcHandle, "depth"), 1);
    This is the post-processing shader code (If you don't see anything you might need to linearize your depth-values):
    uniform sampler2D color;
    uniform sampler2D depth;
    void main() {
        float c = texture2D(depth, gl_FragCoord.xy / vec2(SCREEN_WIDTH, SCREEN_HEIGHT)).a;
        gl_FragColor = vec4(c, c, c, 1.);
    }
  • Render a full-screen quad using you shader.
    glRectf(-1,-1,1,1);

No comments:

Post a Comment