I pass Unix time to my shader from Java code:
gl.uniform1f(shader, System.currentTimeMillis());
The shader looks like (simple form, just to investigate the problem):
#ifdef GLES
precision highp float;
#endif
uniform float u_time;
void main() {
int d = 1000;
float result = floor(u_time / d) * d;
if (result > u_time) {
s = 1.0;
} else {
s = 0.5;
}
gl_FragColor = vec4(s, 0, 0, 1.0);
}
I expect that result
will never be greater than u_time
. Surprisingly it IS (shader produces bright red color).
Moreover, if replace value of d
with 100, for example, it works as expected - renders dark red.
Tried to replace d
with float
value of 100.0, but without any effect.
It works even if I replace u_time
in expression with direct float constant, for example 1563854457241.0 - it is about the same, that Java puts to shader.
What may be the problem? I suspect it relates to precision, but do not undertand how to fix it.
P.S. After all, I got TRUE (bright red color) if replace condition expression with
1000000123.0 * 1000 == 1000000123456.0
Nuf said.
In your shader code you've exceeded the precision limit of a 32 bit floating point number.
See IEEE 754 and GLSL ES -Precision and Precision Qualifiers.
When you use the precision qualifier highp
, then the number of significant bit is 23 (+1 for the sign), so a number like 1000000123456.0
can not be represented with the full precision, because the approximated number of decimal digits is 7.22.