帧缓冲区绑定顺序

Posted

技术标签:

【中文标题】帧缓冲区绑定顺序【英文标题】:Framebuffer binding order 【发布时间】:2017-06-25 09:31:58 【问题描述】:

我正在尝试在绘图调用之外实例化我的所有帧缓冲区。但是,如果我这样做,渲染就会非常有问题。

我认为我的代码应该如何结构化

framebuffer1 = createFramebuffer()
framebuffer2 = createFramebuffer()

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

我当前的代码看起来如何

framebuffer1 = createFramebuffer()

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

这是我的真实代码:(第一个后期处理是景深,第二个是色差)

我如何实例化帧缓冲区 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,
    

我绘制所有元素的主要功能 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)

更新 1

故障:

正确:

我们可以看到、移动的对象,但在“故障”版本中它们不能。浏览器没有错误。就像帧缓冲区只有第一个绘​​图调用一样。

更新 2

你可以在这里找到源代码:https://github.com/ice-blaze/lilengine/tree/depth%2313 如果你想运行项目:

git clone npm install npm start 转到http://localhost:8080/

【问题讨论】:

glitchy”是什么意思? 您不应该在渲染循环中创建帧缓冲区。您最终将每帧创建一个新的。您是否启用深度纹理?默认情况下它们不可用。如果您的帧缓冲区附件大小与您的画布不匹配,那么您需要为这些设置视口。从您的代码中根本不清楚您要做什么。您将天空盒绘制到 bufftex1,立方体和天空盒绘制到 bufftex1,然后使用 bufftex1 将一些与深度相关的东西绘制到 bufftex2,然后使用 bufftex2 绘制到画布上。但是你在做什么?不向我们展示我们不知道的代码。 欢迎来到 Stack Overflow。如果您需要调试帮助,您必须创建一个minimum verifiable complete example 并将其放入问题本身。只发布代码链接是不可接受的。 【参考方案1】:

答案是:缺少gl.clear(...)。绑定一个新的帧缓冲区后,我想做一个clear 是一个好习惯。

【讨论】:

以上是关于帧缓冲区绑定顺序的主要内容,如果未能解决你的问题,请参考以下文章

创建没有帧缓冲区绑定的 Opengl 渲染缓冲区

OpenGL 帧缓冲绑定目标

将模板渲染缓冲区绑定到opengl中的帧缓冲区

缩放 OpenGL ES 帧缓冲区的内容

OpenGL 帧缓冲区 + LibGDX

快速交换帧缓冲区 OpenGL