Search code examples
javascriptgraphicsopengl-eswebglflicker

Webgl texture interlaced flickering on dedicated GPU


I have a vertex buffer object that contains all vertices for an array of surface objects. Each object can use a different texture, up to 16 for my browser supports up to 16 only. My problem is I get interlaced flickering on most surfaces, while some others not.

Here's my fragment shader :

precision mediump float; varying vec2 texCoord; varying float texNum; uniform sampler2D texture0; uniform sampler2D texture1; uniform sampler2D texture2; uniform sampler2D texture3; uniform sampler2D texture4; uniform sampler2D texture5; uniform sampler2D texture6; uniform sampler2D texture7; uniform sampler2D texture8; uniform sampler2D texture9; uniform sampler2D texture10; uniform sampler2D texture11; uniform sampler2D texture12; uniform sampler2D texture13; uniform sampler2D texture14; uniform sampler2D texture15; void main(void){ if(texNum == 0.0){ gl_FragColor = texture2D(texture0,texCoord); }else if(texNum == 1.0){ gl_FragColor = texture2D(texture1,texCoord); }else if(texNum == 2.0){ gl_FragColor = texture2D(texture2,texCoord); }else if(texNum == 3.0){ gl_FragColor = texture2D(texture3,texCoord); }else if(texNum == 4.0){ gl_FragColor = texture2D(texture4,texCoord); }else if(texNum == 5.0){ gl_FragColor = texture2D(texture5,texCoord); }else if(texNum == 6.0){ gl_FragColor = texture2D(texture6,texCoord); }else if(texNum == 7.0){ gl_FragColor = texture2D(texture7,texCoord); }else if(texNum == 8.0){ gl_FragColor = texture2D(texture8,texCoord); }else if(texNum == 9.0){ gl_FragColor = texture2D(texture9,texCoord); }else if(texNum == 10.0){ gl_FragColor = texture2D(texture10,texCoord); }else if(texNum == 11.0){ gl_FragColor = texture2D(texture11,texCoord); }else if(texNum == 12.0){ gl_FragColor = texture2D(texture12,texCoord); }else if(texNum == 13.0){ gl_FragColor = texture2D(texture13,texCoord); }else if(texNum == 14.0){ gl_FragColor = texture2D(texture14,texCoord); }else if(texNum == 15.0){ gl_FragColor = texture2D(texture15,texCoord); } if(gl_FragColor.a < 0.1) discard; }

A picture of what is happening : enter image description here

Now, here's the deal. This works perfectly on a machine with intel hd integrated graphics; not any flickering. This only happens when I run it on my desktop with gtx 770 dedicated gpu.

Why? How?


Solution

  • I found the solution : the problem was from the float equality comparison which was resulting to false most of the time because of the float precision margin errors of my GPU.

    All I had to do was to test if the difference between my texNum and the immediate texture number was smaller than a margin of error of 0.00001 called epsilon.

    In code, I replaced all float equality comparison, for example, the first one:

    if(texNum == 0.0){
        gl_FragColor = texture2D(texture0,texCoord);
    }
    

    For this :

    if((texNum - 0.0) < 0.00001){
        gl_FragColor = texture2D(texture0,texCoord);
    }