I'm trying to get rendering to a floating point texture working in WebGL on iOS Safari (not in a native app). I have managed to get iOS to read a manually (e.g. from JavaScript) created floating point texture, however when I create a framebuffer of floating point type and use the GPU to render into it, it does not work.
I've isolated the issue to code that renders to a floating point texture, which is then passed to another shader to be displayed. Here is what the result looks like applied to a cube:
The render to texture draws a green square, half the size of the texture, which is then applied to each side of the cube.
This all works perfectly fine on both desktop and iOS WebGL as long as the type of the texture that the green square is rendered to is the standard unsigned byte type. However, changing the type to floating point causes the render to texture to fail on iOS devices (while continuing to work on desktop browsers). The texture is empty, as if nothing had been rendered to it.
I have created an example project here to demonstrate the issue: https://github.com/felixpalmer/render-2-texture
Changing the precision of the shaders using the THREE.Renderer.precision
setting does not make a difference
As far as I know no iOS device supports rendering to a floating point texture (nor do most mobile devices at this point in time 3/2015)
My understanding of the WebGL spec is
OES_texture_float
: Allows you to create and read from 32bit float textures but rendering to a floating point is device dependent.OES_texture_float_linear
: Allows linear filter floating point textures. If this doesn't exist andOES_texture_float
does then you can only usegl.NEAREST
for floating point textures.OES_texture_half_float
andOES_texture_half_float_linear
are the same as above except for half float textures.The traditional way to see if you can render to a floating point texture in WebGL, assuming
OES_texture_float
exists, is to create a framebuffer, attach a floating point texture to it, then callgl.checkFramebufferStatus
. If it returnsgl.FRAMEBUFFER_COMPLETE
then you can, if not then you can't. Note: This method should work regardless of the next paragraph.The spec was updated so you could also check WebGL extensions to find out if it's possible to render to a floating point texture. The extension
WEBGL_color_buffer_float
is supposed to tell you you can render to floating point textures. The extensionEXT_color_buffer_half_float
is the same for half float textures. I know of no browser that actually shows these extensions though yet they support floating point rendering if the hardware supports it.For example my 2012 Retina MBP on Chrome 41 reports
Firefox 36 reports
The browser vendors are busy implementing WebGL 2.0 and given the
gl.checkFramebufferStatus
method works there's no pressure to spend time making the other extension strings appear.Apparently some iOS devices support
EXT_color_buffer_half_float
so you could try creating a half float texture, attach it to a framebuffer and check its status then see if that works.Here's a sample to check support. Running it on my iPadAir2 and my iPhone5s I get
which is exactly what we expected.