[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Public WebGL] The miserable state of affairs of floating point support





On Thu, Mar 23, 2017 at 6:08 PM, Florian Bösch <pyalot@gmail.com> wrote:
On Thu, Mar 23, 2017 at 2:19 AM, Kenneth Russell <kbr@google.com> wrote:
On 22 March 2017 at 17:12, Florian Bösch <pyalot@gmail.com> wrote:
Having looked supporting different formats for rendering to and sampling from, I'd like to share my observations.

Extensions are claimed that are not supported

On iOS the implementation claims to support OES_texture_float_linear but this does not actually work and it defaults (silently) to nearest.


Could you please submit a conformance test verifying this behavior?

The conformance test to verify float linear already exists, and it fails pretty much every suite contained in it, including the non linear filtering behavior I described. https://www.khronos.org/registry/webgl/sdk/tests/conformance/extensions/oes-texture-float-linear.html?webglVersion=1&quiet=0
 
Float16Array still does not exist

It's still a major pain to deal with generating data to upload to Half-Float textures because despite repeated prodding on the ECMA-ML as well as here, we still don't have a Float16Array.

Can't help with this. Sorry.

Why not?

That's a _javascript_ issue, not a WebGL issue. This is the WebGL forum. If you want Float16Array you'd need to go petition the _javascript_ guys (I see that you have) 

Yes, TypedArrays started here but they were correctly passed off to JS. I doubt they'll see any traction though for pretty much the same reason nothing like that exists in any other language I know of. it's a niche feature. You can have a C/C++ array of float, short, unsigned short, int, unsigned int etc but there's no half AFAIK

 
 

Some implementations do not accept Uint16Array upload to half-float textures

Safari and iOS refuse to accept an array for texImage2D to upload to half-float textures. Even though it's now in the specification that this is permissible. We talked about this. It was agreed we would allow that.

I confirm that Safari on macOS is failing https://www.khronos.org/registry/webgl/sdk/tests/conformance/extensions/oes-texture-half-float.html . Please confirm that it's failing on iOS and file a bug on bugs.webkit.org.



Setting linear blending mode on textures that don't support it generates no error

The UA complains about an unrenderable texture when you draw sampling from it, so it knows that the blending mode isn't supported. But you can't get an error from it either at texParameter or draw*. This is extremely awkward, because apparently (see above) the linear extensions have no meaning whatsoever, so you have to actually draw to figure out if blending works and then readback the results. If you (the UA) already knows that linear doesn't work, please don't make developers integrate a unit test to figure it out?

Please file an issue about this on https://github.com/KhronosGroup/WebGL . The browser vendors can discuss making this change.


You can't generate errors at texParam time. That's the spec. It's perfectly valid to have intermediate steps where textures are in an invalid state on the road to making them valid. A very common example

      1) gl.texImage2D(..., npot)   // texture invalid as default min filtering is incompatible with npot textures
      2) gl.texParameteri(..., gl.TEXTURE_MIN_FILTER, gl.LINEAR);  // now it's safe

If you follow the road of generating errors then that very common code would fail at step 1 and you'd have to reverse the order. (which would maybe be great but would break tons of content)

You also can't at draw time as plenty of apps work and shipped even though some of their textures may not be renderable. Suddenly generating errors where there were none before would break content.

A simple example might be

    var tex = gl.createTexture();
    var img = new Image();
    img. {
       gl.bindTexture(...);
       gl.texImage2D(...);
       ...
    }

    startRenderLoop()

Until the texture loads you won't see the texture, there will be warning in the JS console but otherwise the app will work just fine 

 
 
The color_buffer extensions have no meaning

Platforms (such as Chrome) that support drawing to floating point textures do not expose these extensions, leaving you no choice but to getExtension it and then promptly ignore anything you got and test if you can actually construct an FBO that is indicated as valid and draw to it and then read the drawn texture (trough another FBO because see blow).

This behavior is much clarified and simpler in WebGL 2.0. There's only one extension: EXT_color_buffer_float, and it provides a strong guarantee about renderability without adding a lot of feature detection code to the WebGL implementation itself and impacting startup time of all WebGL apps. Please try WebGL 2.0. If you see issues in this area in that version then please file bugs.

The fix for this issue exists, it's color_buffer float extensions. I've filed bugs for you to implement it. You want me to file again?

this is never going to be fixed for WebGL1 as it would break too much content. The whole issue was WebGL shipped for > year with OES_texture_float and the ability to use them as a framebuffer attachments before Mark Callow pointed out that was wrong and that we needed EXT_color_float_buffer. So it was added but the original method (make floating point texture, attach, check for FRAMEBUFFER_COMPLETE) was left.

It's fixed in WebGL2 because that will not break any content but it can't be fixed in WebGL1 without breaking sites.
  

readPixels of floats may or may not work

Some platforms do not implement readPixels from a floating point texture. Some do. Because of that, you can't directly test some of the more interesting properties of floating point textures (such as blending, filtering, clamping, etc.) but you have to do it trough a proxy unsigned byte FBO because you can't rely on readPixels.

This should again be much clarified in WebGL 2.0 and there should be strong guarantees about readPixels' behavior there.

The specification of color-buffer-float clearly specifies that area, it states that: "The format and type combination RGBA and FLOAT becomes valid for reading from a floating-point rendering buffer."

Agreed: Add a conformance test?
 

Some devices do not expose floating point textures even though they support them

For reasons that completely boggle me, the fairly new Samsung S7 (just a year old) which has perfectly fine and working support for a variety of floating point textures/operations do not expose that to WebGL (by some combination of unlucky ES config and whatnot). That's a fairly big problem. Because samsung devices are fairly popular, it means floating point support on mobiles is actually retrograde, mean reverting slowly back to somewhere anno 2012 or so.

We just tested Chrome Dev on a Samsung Galaxy S7 Edge and it passes the render-to-RGBA-texture portion of https://www.khronos.org/registry/webgl/sdk/tests/conformance/extensions/oes-texture-float.html . (RGB textures are not renderable.) It also seems to support EXT_color_buffer_float for WebGL 2.0. If you have a scenario on a newer device like this where render-to-FP-texture is not working at all then please file a bug.

If you're trying to save memory, then rendering to R32F and RG32F textures is available as of WebGL 2.0.

They are not available in WebGL 1, and that is the problem. I'll elaborate on this just below. But to note, my Nexus 4 supported floating point textures, but my Galaxy S7 doesn't, and that is a problem because....

The only qualifier I can find for the situation is miserable and utterly broken. It's hurting WebGL. It should be addressed. It should have been addressed long ago, and most of these things came up in the past years at one point or another. I don't understand why they are not addressed.

WebGL 2.0 should solve many longstanding issues with rendering to floating-point textures. It's supported in Firefox on Android now and will be in Chrome 58 on Android. Please help us make sure that these issues are addressed in the most recent version, and we can work on backporting some of the fixes to WebGL 1.0 + extensions.
  • WebGL 1.0 enjoys 96% overall support with 7% major performance caveat ==> 89% usable WebGL 2.0
  • WebGL 2.0 is at 44% support with 6.5% major performance caveat ==> 41% usable WebGL 2.0 (I predicted this)
  • WebGL 2.0 has reached a plateau at its current support level that persisted for the last 1-2 months, it's no longer quickly gaining much support (I predicted this too)
I hate sounding like a broken record. WebGL 2.0 is not a substitute for a well functioning WebGL 1.0 for a long time. To the ears of a webapp dev that's like "We don't fix this because there's a new shiny thing, which you can't use more than half of the time, and that's how it's gonna be for years." It's not good. It's anything but good.