Floating point render targets seems to revert to half float on Android

Hello, I have a problem with rendering depth to a floating point texture. I have created a custom material that renders the depth of a mesh (which uses special attributes, hence the custom material for depth rendering) to a frame buffer, and when I do this on PC and then use the values to calculate viewspace normals, they look as I’d expect. But when I do the same thing on Android, it looks as if the depth texture only has half float precision.
The reason I think it renders to half precision floats is that if I set it to use half float precision, it looks the same on both PC and Android.



PC with half float normal:

I’ve looked at the Android capabilities through the inspect device window in chrome, and it says:
textureFloatRender = true
highPrecisionShaderSupported = true
colorBufferFloat = true
I’ve followed the code execution all the way to the glTexImage2d call, and it uses the correct values for format and internalformat that would correspond to float texture and single component texture
On another note, why does it seem like half float textures have underflow and overflows? I can’t understand why there are weird striation artifacts when I calculate the viewspace normals

I can’t post a repo, because it’s super secret work stuff (original content DO NOT STEAL!), but I’ll try to get a playground going and post it here

Thanks for your time

Edit: Using Babylonjs > 6.0

Have you tried to compare float / half-float on Android? The artifacts don’t seem to be the same between the “Android float” and “PC half-float” pictures, so I’m not sure the problem is that Android uses half-float when you ask float…

A repro in the PG will certainly help!

Hi, thanks for your answer, I know the artifacts does not seem to be the same on Android and PC, but that’s because I took a picture from a bad angle, here is another one on PC where you can see the similarities better.

I’m not sure either that Android uses half-float, like I said the call to glTexImage2d is correct. Could it be that the texture is created correctly but that the writing to it is wrong somehow?
I’m working on the PG, I’m trying to think how to best reproduce my problem, I know that trying to figure out what the issue is is really hard without something concrete to look at, I was just hoping that maybe someone would have an immediate flash of insight.

Any idea why there is striation though? I don’t see how half float precsion would cause this, I’ve tried changing the frustum so that it’s really small so that precision should not be an issue, but there is still the weird striation thing.
I’m sure you know what method I use to recreate the normals in viewspace from the depth, but here is a link to the place I learnt it from:

You can try to raise the camera.minZ value as much as possible and see if that helps.

Yeah I already tried to reduce the frustum depth, I made a PG now though and I observed the same problem

If you change MAX_PRECISION to false, it will look the same on PC and Android (and probably on iPhone too, don’t know we don’t have a test phone at work, it would probably explode and charge you 100 dollar in California tax)


I updated the playground so that you can change the filtering (through a hack), since I noticed that my Android device does not support linear filtering, still acts as if it was a half float though

Just to be sure it’s not a problem with Babylon, I took a plain WebGL example and modified it to test if a float render target was converted to half float by the browser:

What you should see if the render target is float:

What you will see if the render target has been converted to half-float by the browser (or at least is not float):

I checked on my Samsung Galaxy, I get the black rendering, confirming the render target is not float.

Note that the render target is not even half float on my Android.

If you use this PG:

The rendering you get if the render target is half float (set true line 104 to force the render target to be half float instead of float):


But my Samsung still shows a black square.

Ok I see, I was actually also about to make a pure webgl test during the weekend but I got stuck in a horrible marsh regarding monorepos, can’t get a monorepo to reload after a shader has changed in a workspace different from the one that is the actual app (trying to look into something called turbowatch, but it’s disheartening the levels of frameworks I need to use to get something as primitive as a watch on a text fule), but I appreciate that you did one!

So my interpretation is that some vendors phones just don’t work as advertised by their capabilities reports?

Big ups for all the help!

Maybe you can try to create an issue in the Chromium repo, in case it’s a problem with Chrome on Android?


Yeah I’ll do it, I’m on a conference rn so might take some days. It’s really helpful knowing that it’s a bug with some Android implementation of WebGL (probably in Chromium, like you wrote). My boss has a very new phone and it displays the test square in your pure WebGL you made correctly.