我有一些 javascript/webgl 代码可以在我尝试过的所有浏览器上运行,但在 Android 上运行的移动版 firefox 除外。问题与“framebuffer complete”有关,但我不知 Prop 体是什么问题。
这是我能制作的最小的复制品。它应该只是创建一个纹理和一个帧缓冲区,设置一些属性,然后检查帧缓冲区是否“完整”:
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,所以很可能我犯了一些明显的疏忽(例如,没有绑定(bind)必需的属性),而移动版 firefox 是唯一没有默默修复我的错误的浏览器。
另一个可能相关的事情是必须将 GL.FRAMEBUFFER
传递给 gl.checkFramebufferStatus
,而不是实际的 frameBuffer
实例。当我传递 frameBuffer
时,结果总是 0。通常 0 表示成功,但是 the mdn docs甚至不要将 0 列为该函数的可能返回值;他们说好的结果是 FRAMEBUFFER_COMPLETE
。
最佳答案
如果它在其他浏览器中在完全相同的手机上工作,那么我会 file a bug with Mozilla .
但一般来说,将浮点纹理附加到帧缓冲区的能力并未得到普遍支持。在 OpenGL ES 2.0 中,任何格式都不能保证有效:(
在 WebGL 中,只有 3 种格式可以保证有效。 From the spec :
The following combinations of framebuffer object attachments, when all of the attachments are framebuffer attachment complete, non-zero, and have the same width and height, must result in the framebuffer being framebuffer complete:
- COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture
- COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_ATTACHMENT = DEPTH_COMPONENT16 renderbuffer
- COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE texture + DEPTH_STENCIL_ATTACHMENT = DEPTH_STENCIL renderbuffer
附件的所有其他组合取决于 GPU/驱动程序/浏览器。
关于javascript - FRAMEBUFFER INCOMPLETE ATTACHMENT 只发生在 Android 和/Firefox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36109347/