Possible shader precision issue in fragment shader on Nexus 7


I’ve got a very simple animated fragment shader demonstrating the problem:

precision mediump float;
uniform mediump float time;
void main(void) {
    float time = time;
    gl_FragColor = vec4(vec3(sin(gl_FragCoord.x / mod(time, 100.0))), 1.0);

It works fine on HTC Desire S and GLSL Sandbox (glsl.heroku.com) - the animation is very fluent. On Nexus 7, however, the animation is jerky (updates around every 2 seconds). The scene is rendered at 60FPS, and other things (like geometry transformation in vertex shader) is fluent. This problem also prohibits me to use pseudo-random functions, such as:

float rand(vec2 n) {
    return 0.5 + 0.5 * 
        fract(sin(dot(n.xy, vec2(12.9898, 78.233)))* 43758.5453);

as they return 0 most of the time. What might cause the problem and how to get around it?

Using float to store time is problematic.

With fp32 it takes a while for the precision to disappear. With fp20, not so long.

It looks like you could do the “mod(time, 100.0)” calculation in vtx shader (where we have fp32) to improve the situation, or better, cpu-side (using integer time) to fix it properly.

It’s constant over the drawcall anyway. why recompute it for every single fragment?

Thank you for reply.

I was already doing modulo CPU-side, but with much larger value (10 000 * PI). I changed it to much smaller value and now it works as expected. I’m surprised that precision is lost so quickly.