首页 > 解决方案 > GLSL 问题:坐标偏移和后退在不同的机器上产生不同的结果

问题描述

我有一个 GLSL 片段着色器源,它在我们的一半机器上产生正确的结果,而在另一半机器上产生不正确(但一致)的结果。

我基本上有两个要添加的矩阵或数组。数据映射到大小为 7x9 的 2D 纹理。两个输入的大小相同,均为 60 个 float32。我的代码找到的最接近的纹理大小是 7x9。

以下脚本在所有机器上产生正确的结果。TexCoords 是我的变化:

    glFragColor = texture2D(A, TexCoords) + texture2D(B, TexCoords);

但是,以下(简化)版本没有。这表明我将坐标映射到偏移量和返回的逻辑不正确,或者这里有更神秘的东西在起作用:

    const float xScale = 7.0; // x size of the texture
    const float yScale = 9.0; // y size of the texture
    float s = TexCoords.s * xScale; // denormalize x
    float t = TexCoords.t * yScale; // denormalize y
    int offset = int(t) * 7 + int(s); // flattened offset from 0

    s = mod(float(offset), 7.0); // recalc x from offset
    t = floor(float(offset) / 7.0); // recalc y from offset

    vec2 coords = vec2(s / xScale, t / yScale); // normalize
    glFragColor = (texture2D(A, coords) + texture2D(B, coords);

正确结果示例(截断)

EXPECTED: type=float32; dims=[3,4,5]; data=[1.0915919542312622,0.04060405492782593,0.16559171676635742

不正确的例子:

ACTUAL: type=float32; dims=[3,4,5]; data=[1.0915919542312622,1.0915919542312622,0.04060405492782593,...  

标签: glslwebgl

解决方案


通过反复试验,我意识到要从非规范化数字到规范化坐标,我不能只将偏移/索引除以纹理的宽度/高度。必须包括一些公差。例如,TexCoords 中的实际数字从不从 0 开始。它们从不在 1/w 或 1/h 上,但总是明显更大或更小。

所以现在我要在索引中添加一个 0.5(我仍然没有科学的理由),然后才能得到它的标准化坐标:

vec2 coords = vec2((s+0.5)/xScale, (t+0.5)/yScale)

推荐阅读