我有大量没有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缓冲区。每帧重新上载所有数据。仅当相机移动并处于特定位置时,才会发生闪烁。
典型的帧由以下迹线组成:
更新投影制服,上传UV数据,绑定纹理,上传位置数据,绑定顶点数组,最后通过GL_TRIANGLES从0到总计数绘制数组。非常标准和简单。
相机的位置几乎改变了处理UV坐标的方式。真的很奇怪而且很难调试。
更新:
我在顶点着色器中进行了测试,以查看在该阶段边界是否在边界之外,是否不在边界内。当我们到达片段着色器时,边界就在外面。这意味着我的UV坐标在顶点和片段阶段之间变得不精确-也许是插值错误?