- Home /
Very bad float precision
Hi, I have a water shader which worked correctly on all devices, but after a Unity update apparently, it is not working correctly anymore on low-budget devices. I see a small water circle around the camera which is drawing correctly, but everything else is wrong. After some debugging, I came up with this simple shader which has the same problem:
Shader "test"
{
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct v2f
{
float4 pos : SV_POSITION;
float4 wpos : TEXCOORD0;
};
v2f vert(appdata_base v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.wpos = mul(unity_ObjectToWorld, v.vertex);
return o;
}
float4 frag(v2f i) : COLOR
{
float3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.wpos.xyz);
return float4(viewDir, 1.0f);
}
ENDCG
}
}
FallBack "Diffuse"
}
What I see on PC and Middle/High-end devices with this shader: https://ibb.co/8KYyK0j . And what I see with the same shader on low-end devices: https://ibb.co/cgQZrRS
It seems like there is some big problems with precision.
I tested a lot of workarounds but nothing working. I am clueless now. May be somebody have a clue? My Unity version 2018.4.2 Test device: Galaxy J1 mini
I would say it again to be clear for sure - it worked perfectly before, on the same device, the same shader, nothing changed but Unity version.
Thank you!
$$anonymous$$y thinking was that there may have been some form of auto-precision handling on the macros now, but going through the built-in includes that doesn't seem to be the case. Which in turn leads me to think it's the normalization; have you tried doing it manually? i.e.
float3 viewDir = _WorldSpaceCameraPos.xyz - i.wpos.xyz;
viewDir = viewDir / length (viewDir);
What is interesting to me is the weird circular value clipping. That makes me think that somehow you're getting a NaN (again, possibly from the normalization). I'm interested to figure out what would be causing this too, although I can't test on said hardware myself.
Of course I tried to normalize it manually and the same thing happens. I even tried to calculate manually the length of the vector and also didn't help.
Again, just throwing suggestions around, have you tried compiling for a specific target? From memory, default is OpenGL ES 2.0, which could be messing with precision.
I tried for ES 2 - didn't work. Then I tried for ES 3 - didn't work :)