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 上