Page 1 of 1

Need help with quad bleeding

Posted: Sun Oct 30, 2016 9:54 am
by drikdrok
I must have spent atleast 10 hours with this problem... And I have now decided it's time to ask for help.

I'm drawing a world inside a sprite batch, and at certain points, black lines appear between tiles. I'm pretty sure this is caused by "quad bleeding".
I have tried flooring multiple variables at different places, nothing works. I have made borders around the tiles in my spritesheet. And to make everything more complicated. The black lines behave differently depending on what computer i test on...

Perhaps somebody knows what causes it and how to fix it? I have provided the whole project in .love form.
Thanks! :awesome:

Re: Need help with quad bleeding

Posted: Sun Oct 30, 2016 10:15 am
by D0NM
you should OVERLAP the tiles.
Now u have 16x16 tiles.
Add extra row and column to each tile -> 17x17
and draw them as you did for 16x16.
Visually you won't see any differences because all the "extra" pixels of your tiles are covered with their neighbour tiles.

Do not worry, some people have the similar problems here.
Because OpenGL has some peculiarities with texture bleeding.

Since you use scaling, you will always have such a problem here.
You might minimize it if you use some integer steps in your scaling. Round the numbers.

Re: Need help with quad bleeding

Posted: Sun Oct 30, 2016 11:28 am
by Fuzzlix
D0NM wrote:you should OVERLAP the tiles.
Now u have 16x16 tiles.
Add extra row and column to each tile -> 17x17
and draw them as you did for 16x16.
Nice trick. I will keep it in mind. It may work well when you "flood fill" your screen top-left to botto-right.
I had similiar trouble in my game. My tiles are very small compared to the display resolution. On hd displays i end up drawing with scale = 6..8.
I use a different solution: i use a canvas to draw all stuff into using scale=1. Finally i draw the canvas with scale=6 to the window.

Re: Need help with quad bleeding

Posted: Sun Oct 30, 2016 12:44 pm
by D0NM
Fuzzlix wrote: I use a different solution: i use a canvas to draw all stuff into using scale=1.
Finally i draw the canvas with scale=6 to the window.
We use it in Zabuyaki, too. But we still overlap the tiles / graphic chunks at least with 1 pixel.
Because our original scale ~= 1. It is always 2x.
So we had that bleeding issues. Especially when our parallax have many layers with different movement speed, etc

Here goes some interesting reading about the textures
In this case, you will always be sampling the center of each texel and you should not get any bleeding... Unless you use mipmapping, in which case you will always get bleeding starting on the mip level where the scaled subtexture doesn't neatly fit inside the pixel grid.

To generalize, if you want to access a specific texel, the coordinates are calculated as:

Code: Select all

function get_texel_coords(x, y, tex_width, tex_height)
    u = (x + 0.5) / tex_width
    v = (y + 0.5) / tex_height
    return u, v
end
This is called "half pixel correction". There's a more detailed explanation in here if you're interested.
the source

Re: Need help with quad bleeding

Posted: Sun Oct 30, 2016 3:25 pm
by drikdrok
D0NM wrote:you should OVERLAP the tiles.
Now u have 16x16 tiles.
Add extra row and column to each tile -> 17x17
and draw them as you did for 16x16.
Visually you won't see any differences because all the "extra" pixels of your tiles are covered with their neighbour tiles.

Do not worry, some people have the similar problems here.
Because OpenGL has some peculiarities with texture bleeding.

Since you use scaling, you will always have such a problem here.
You might minimize it if you use some integer steps in your scaling. Round the numbers.
THANK YOU!!
I will try this :awesome:

Re: Need help with quad bleeding

Posted: Sun Oct 30, 2016 5:43 pm
by Jasoco
math.floor all the X and Y coordinates of your drawn images, or better yet, your camera. And don't zoom arbitrarily to decimal values unless you have to.

Re: Need help with quad bleeding

Posted: Sun Oct 30, 2016 7:04 pm
by raidho36
The problem is that texture coordinates are interpolated and can be shifted by sub-pixel amounts, but renderable fragments can only take integer coordinates, and during rendering, fragments are only generated for pixels which centers directly overlap with the polygon. So there may be situations where there are small gap between polygons and fragments are not generated in there. Alternatively, the texture may be subpixel shifted so that on the edges areas outside of the intended texture become visible.

Proper solution is to pad texture with same pixels as on the edge, or wrapped around if the tile is to be rendered with wrapping.

Re: Need help with quad bleeding

Posted: Mon Oct 31, 2016 1:35 am
by pgimeno
A failsafe solution, assuming you can't zoom out too much, is to draw everything in 1:1 scale to a canvas, and then zoom the canvas.

Re: Need help with quad bleeding

Posted: Mon Oct 31, 2016 6:06 am
by raidho36
That will still happen with non-integer coordinates.

Re: Need help with quad bleeding

Posted: Mon Oct 31, 2016 3:36 pm
by pgimeno
Yes, but drawing at 1:1 scale makes it clear what to round and how. Drawing at arbitrary zoom levels causes rounding problems which leads back to black lines.

The problem of this method is that you can only scroll in original pixel coordinates, not fractions (unless you scroll the canvas by the fractional part, after having made it 1 pixel bigger).