4

I'm trying to instantiate all my framebuffers outside the draw call. But if I do that, the render is very glitchy.

How I think my code should be structured

framebuffer1 = createFramebuffer()
framebuffer2 = createFramebuffer()

draw(){
    bindFramebuffer(framebuffer1)
    drawScene()
    bindFramebuffer(framebuffer2)
    drawFirstPostProcess()
    bindFramebuffer(null)
    drawSecondPostProcess()
}

How my current code is looking

framebuffer1 = createFramebuffer()

draw(){
    bindFramebuffer(framebuffer1)
    drawScene()
    framebuffer2 = createFramebuffer()
    bindFramebuffer(framebuffer2)
    drawFirstPostProcess()
    bindFramebuffer(null)
    drawSecondPostProcess()
}

And here is my real code: (the first post process is a depth of field and the second a chromatic aberration)

How I instantiate a framebuffer GitHub

export function createFramebuffer(gl, width, height) {
    // Framebuffer part
    const colorTexture = gl.createTexture()
    gl.bindTexture(gl.TEXTURE_2D, colorTexture)
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
    gl.texImage2D(
        gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE,
        null,
    )

    // Create the depth texture
    const depthTexture = gl.createTexture()
    gl.bindTexture(gl.TEXTURE_2D, depthTexture)
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
    gl.texImage2D(
        gl.TEXTURE_2D, 0, gl.DEPTH_COMPONENT, width, height, 0,
        gl.DEPTH_COMPONENT, gl.UNSIGNED_SHORT, null,
    )

    const buffer = gl.createFramebuffer()
    gl.bindFramebuffer(gl.FRAMEBUFFER, buffer)
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTexture, 0)
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.TEXTURE_2D, depthTexture, 0)

    gl.bindTexture(gl.TEXTURE_2D, null)
    gl.bindFramebuffer(gl.FRAMEBUFFER, null)

    return {
        buffer,
        colorTexture,
        depthTexture,
    }
}

My main function where I draw all the elements GitHub

const chromatic = new ChromaticAberration(gl)
const depth = new DepthField(gl)

const bufftex1 = createFramebuffer(gl, canvas.width, canvas.height)

GLB.animate = (time) => {
    window.requestAnimationFrame(GLB.animate)

    gl.enable(gl.DEPTH_TEST)

    gl.viewport(0.0, 0.0, canvas.width, canvas.height)

    gl.bindFramebuffer(gl.FRAMEBUFFER, bufftex1.buffer)

    gl.clear(gl.COLOR_BUFFER_BIT + gl.DEPTH_BUFFER_BIT)

    drawCubes()
    skybox.draw()

    const bufftex2 = createFramebuffer(gl, canvas.width, canvas.height)
    gl.bindFramebuffer(gl.FRAMEBUFFER, bufftex2.buffer)

    depth.draw(
        canvas.width, canvas.height, bufftex1.colorTexture, bufftex1.depthTexture,
        document,
    )

    gl.bindFramebuffer(gl.FRAMEBUFFER, null)
    gl.disable(gl.DEPTH_TEST)

    chromatic.draw(time, canvas.width, canvas.height, bufftex2.colorTexture, document)
}

Update 1

Glitchy:

glitch

Correct:

correct

The object we can see, move, but in the "glitchy" version they don't. There is no error in the browser. It's like if the framebuffer had only the first draw call.

Update 2

You can find the source code here: https://github.com/ice-blaze/lilengine/tree/depth%2313 If you want to run the project:

  • git clone
  • npm install
  • npm start
  • go to http://localhost:8080/
Ice-Blaze
  • 897
  • 8
  • 18
  • 1
    what does "*glitchy*" mean? – LJᛃ Jun 25 '17 at 11:51
  • 2
    You shouldn't be creating your framebuffer in your render loop. You'll end up creating a new one every frame. Are you enabling depth textures? They aren't available by default. If your framebuffer attachment sizes don't match your canvas then you need to set the viewport for those. It's not clear at all from your code what you're trying to do. You draw a skybox to bufftex1, cubes and a sky box to bufftex1, then some thing related to depth to bufftex2, using bufftex1, then you draw to the canvas using bufftex2. But what are you doing? Without showing us the code we have no idea. – gman Jun 25 '17 at 12:47
  • 1
    Welcome to Stack Overflow. If you want debugging help you must create a a [minimum verifiable complete example](https://meta.stackoverflow.com/questions/349789/how-do-i-create-a-minimal-complete-verifiable-example) and put it **in the question itself**. Just posting a link to your code is unacceptable. – gman Jun 25 '17 at 13:12

1 Answers1

3

The answer was: a missing gl.clear(...). After binding a new framebuffer I guess it is a good habit to do a clear.

Ice-Blaze
  • 897
  • 8
  • 18