为什么我的片段着色器收到的属性超出了我设置的范围?

时间:2018-07-20 15:06:27

标签: opengl glsl shader fragment-shader opengl-3

我有大量没有MSAA渲染的纹理正方形瓷砖(由两个相邻的三角形组成)。所有图块都以网格状接触,并在1280x720单位的画布上具有32单位的宽度。

*******
*   / * 32 units
* /   *
*******
32 units

渲染并平滑移动相机时,在每个图块的边界之间会显示线条,但令我惊讶的是,即使我将片段颜色硬编码为黑色,这种情况仍然会发生。这表明这不是瓷砖之间经常出现的纹理图集渗漏。

纹理图集为2048x2048像素,每个图块的内部为128x128像素。我将地图集的第二行,第二列作为目标,因此,每个图块的UV坐标分别设置为0.125、0.125(左上图块)至0.1875、0.1875(右下图块),这完全是 我在缓冲区中上传的内容。

使用以下片段着色器,所有故障线都变为红色,而不是以前看到的出血:

#version 330

uniform sampler2D tex;

in vec2 v_uv;
out vec4 f_color;

void main() {
    vec4 color = texture(tex, v_uv);

    // Use the color black for every fragment
    if (color.a >= 0.0) { // Always TRUE
        color = vec4(0.0, 0.0, 0.0, 1.0);
    }

    // Check if the given v_uv is within the bound
    if (v_uv.x < 0.125) {
        color = vec4(1.0, 0.0, 0.0, 1.0);
    }

    f_color = vec4(color.x, color.y, color.z, color.a);
}

注意测试以查看UV是否在范围内。出现红线表明,尽管请求的属性值介于0.125至0.1875之间,但着色器却接收到〜0.12499。这是没有意义的,因为标准浮点应该能够精确地保持0.125。

为什么我的片段着色器在浮点应该能够精确地精确地保持0.125和0.1875的情况下收到一个略有错误的值?

此着色器和带有数十个黑色图块的红线的示例视频:https://gfycat.com/PlushScientificAlligator

这与GLFW,glad,OpenGL 3.3,GLSL 330和C ++一起运行。

以下是一些其他详细信息:

顶点着色器,主要是直通,仅将顶点乘以我的投影即可。经测试,它确实会收到任何无效的UV坐标:

#version 330

uniform mat4 projection;

layout(location = 0) in vec2 position;
layout(location = 1) in vec2 uv;

out vec2 v_uv;

void main() {
    gl_Position = projection * vec4(position.x, position.y, 0.0, 1.0);
    v_uv = uv;
}

由以下组成的顶点数组:

glVertexAttribPointer(index, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(GLfloat), nullptr);

我正在使用两个缓冲区:一个位置和一个UV缓冲区。每帧重新上载所有数据。仅当相机移动并处于特定位置时,才会发生闪烁。

典型的帧由以下迹线组成:

Frame call trace

更新投影制服,上传UV数据,绑定纹理,上传位置数据,绑定顶点数组,最后通过GL_TRIANGLES从0到总计数绘制数组。非常标准和简单。

相机的位置几乎改变了处理UV坐标的方式。真的很奇怪而且很难调试。

更新

我在顶点着色器中进行了测试,以查看在该阶段边界是否在边界之外,是否不在边界内。当我们到达片段着色器时,边界就在外面。这意味着我的UV坐标在顶点和片段阶段之间变得不精确-也许是插值错误?

0 个答案:

没有答案