FRAMEBUFFER INCOMPLETE ATTACHMENT 仅发生在带有 / Firefox 的 Android 上

Posted

技术标签:

【中文标题】FRAMEBUFFER INCOMPLETE ATTACHMENT 仅发生在带有 / Firefox 的 Android 上【英文标题】:FRAMEBUFFER_INCOMPLETE_ATTACHMENT only happens on Android w/ Firefox 【发布时间】:2016-03-20 01:40:37 【问题描述】:

我有一些 javascript/webgl 代码可以在我尝试过的所有浏览器上运行,除了在 android 上运行的移动版 firefox。这个问题与“framebuffer complete”有关,但我不知道具体是什么问题。

这是我能做的最小的复制品。它应该只创建一个纹理和一个帧缓冲区,设置一些属性,然后检查帧缓冲区是否“完整”:

var canvas = document.createElement('canvas');
var gl = canvas.getContext('webgl');
var GL = WebGLRenderingContext;
if (gl.getExtension('OES_texture_float') === null) 
    alert("No float support.");


var texture = gl.createTexture();
var frameBuffer = gl.createFramebuffer();
gl.bindTexture(GL.TEXTURE_2D, texture);
gl.bindFramebuffer(GL.FRAMEBUFFER, frameBuffer);

gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MAG_FILTER, GL.NEAREST);
gl.texParameteri(GL.TEXTURE_2D, GL.TEXTURE_MIN_FILTER, GL.NEAREST);
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.texImage2D(
    GL.TEXTURE_2D, //target
    0,             //level
    GL.RGBA,       //internalformat
    2,             //width
    2,             //height
    0,             //border
    GL.RGBA,       //format
    GL.FLOAT,      // type [changing to UNSIGNED_BYTE "fixes" the failure...?]
    null           // pixels
);
gl.framebufferTexture2D(
    GL.FRAMEBUFFER,
    GL.COLOR_ATTACHMENT0,
    GL.TEXTURE_2D,
    texture,
    0);

var result = gl.checkFramebufferStatus(GL.FRAMEBUFFER);
if (result === GL.FRAMEBUFFER_COMPLETE) 
    alert("success (FRAMEBUFFER_COMPLETE)");
 else 
    alert("ERROR " + (
        [0]: "Argument wasn't a frame buffer",
        [GL.INVALID_ENUM]: "INVALID_ENUM",
        [GL.FRAMEBUFFER_INCOMPLETE_ATTACHMENT]: "FRAMEBUFFER_INCOMPLETE_ATTACHMENT",
        [GL.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT]:
            "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT",
        [GL.FRAMEBUFFER_INCOMPLETE_DIMENSIONS]: "FRAMEBUFFER_INCOMPLETE_DIMENSIONS",
        [GL.FRAMEBUFFER_UNSUPPORTED]: "FRAMEBUFFER_UNSUPPORTED"
    [result] || result));

在我的测试中,此代码在 Windows+Firefox-44、Windows+Chrome-49、Android+Chrome 和 Ubuntu+Firefox 上成功。但在 Android+Firefox 上使用 FRAMEBUFFER_INCOMPLETE_ATTACHMENT 失败。

另外,我发现它似乎只影响FLOAT 纹理。如果我将类型更改为UNSIGNED_BYTE,它就会通过。

因为我一般不熟悉 opengl,很可能是我做了一些明显的疏忽(例如,没有绑定必需的属性),而移动版 firefox 是唯一没有默默修复我的错误的浏览器。

另一个可能相关的事情是必须将GL.FRAMEBUFFER 传递给gl.checkFramebufferStatus,而不是实际的frameBuffer 实例。当我通过frameBuffer 时,结果始终为0。通常0 表示成功,但the mdn docs 甚至没有列出0 作为该函数的可能返回值;他们说好的结果是FRAMEBUFFER_COMPLETE

【问题讨论】:

您需要检查gl.getExtension('OES_texture_float'); 是否返回非null 以查看是否支持该功能。 checkFramebufferStatus 没有任何重载接受帧缓冲区对象作为参数,它应该独占gl.FRAMEBUFFER 调用并检查当前绑定的帧缓冲区。您是否检查过 OES_texture_float 扩展是否真的受支持? @WacławJasper 我从重现中删除了该检查,因为它在我测试的所有浏览器(包括 firefox+android)上都返回非空值。我把支票放回去了,因为省略它会造成混乱。 Firefox 的移动版本似乎在khronos.org/registry/webgl/sdk/tests/… 的大量一致性测试中失败了。可能是浏览器的bug? OES_texture_float 扩展 does not guarantee(参见概述部分的最后一点)您可以渲染到浮点纹理。这就是为什么WEBGL_color_buffer_float应该被引入,但是它很少被实现,唯一可以确保的方法是像你已经做的那样检查帧缓冲区状态。 【参考方案1】:

如果它在其他浏览器中在完全相同的手机上运行,那么我会file a bug with Mozilla。

一般来说,将浮点纹理附加到帧缓冲区的能力并未得到普遍支持。在 OpenGL ES 2.0 中,没有任何格式可以保证工作:(

在 WebGL 中,只有 3 种格式可以保证有效。 From the spec:

以下帧缓冲区对象附件的组合,当所有附件都是帧缓冲区附件完整、非零且具有相同的宽度和高度时,必须导致帧缓冲区完整:

COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE 纹理 COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE 纹理 + DEPTH_ATTACHMENT = DEPTH_COMPONENT16 渲染缓冲区 COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE 纹理 + DEPTH_STENCIL_ATTACHMENT = DEPTH_STENCIL 渲染缓冲区

所有其他附件组合取决于 GPU/驱动程序/浏览器。

【讨论】:

如果只允许字节,人们如何进行涉及浮点数的多步 GPU 计算?他们只是在步骤之间继续手动打包和拆包吗? 它确实可以在同一部手机上的 Chrome 中运行,所以我会提交一个错误。 它们要么打包/解包,要么只在支持浮动的设备/浏览器上运行

以上是关于FRAMEBUFFER INCOMPLETE ATTACHMENT 仅发生在带有 / Firefox 的 Android 上的主要内容,如果未能解决你的问题,请参考以下文章

使用深度纹理获取 GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT [关闭]

WebGL渲染错误:GL_INVALID_FRAMEBUFFER_OPERATION: Draw framebuffer is incomplete

WebGL渲染错误:GL_INVALID_FRAMEBUFFER_OPERATION: Draw framebuffer is incomplete

为啥我使用大于 12.02 的 JAVAFX 版本会得到 GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT

FRAMEBUFFER INCOMPLETE ATTACHMENT 仅发生在带有 / Firefox 的 Android 上

Android GLES3.0 帧缓冲不完整