专用 GPU 上的 Webgl 纹理交错闪烁

Webgl texture interlaced flickering on dedicated GPU

我有一个顶点缓冲区对象,其中包含曲面对象数组的所有顶点。每个对象可以使用不同的纹理,最多 16 个,因为我的浏览器最多只支持 16 个。我的问题是我在大多数表面上出现交错闪烁,而其他一些则没有。

这是我的片段着色器:

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; }

正在发生的事情的图片:

现在,这就是交易。这在配备 intel hd integrated graphics 的机器上完美运行;没有任何闪烁。只有当我 运行 它在我的桌面上使用 gtx 770 专用 gpu 时才会发生这种情况。

为什么?怎么样?

我找到了解决方案: 问题出在浮点相等性比较上,由于我的 GPU 的浮点精度裕度错误,大多数情况下结果为 false。

我所要做的就是测试我的 texNum 和直接纹理编号之间的差异是否小于称为 epsilon 的误差范围 0.00001。

在代码中,我替换了所有float相等比较,比如第一个:

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

为此:

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