Texture bleeding

Member
Posts: 65
Joined: 2009.03
Post: #1
Hi all

I know this kind of thing has been asked before from searching the forum, but I'm not sure I've got the final answer on this.

I have a spritesheet class which can use smaller textures from within a larger texture. This is working fine when the sprite is static. When I move the sprite I end up with a single line of pixels bleeding into the bottom and right of my sprite from the textures below and to the right in the spritesheet.

I calculate the texture coords for the sprite once when it is created and then calculate the quad each game cycle. The reason for this is that i'm loading the quads into an array and then rendering them to screen using glDrawElements to reduce the number of OpenGL calls. When I was calculating the quad size once and always drawing at 0,0 and using glTranslate, I never had this problem, even when moving sprites.

If I place a pixel space around the textures I don't get the issue which is a simple enough fix.

I am guessing that as I'm calculating the location and size of the quad each game cycle, there is some rounding issue which is causing the quad size to be adjusted when the location is between pixels if that makes sense causing me to get this bleeding.

Does that make sense? and is spacing around the textures the only fix for this?

I've read that this bleeding issue can be a real pain but I wanted to make sure I was not missing something and to check that adding spacing to the spritesheet was best approach.

Thanks for any help.

MikeD
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #2
Sounds like you are getting filtering artifacts where the pixels don't line up 1:1 with the texels you are trying to draw.

Turn of linear filtering or snap your vertex coordinates to integer values.

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #3
When using NEAREST (doesn't matter with LINEAR), I found that making sure the texture coordinates were even (as opposed to odd) helped get rid of the rounding errors. For example: Let's say I have a sprite which is 19 pixels high in a 512x512 sprite sheet. I'll use 20/512 for calculating the texture coordinate, to avoid artifacts, instead of 19/512.
Quote this message in a reply
Member
Posts: 446
Joined: 2002.09
Post: #4
It's usually easier to just leave some padding around each tile in your texture. I find 1 pixel is enough (that is, 2 pixels between tiles, and one pixel at the edges - though using edge clamping can sometimes fix edge cases).
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #5
Padding didn't help with my funky edges. It has to do with how OpenGL does the sampling for NEAREST. I wasn't having texture "bleeding", but rather aliasing, so I don't know if what I described is actually relevant to the OP or not, but I figured it was worth mentioning.
Quote this message in a reply
Member
Posts: 446
Joined: 2002.09
Post: #6
Sorry - I was replying to the OP and you snuck in ahead of me...

I've seen those problems with NEAREST filtering as well, though they seem to be exaggerated in the simulator (or at least render much differently on the device).
Quote this message in a reply
Moderator
Posts: 3,571
Joined: 2003.06
Post: #7
Yes! I've seen that it's different between the simulator and the device too. I thought maybe the device was more friendly about it, but after lots of experimentation that's not the case. There's no way to know when either one will sample up or down a pixel, so like I said, my solution was to stick to even coordinates. That seems to have worked perfectly so far.
Quote this message in a reply
Member
Posts: 65
Joined: 2009.03
Post: #8
Thanks for the info guys. I am going to go with leaving a pixel border around each image. I also came across a comment when looking at the latest 3.0 release notes

Quote:Issue: In an OpenGL ES application, texture operations are sampling off the edge of single image within a texture atlas into neighboring images.
This symptom can occur when an OpenGL ES application assumes a particular sub-pixel precision is honored by the GPU. To correct this issue, you should always leave enough padding in between the images within a texture atlas to account for sampling texels along the edges of any one image.

I have been using GL_NEAREST for the filtering as the images are tightly packed and LINEAR was producing off edge effects. But even with NEAREST I was getting the bleeding.

I had been doing a lot of work on the Simulator which did not show the bleeding at all, it only appeared when I tried it on the device.

Again, thanks for the info guys and I'm going to go with the padding.

MikeD
Quote this message in a reply
Post Reply