[Solved] Weird Display Issue Using a Rectangle

Hello, I’m making a platformer in pixel art and I have some issue with displaying some sprite.
Sometime, the rectangle display a bit of the to sprite above it.

I create a tiny project just for see if the bug was on my platformer game, so I create a new monogame for window project and here is the program :

    Texture2D sprite;
    Rectangle rectangle;

    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);

        sprite = Content.Load<Texture2D>("player");
        rectangle = new Rectangle(0, 32, 32, 32);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        spriteBatch.Begin();
        //spriteBatch.Begin(samplerState: SamplerState.PointClamp);

        spriteBatch.Draw(sprite,new Vector2(50,50), rectangle, Color.White, 0, Vector2.Zero, new Vector2(12), 0, 0);


        spriteBatch.End();

        base.Draw(gameTime);
    }

Here you can see the render…

…and here is the sprite that I use (in png, it 32*32 pixels) :

Normally when the game display the sprite with the rectangle (I took the first frame of the walk animation), we are not supposed to see the foot of the sprite just above (the first sprite of the base animation) :

However this is just the tiny project, and in my platformer project, I use the “spriteBatch.Begin(samplerState: SamplerState.PointClamp);” for keep all pixels intact, and I have the same issue, I still see sometime a bit of the sprite above.

I try to re-create this situation in the tiny project by using “spriteBatch.Begin(samplerState: SamplerState.PointClamp);” instead of a normal “spriteBatch.Begin();” but I did not manage to do it. (I also try to use float like 10.5f for the size of the sprite in the spriteBatch.Draw() method ).

Note : in my platformer project I use a matrix to render sprite, but I don’t think that impact the fact to have a portion of the sprite above.

To avoid this, I can do a margin of 1 pixel between each frame, but I prefer to avoid using a margin, I will use them only if I don’t find any solution.

Which version of MonoGame are you using and which platform is your project targeting?

1 Like

I’m using the .NET Framework 4.5 and I’m targeting for a window project

(the screenshot is in French)

Oups sorry I didn’t fully answer the question. I’m using the 3.6.0.1625 version of monogame (I’m guess?)

Can you try it on the latest develop or on the latest stable, MonoGame 3.7.1, and see if the issue persists? 3.6 also has a catastrophic content pipeline issue, so I highly recommend upgrading regardless.

1 Like

I just try with the latest version of Monogame (3.7.1) and the result is the same.

SamplerState.PointClamp should definitely stop the neighboring pixel bleed (and make your sprite sharper when resized).
Here’s what it should look like with or without (the first square has red and green bleed on top and bottom, the second does not):


edit: replaced image with more clear one.

1 Like

In my platformer game I use"SamplerState.PointClamp" (and a matrix to render the game) but I still have this problem : here is a link https://youtu.be/yJZ-pv7d7BM

I have no idea why I do that, especially with the jump/fall animation (because on the walk cycle animation I don’t have this problem)

Are you rendering to a RenderTarget then drawing that RenderTarget to the backbuffer with a different SamplerState?

1 Like

I don’t use any “RenderTarget” ( I never use them, I should try… ), this is what I use to render the game
“spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, null, null, null, Transform);”

(Transform is just a matrix)

I’m not experiencing this problem in a fresh project. The video and screenshots indicate that there is something going on that’s not rendering the sprites with PointClamp. How are you making your matrix?

Which MG platform are you using?
There are two project types for the windows desktop, using DirectX and OpenGL.

could this be related to this?

1 Like

I make a windows desktop using DirectX. My pc is a Window 10 and I use visual studio 2017.

and here is the code of my matrix, but I don’t think this impact the problem.
" Transform = Matrix.CreateTranslation(new Vector3(-centre.X, centre.Y, 0)) *
Matrix.CreateRotationZ((float)Rotation.Direction) *
Matrix.CreateScale(new Vector3(Ratio.X, Ratio.Y, 0)) *
Matrix.CreateTranslation(new Vector3(View.Width / 2, View.Height / 2, 0));"

OK , openGL is ruled out.

How do you import the texture? Do you see any difference when you enable/disable the GenerateMipmaps option?

1 Like

In addition to mipmaps, make sure the sprite’s TextureFormat is set to Color.

The scale is incorrect; the Z should be 1.

2 Likes

I use the classic monogame Content.mgcb, I try to enable/disable the GenerateMipmaps, and it change nothings. The sprite’s texture format is already set on Color. I also remove the Z scale ( and also try with/without the GenerateMipmaps), nothings change.

(I remove my old message because I didn’t reply on the topic but only at nkast)

I think I found the origin of this glitch : When I’m trying to display an picture on some float value with a lot of decimal, sometime few pixel of the sprite above appear.

I make an other tiny project and I reproduce the same glitch with few line of code : here the link.

Important note : I try to share the file on dropbox but some folder failed to be shared on dropbox server. If the project doesn’t work : you just need create a new “windows desktop using DirectX” and copy/past the “Game1.cs” file from the link below in this new project, and add this texture in the monogame pipeline and call it “player”.

You will the sprite above in the 10-15 seconds after launch the project.

By the way, I try the project with and without using matrix, it change nothings.

http://community.monogame.net/uploads/default/original/2X/c/cfbfa9a668ffd116205421c95a2b0ffbf8f6b923.png

I didn’t find any solution for the moment, but I hope this project will help me to find any solution.

In theory, I can simply display the sprite by using “Math.Round()” of the position (because the screen is made of “whole number” (is this the good word ?) of pixels, so if I tell to the game to display the sprite at a “new Vector2(1.0123456789f,1.0123456789f)” or a “new Vector2(1f,1f)”, the same things should happen ?).

But how can I do that with a matrix ?

I think this is just a misunderstanding of what I usually refer to as “partial pixels”. Say you scale a texture that is 25x25 by 3.5, the result would be a texture that is 87.5x87.5. Since there is no such thing as a 0.5 pixel, Monogame will simply draw an extra pixel, and gathers what the pixel’s content should be based on the source image. So, if you were drawing just a single texture like this, it would work fine, since the outsides of a single texture (or a single sprite) would just be blank/transparent pixels. However, since you’re using a spritesheet, no pixel-wrap method is going to help you because you haven’t gotten to the edge of your original texture yet. So, it gathers the nearest rows/columns of pixels when it is adding that pixel. This could be why you see a portion of your sprite above, when you scale the sprite below to a size that it’s original resolution is not divisible by. Therefore, the solution is to give your sprites 1px padding between them. That’s one solution anyway, and probably the easiest.

1 Like

The UV is defined as (0,32) to (31,63) and the GPU interpolates between those values.
So, when you are drawing on a half pixel are you saying that the GPU is sampling the texture at (0,31.5) below the defined bound of V?

1 Like

@nkast Yes that what I try to say.

@TheKelsam If I don’t find any solution, I will give to my sprites 1 pixel padding between them (even if I don’t like this solution)

But if I’m scaling a texture that is 25x25 by 3.5, the result would be a texture that is 87.5x87.5 as you said TheKelsam.
But is there a way with a matrix to make the floor of the final texture and display it on a 87*87 area instead of a 87.5x87.5 area to avoid o display a bit of the sprite above ?