Sprites getting stretched and cut off

Hello folks.
I recently came into a problem with drawing pixel-art sprites in my game. I have my game drawn on a RenderTarget2D which is then scaled when drawn to 1920x1080 (the size of my monitor). I was drawing stars on the screen (I’ll put the spritesheet below) but noticed that they only maintained their proper look when having it’s velocity (x or y) a whole number. When changing it from 1 to something like 0.5f, this happens:


This is the spritesheet (scaled only for this post, normally 1x1 pixel ratio):
starsheet

Also, here’s the code where I draw it:

        GraphicsDevice.SetRenderTarget(renderTarget);
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin(samplerState: SamplerState.PointClamp);
        stars.Draw(spriteBatch);
        spriteBatch.End();
        GraphicsDevice.SetRenderTarget(null);
        GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin(samplerState: SamplerState.PointClamp);
        spriteBatch.Draw(renderTarget, new Rectangle(0, 0, 1920, 1080), Color.White);
        spriteBatch.End();

If anyone can help me get to the bottom of this that would be great. Also, I don’t know if this is relevant but I’m scaling the RenderTarget2D using the Rectangle overload, not the Vector2 overload.

For your stars spritesheet, do you have any space between the stars and the edge of the image, as well as each frame? If not, just leave like 1 pixel along the outer edges and between images.

I didn’t have that. Thanks. Just curious though, why would that matter?

I believe, and I might need to be corrected on this, that when dealing with positions with decimals, the source rectangle shifts and grabs the adjacent pixel of the image. If there is not an adjacent pixel, it wraps to the other side.

1 Like

Interesting, that makes sense.

Inside of stars.Draw, try casting your star position to int when you make the call to the spriteBatch Draw method.

I see this issue all the time and is usually a result of rasterization of sub-pixel positions. It’s fine to have your velocity as a float and the movement be sub-pixel, but the actual rendering needs to be resolved to the nearest integer. If you let the built-in rasterizer figure it out, it does stuff like this.

Assuming stars is a class which contains some kind of list of stars, _stars, and each star has a Position member which is a Vector2, you can do this…

for each (var star in _stars)
  _spriteBatch.Draw(_starTexture, _star.Position.ToPoint(), Color.White);
2 Likes

Thanks so much, that fixed it. I actually had tried that before and forgotten :smiley:

1 Like