5

我想将我的延迟渲染器和前向渲染器组合在一起。为了共享相同的深度缓冲区,我使用带有 4 个颜色附件的单个帧缓冲区对象,COLOR_ATTACHMENT0-2 用于 G 缓冲区渲染,COLOR_ATTACHMENT3 用于延迟着色和前向渲染,这是伪代码:

//**Gbufffer part**
Bind G-Buffer FBO
gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2]);
draw the G buffer

//**Lighting part**
Bind Lighting buffer FBO

//**Shading part**
Bind G-Buffer FBO
gl.drawBuffers([gl.COLOR_ATTACHMENT3]);

//**Forward rendring part**
//Still use the G-Buffer FBO and COLOR_ATTACHMENT3
draw forward material

使用它时,我在 Firefox 中遇到了一个错误:

错误:WebGL:drawBuffers:buffers[i]必须为 NONE 或 COLOR_ATTACHMENTi。

在 Chrome 中启动时,我得到了这个:

FrameBufferObject.ts:151 WebGL:INVALID_OPERATION:drawBuffers:COLOR_ATTACHMENTi_EXT 或 NONE

我的代码有什么问题?这真的让我很困惑...... THX。

4

2 回答 2

7

如果我没记错的话,你必须为第一个缓冲区使用颜色附件 0,第二个缓冲区使用颜色附件 1,第三个缓冲区使用颜色附件 2,依此类推。

换句话说,这没关系

gl.drawBuffers([
  gl.COLOR_ATTACHMENT0,  // color attachment 0 to draw buffer 0
  gl.COLOR_ATTACHMENT1,  // color attachment 1 to draw buffer 1
  gl.COLOR_ATTACHMENT2,  // color attachment 2 to draw buffer 2
]);

这也可以

gl.drawBuffers([
  gl.COLOR_ATTACHMENT0,  // color attachment 0 to draw buffer 0
  gl.NONE,               // NONE to draw buffer 1
  gl.COLOR_ATTACHMENT2,  // color attachment 2 to draw buffer 2
]);

这不是!!

gl.drawBuffers([
  gl.COLOR_ATTACHMENT0,  // color attachment 0 to draw buffer 0
  gl.COLOR_ATTACHMENT2,  // color attachment 2 to draw buffer 1 ERROR!
  gl.COLOR_ATTACHMENT1,  // color attachment 1 to draw buffer 2 ERROR!
]);

所以在你的情况下。

gl.drawBuffers([
   gl.COLOR_ATTACHMENT3,  // color attachment 3 to draw buffer 0 ERROR!
]);

必须始终匹配 0 到 0、1 到 1、2 到 2 等。

如果这真的是你正在做的事情,你应该制作 3 个帧缓冲区对象。一个包含前 3 个缓冲区,一个包含第 4 个缓冲区,一个包含所有 4 个缓冲区。然后你会做类似的事情

gl.bindFramebuffer(gl.FRAMEBUFFER, threeAttachmentFB);
gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1, gl.COLOR_ATTACHMENT2]);

.. draw stuff ..

gl.bindFramebuffer(gl.FRAMEBUFFER, oneAttachmentFB);
gl.drawBuffers([gl.COLOR_ATTACHMENT0]);

.. draw stuff ..

gl.bindFramebuffer(gl.FRAMEBUFFER, fourAttachmentFB);
gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1,
                gl.COLOR_ATTACHMENT2, gl.COLOR_ATTACHMENT3]);

.. draw stuff ..

在此版本中,不保证各种组合都能正常工作。目前尚不清楚 WebGL2 中的限制是什么,但在 WebGL1 中,只有这些组合才能保证有效

  • 一种颜色附件(有或没有深度或深度模板)

    COLOR_ATTACHMENT0_WEBGL = RGBA/UNSIGNED_BYTE
    
  • 两种颜色附件(带或不带深度或深度模板)

    COLOR_ATTACHMENT0_WEBGL = RGBA/UNSIGNED_BYTE
    COLOR_ATTACHMENT1_WEBGL = RGBA/UNSIGNED_BYTE
    
  • 三色附件(带或不带depth或depth_stencil)

    COLOR_ATTACHMENT0_WEBGL = RGBA/UNSIGNED_BYTE
    COLOR_ATTACHMENT1_WEBGL = RGBA/UNSIGNED_BYTE
    COLOR_ATTACHMENT2_WEBGL = RGBA/UNSIGNED_BYTE
    
  • 四种颜色附件(有或没有深度或深度模板)

    COLOR_ATTACHMENT0_WEBGL = RGBA/UNSIGNED_BYTE
    COLOR_ATTACHMENT1_WEBGL = RGBA/UNSIGNED_BYTE
    COLOR_ATTACHMENT2_WEBGL = RGBA/UNSIGNED_BYTE
    COLOR_ATTACHMENT3_WEBGL = RGBA/UNSIGNED_BYTE
    

根据 GPU/驱动程序/浏览器/操作系统,所有其他组合可能会或可能不会起作用

于 2016-05-23T21:38:54.000 回答
1

如果您的实际代码与您在此处发布的代码略有不同,我不会感到惊讶。

https://dxr.mozilla.org/mozilla-central/source/dom/canvas/WebGLContextFramebufferOperations.cpp查看WebGLContext::DrawBuffers的 Firefox 源代码:

for (size_t i = 0; i < buffers.Length(); i++) {
    // "If the GL is bound to a draw framebuffer object, the `i`th buffer listed in
    //  bufs must be COLOR_ATTACHMENTi or NONE. Specifying a buffer out of order,
    //  BACK, or COLOR_ATTACHMENTm where `m` is greater than or equal to the value of
    // MAX_COLOR_ATTACHMENTS, will generate the error INVALID_OPERATION.

    // WEBGL_draw_buffers:
    // "The value of the MAX_COLOR_ATTACHMENTS_WEBGL parameter must be greater than or
    //  equal to that of the MAX_DRAW_BUFFERS_WEBGL parameter."
    // This means that if buffers.Length() isn't larger than MaxDrawBuffers, it won't
    // be larger than MaxColorAttachments.
    if (buffers[i] != LOCAL_GL_NONE &&
        buffers[i] != LOCAL_GL_COLOR_ATTACHMENT0 + i)
    {
        ErrorInvalidOperation("%s: `buffers[i]` must be NONE or COLOR_ATTACHMENTi.",
                              funcName);
        return;
    }
}

您的代码未通过该检查。也许你把顺序搞混了?

[编辑]正如 gman 指出的那样,您对 drawbuffers 的第二次调用gl.drawBuffers([gl.COLOR_ATTACHMENT3]);不符合此验证[/编辑]

于 2016-05-23T18:44:59.500 回答