I am writing a project that uses a tile-based rendering system and have encountered the very common ‘lines between supposedly touching tiles’ issue.
Firstly, I checked to ensure all of my tiles were touching when uploading my data -> all okay, definitely the correct UV coordinates and data sent with no obvious rounding errors.
Secondly, I disabled MSAA and checked whether it was the UV coordinates bleeding or the floating point positions being off -> UV coordinates seemed to be bleeding in texture atlas.
I was surprised to see that when I wrote the following simple fragment shader (to test if the v_uv
was within the UV coordinates I require):
#version 330
uniform sampler2D tex;
in vec2 v_uv;
out vec4 f_color;
void main() {
vec4 color = texture(tex, v_uv);
float tile_size = 128.0 / 2048.0;
float top_left_x = 256.0 / 2048.0;
float top_left_y = 256.0 / 2048.0;
if (v_uv.x < top_left_x) {
color = vec4(0.0, 0.0, 0.0, 1.0);
}
if (v_uv.y < top_left_y) {
color = vec4(0.0, 0.0, 0.0, 1.0);
}
if (v_uv.x > top_left_x + tile_size) {
color = vec4(0.0, 0.0, 0.0, 1.0);
}
if (v_uv.y > top_left_y + tile_size) {
color = vec4(0.0, 0.0, 0.0, 1.0);
}
f_color = vec4(color.x, color.y, color.z, color.a);
}
The bleeding texture atlas now showed black lines instead of the original atlas bleeding. How can that be and why is it extrapolating the UV outside of my primitive’s edges by a small amount?
Even though I uploaded the UV coordinates of (0.125, 0.125)
to (0.1875, 0.1875)
for every tile (the texture is located on the 2nd column and 2nd row, 128px of a 2048px atlas).
TL;DR: Why is the fragment shader given a v_uv
out of the primitive’s bounds and why does the vertex shader receive the correct UV, but fragment not?