Sorry, but I always use highp. I hate low and medium precision.
I can guess that the problem may be in the sampler mapping via glGetUniformLocation(). Or there might be a GLES2 legacy hiding somewhere, which prevents float samplers from being set correctly. This, by the way, may be indicated by the crash of the build when trying to use float formats other than R32F.
As long as I don’t have guaranteed float render-targets, I make shadows using RGBA texture to record depth.
And here I’ve encountered a strange bug that shows up consistently on all iPhones and iPads (I’ve tested devices from iPhone7 to 12 Pro and several iPads):
It looks as if the RGBA channels are less than 8 bits.
I wasn’t able to find the cause, but I was able to artificially reproduce this error on Android by lowering the storage accuracy of the four RGBA channels, but still leaving the same entire unpacking formula from RGBA to float (i use this formula: Encoding floats to RGBA - the final? · Aras' website)
I solved this problem by turning off linear texture filtering (yes, there it is again!).
It’s a pity, I wanted to have smoothed shadows, but while filtering on androids is accurate enough, on iPhones it’s not.
Nevertheless, I will prepare and send a project with this error later, perhaps you will be interested to see it.
We are discussing support for adding extensions in some way, so hopefully you can get that in some near ish future you can do the sampling yourself aswell but it’s a bit expensive for low end I’m afraid
Due to the advent of float RT, I have converted my shadows to R32F format. And discovered the unpleasant thing - for some old (and not so old) smartphones the R16F format is somehow used instead of the R32F format.
If I use RGBA32 and convert the shadow depth to 4 components (R,G,B,A) then everything works correctly on all smartphones and PCs.
While this is a good solution, it is saddening to have to do a dot() for each texture read and normalize the shadow depth to a range of 0…1.
But the unpredictable switching in 16F is a nuisance. Is there anything you can do about it?
Not sure, it’s a pretty classic problem with OpenGL and old devices. But maybe we could expose values from this function glGetShaderPrecisionFormat so you can do the workaround necessary. Alternatively I guess you could split the value over two R16 channels. But usually 16F should be enough for shadows I would think, but I guess it depends on your needs..
Yeah, I jumped to conclusions a bit.
Indeed, the 16 bit format should be enough.
Indeed, when I tweaked the bias, everything was almost fine.
Moreover, even the position recovery from depth was not affected (well, or it’s imperceptible to the eye).
SSAO didn’t feel the drop in accuracy from 32 to 16 bit at all, apparently it doesn’t care about such subtleties.
What the hell! When using the R16F directly, the smartphone crashes with error GL 1282. Classic!
So I am forced to always specify R32F, expecting to sometimes get R16F. It’s all right, we’ll get over it somehow.
Hmm on more than one device? You might be facing some strange driver edge case.. old android is a minefield of issues like this unfortunately. But if it’s an es3 device you should be able to request 16F, I’ll do some investigation this week but you might want to use the 32F solution for now if it works..
For people reading this now or in the future, do NOT use anything other than point filtering for depth targets if you are testing for differences in depth yourself. I believe that some graphics APIs have a sampler type for shadow mapping that allows for getting some basic PCF running with linear filtering, but I do not believe Defold allows you to access that currently. The reason you do not want to use linear filtering on depth targets is it gives you incorrect depth values (remember this is depth information, not color information) You are basically blurring the depth buffer, which when testing against fragment depth you will get artifacts. It only gets worse when you are using some form of encoding on your depth buffer.
If you want smooth shadows, there are other solutions. One simple solution is PCF, which acts as a form of antialiasing (or really a blur). Combine that with linear filtering in the shader (after you have tested your depth values) and you get decent shadows.