[Warning] WebGL: INVALID_FRAMEBUFFER_OPERATION: clear: framebuffer not complete (three.js, line 19838)
[Warning] WebGL: INVALID_FRAMEBUFFER_OPERATION: drawElements: framebuffer not complete (three.js, line 16994)
This is happening in the GPGPU examples and in my own project (see jons.website/projects/reaction-diffusion), which uses the latest build, indicating that whatever problem this is spans multiple versions of Three. It seems to me that the problem is related to the use of floating-point textures, but my knowledge ends there.
The problem is that the things the shaders do in these examples (i.e. forming the waves in the water example) don't seem to take, and it will repeatedly spit out the two errors above.
I could reproduce this on an iPad (9.3.3), iPhone 6 (9.0.2), and iPhone 6s (9.3.4), using both Chrome and Safari. I do not know if this affects Android, but it seems likely.
[ ] ...
[x] All of them
[ ] Internet Explorer
[ ] All of them
Any device with iOS 8.0+, most likely
The example you posted works fine for me on Firefox/Windows.
It shows THREE.WebGLRenderer 81dev in the console and has no errors at all.
The issue is with iOS Safari and Chrome.
oops, I meant to say Chrome/Windows.... No error still.
iOS bug?
Ah, I should clarify. You need to be using an iOS device, and access the page on Chrome or Safari.
I believe it's an issue with the OES_texture_float extension. iOS seems to report this even if it can't use it, it appears. See here on SO for more details.
This may be an issue deeper than Three.js is responsible for. The issue turns out to be with WEBGL_color_buffer_float. Some devices are able to write to floating point render textures despite not explicitly supporting the WEBGL_color_buffer_float extension, including iOS devices (as of 9.3.4) and my Macbook Pro (not sure if others behave the same way, but it seems to be driver level).
My solution is to check for this extension only on mobile, in order to prevent breaking it on any desktop browsers that have the capability but don't explicitly support it.
Should this be considered closed?
Hmm, on my iPad, http://threejs.org/examples/#webgl_gpu_particle_system kind of works. It breaks after some seconds. I wonder if this has something to do with mediump/highp?
I think that one works (if briefly) because it isn't using floating point render textures. In contrast, the GPGPU examples use GPUComputationRenderer, which reads from and renders to float textures.
Most platforms properly report that they can read from float render textures using OES_texture_float. If you want to know whether you can render to a float texture, you look for WEBGL_color_buffer_float; however, to my knowledge there are very few platforms that report WEBGL_color_buffer_float, even if the hardware supports it. This behavior is what caused my confusion.
From what I'm reading, WEBGL_color_buffer_float probably isn't going to gain wider support. Instead, WebGL 2.0 is going to replace it with an extension called EXT_color_buffer_float that should (should) do the same thing but have wider support from browsers.
The core problem isn't Three's fault, but perhaps something could be done to throw an error on unsupported platforms? The technique I'm aware of for checking for float texture render support is to set up a simple scene and try to render it into a texture, which would kind of look like the following:
//Set up a scene, renderer, and camera beforehand
var renderTarget = new THREE.WebGLRenderTarget(16, 16, {
format: THREE.RGBAFormat,
type: THREE.FloatType
});
renderer.render(scene, camera, renderTarget);
var gl = renderer.context;
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status !== gl.FRAMEBUFFER_COMPLETE) {
return false;
}
return true;
Hi, (I'm the author of the GPGPU stuff)
@naso already spotted the issue and made it work on iOS by using HalfFloat precision.
So it would be easy to add your test to GPUComputationRenderer.init() and then a variable to set the render targets type to HalfFloat if the test fails.
I will look into it.
I did the changes. Please let me know if this one works in iOS:
http://yomboprime.github.io/GPGPU-threejs-demos/webgl_gpgpu_water.html
If all goes well, it should work and display this message in the console: FloatType not supported for render targets, switching to HalfFloatType.
I haven't done any in-depth testing, but it works on my iPhone and iPad. I wonder if the other demos will work the same with half-precision. Mine behaves differently, but I guess that's just something I have to work around.
Thank you for your work. Feel free to close this whenever you're satisfied!
Yes, the other demos in that repo will work (not the erosion one though). Just go to:
http://yomboprime.github.io/GPGPU-threejs-demos/
I will make a PR with the changes. I can not close this issue, I'm only a contributor ;-)
BTW, this should be tested more thoroughly by someone with a iOS device.
I don't know how it looks with the HalfFloat type, but 16 bits seems too little to me.
I'll try tomorrow.
Works fine! 馃憣
Nice!
Most helpful comment
I think that one works (if briefly) because it isn't using floating point render textures. In contrast, the GPGPU examples use GPUComputationRenderer, which reads from and renders to float textures.
Most platforms properly report that they can read from float render textures using OES_texture_float. If you want to know whether you can render to a float texture, you look for WEBGL_color_buffer_float; however, to my knowledge there are very few platforms that report WEBGL_color_buffer_float, even if the hardware supports it. This behavior is what caused my confusion.
From what I'm reading, WEBGL_color_buffer_float probably isn't going to gain wider support. Instead, WebGL 2.0 is going to replace it with an extension called EXT_color_buffer_float that should (should) do the same thing but have wider support from browsers.
The core problem isn't Three's fault, but perhaps something could be done to throw an error on unsupported platforms? The technique I'm aware of for checking for float texture render support is to set up a simple scene and try to render it into a texture, which would kind of look like the following: