Texture Bleeding On Scale (2D) - I'm stumped!

Started by
5 comments, last by NexusOne 18 years, 9 months ago
Hey all, This one has me stumped and I hope someone else has come across the issue. Whenever I scale my sprite (my own quad, not the sprite interface), if I use a fairly "odd" number, the texture begins to bleed from the top or left side, depending on which way I'm scaling. Here's a picture: Top Scale: 2,2 Middle Scale: 2.15, 2 Bottom Scale: 2, 2.15 Here's a copy of the sprite sheet I'm using (I didn't add all these funky borders until I realized it was bleeding): I'm using Matrix.Transformation2D() to manually transform the vertices. Here's a basic snippet:

mat = DirectX.Matrix.Transformation2D(new DirectX.Vector2(renderInformation.Corners.Width / 2, renderInformation.Corners.Height / 2), 0, renderInformation.Scale, new DirectX.Vector2(renderInformation.Corners.Width / 2, renderInformation.Corners.Height / 2), 0f, new DirectX.Vector2(renderInformation.X, renderInformation.Y));

// Bottom Left Vertex For Example
vector.X = renderInformation.Corners.Left;
vector.Y = renderInformation.Corners.Bottom;
vector.TransformCoordinate(mat);

// Add this information to the VB
vbData[polygon].X = vector.X;
vbData[polygon].Y = vector.Y;

vbData[polygon].Tu = renderInformation.TexturePoints.Left;
vbData[polygon].Tv = renderInformation.TexturePoints.Bottom; 

I'm 99% certain it's not related to my code (or atleast, this snippet) because the texture coordinates are calculated at the beginning when the animations are loaded. Here's that snippet if it's going to help:

_texture = VideoTask.Instance.GetTexture(texture);
using(Direct3D.Surface surface = _texture.GetTexture().GetSurfaceLevel(0))
{
	_textureRect = new FloatRectangle((float)top / surface.Description.Height, (float)left / surface.Description.Width, (float)bottom / surface.Description.Height, (float)right / surface.Description.Width);
}

Any ideas? I'm completely baffled on this one. It almost seems like a floating point error but the texture coordinates aren't dependent on scale!
Advertisement
I had a sprite animation that had each frame of the animation stored in the cells of a grid. When I moved that sprite animation across the screen, when it wasn't at integer coordinate the black grid border would "bleed" onto the sprite animation.

This bleeding was prevented by loading the image without a filter and/or (I don't remember) disabling anti-aliasing. Unfortunately, with AA disabled, the rotated sprite looked terrible so I switched AA back on, bringing back the texture bleeding.

My ultimate "solution" was to say "erase your gridlines so we don't have this horrible texture bleeding"!

If you don't plan on rotating your sprites then disabling AA and the texture filtering should work. If you do have to rotate then well, you could well, take the easy way out like I did [grin]. There's got to be a better solution...
Your problem is most likely the common texel to pixel problem described in numerous articles, also one or two here on GameDev. What it basically means is that texels map to corners of the "pixels", whereas pixels map to the center (or the other way around, can't remember)... something that isn't possibly visible without a filter, but when scaling, that half pixel becomes a full one and thus possibly showing (something like that at least ;)).

So, take a look at the DirectX articles and you'll find it.

http://www.gamedev.net/reference/articles/article1608.asp

has a solution for it, however not the one recommended by microsoft, but should do just as well as it is all about changing coordinates and sizes.

and microsofts

http://msdn.microsoft.com/library/en-us/directx9_c/directx/graphics/programmingguide/gettingstarted/direct3dtextures/coordinates/mappingtexelstopixels.asp?frame=true


Just as a note, I've tried two ways of offsetting by 0.5 texels on a GeForce3 while using RHW coords. One was to offset the position, and one was to offset the texture coordinates. The position method did nothing. While it may work on non-RHW coordinates, it certainly doesn't on RHW coords, which is what most tile and sprite systems will use. Offsetting the texture coordinates worked great.

Be aware, then when scaling down and using linear filtering, it's still possible you'll grab texels from neighbouring tiles, or that the texel in the mipmap level used is already a mix of neighbouring tiles.
Namethatnobodyelsetook, could you go into how you offset the texture coordinates? Offsetting the position is doing nothing for me.
*bump* *sniffles*
The texture coord system in Managed DX isn't the most reliable. I suggest using borders of 3-4 "safety pixels" around the edges of your texture in case it bleeds (my tree textures always bleed).
Graphics make the game! 8-)

This topic is closed to new replies.

Advertisement