0

ChatGPT insists that when using a framebuffer and attaching multiple draw buffers, the 0-indexed one will be the one that when you write to in the shader, it will be rendered on the canvas. However I don't find it to be the case.

Here's how I setup:

   // Create and bind framebuffer
    multiFrameBuffer = gl.createFramebuffer();
    gl.bindFramebuffer(gl.FRAMEBUFFER, multiFrameBuffer);

    // Create textures for color attachments
    const textureRender = createTexture(gl);
    const textureSmoothed = createTexture(gl);
    const textureWithChangeMarks = createTexture(gl);

    // Attach textures to framebuffer
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureRender, 0);
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, textureSmoothed, 0);
    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT2, gl.TEXTURE_2D, textureWithChangeMarks, 0);

    // Specify draw buffers
    gl.drawBuffers([
        gl.COLOR_ATTACHMENT0,
        gl.COLOR_ATTACHMENT1, 
        gl.COLOR_ATTACHMENT2
    ]);

in my fragment shader I define:

layout(location = 0) out vec4 fragColor;
layout(location = 1) out vec4 mergedColor;
layout(location = 2) out vec4 changedColor;

I write colors to all vectors, I expect that writing to fragColor will be the rendered pixels on the canvas associated with the webgl context, but nothing renders. If I readPixels from the other two - I get the buffer as expected. I haven't tried to read like that from attachment0 - but I'd like to be able to directly render to the canvas.

1 Answer 1

2

You can only do either, render to a framebuffer or render to the canvas (the default framebuffer). Afaik the default framebuffer (bound when calling gl.bindFramebuffer(gl.FRAMEBUFFER, null)) can not be configured outside the arguments given during context creation, meaning it'll always have one and only one color attachment.

If you're using webgl2 you can use blitFramebuffer to copy the contents from your READ_FRAMEBUFFER to your DRAW_FRAMEBUFFER, using the COLOR_BUFFER_BIT this will copy the contents of your first color attachment to the canvas. In WebGL1 you'd need to draw a screenspace rectangle and manually blit the texture using a simple fragment shader.

2
  • When trying the blitFramebuffer approach, I get: GL_INVALID_OPERATION: Invalid operation on multisampled framebuffer error. ChatGPT recommends creating a "intermediate" frame buffer, binding the texture, and copying from it - but I still get the error when I try it.
    – Yuval A.
    Commented Feb 28 at 16:42
  • 1
    stackoverflow.com/questions/47934444/…
    – LJᛃ
    Commented Mar 1 at 16:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.