Monogame Tiled Zoom In cause Warped Tiles and wierd graphics


I render a Tiled Map with Monogame Extended and everything is fine except when I Zoomed In.

Here what I got at 1x Scale:

And what I got at x4 Scale (I put red square to demonstrate my problem):

I don’t know how to fix this problem.

I noticed that the demo code from Monogame Extended seems to have the same problem.

Is there a solution for my problem, thanks in advance.

I’m not sure I see a problem here, the zoom looks like I would expect, not sure what the red squares are for. Would love to know what others think as I just don’t see an issue.

It’s actually quite difficult to write a good tiled map renderer that works perfectly in all situations. We’ve already been through a few iterations on this renderer and it’s already much better than some previous attempts.

Honestly, I don’t know how to make it perfect at all zoom levels.

You could always try and write your own renderer. There have been a few ideas over the years for different types of renderers, each with their own pros and cons. It’s a tricky balance between memory consumption, rendering quality and frame rate performance. Depending on your requirements you might be able to get something that works better for your situation.

With the existing renderer though, probably not.The only thing I can think of that might help is to try and clamp your zoom levels to ones that work well for your game. It should render perfectly at multiples of 2 and it’ll probably work okay at some other ones. You’ll just have to play with it and see.

Thanks you for your response.

In my case, I want to do a game in the Style of 16-bit era (Super Mario World, Mega Man, etc.) Where Pixel are clearly visible.

All my game is in 320x240 resolution. But playing on a window resolution of 320x240 is a bit small.
So I want the player to change the resolution when he wants between 320x240, 640x480 and 1280x960.

At first, I wanted to simply zoom with the camera (scale of 1x, 2x and 4x) when needed but it created the Warped Tiles.

Did I need to write my own renderer to achieve my goal or you have any others suggestion?

I don’t see any problem or artifact either. Your eyes are ok :wink:

Why not render the whole game in 320x240 on a render target and then render that to the backbuffer either with x1, x2, x3 or x4 resolution. You can use pointsampling to keep things pixelated.

Ahah, I think so :stuck_out_tongue:

Here a images (I scale x4 in paint to see better) to demonstrate the problem. If I zoomed x4, normally, all pixel must be multiply by 4, but not here:

And here what I want:

I’m not very familiar with the RenderTaget2D class.

Monogame Extended Tiled does’t use a SpriteBatch to draw the map (from what I understand from the source code). I think it make a 3D shape with the texture of the map.

I will check what I can do with RenderTarget2D,

Thanks :slight_smile:

They are at the same distance number of rectangles (as the squares/pixels are a little deformed) between the 2 so its seems ok without that level of zoom (impossible to zoom it on my phone :rage:)
You have the same problem as depicted here

I think you need to take into account the aspect ratio when zooming to keep the pixels as squares all of the same size. And even like that it may not be perfect

Just render like you normally would, but in front of the drawing code set your render target using GraphicsDevice.SetRenderTarget. After rendering unset the RT so you draw to the back buffer again by calling SetRenderTarget with argument null. You can use SpriteBatch to draw your Render Target to the back buffer. Make sure to pass a Point sampling state to SpriteBatch.Begin to get proper upscaling (no interpolation between pixels).

It works perfectly when using a RenderTarget2D to render my entire game and then scale it, plus I learned something about GraphicsDevice and RenderTarget

Thank you for your support, this is greatly appreciated :slight_smile:

1 Like

I’m having the exact same issue as referenced earlier. Would you mind providing an example how you resolved it?

Hi mason-wolf, here what i do:

  1. Don’t zoom with the camera, stay at 1x scale.

  2. Declare a RenderTarget2D with the native resolution you want, for me, it was 320x240. (Don’t do this in the Draw loop or the Update Loop, do this before that):
    PresentationParameters pp = Graphics.GraphicsDevice.PresentationParameters; _renderTarget = new RenderTarget2D(Graphics.GraphicsDevice, 320, 240, false, SurfaceFormat.Color, DepthFormat.None, pp.MultiSampleCount, RenderTargetUsage.DiscardContents);

  3. Before you begin to draw anything in the Draw loop, change the RenderTarget2D of the GraphicsDevice:
    GraphicsDevice.SetRenderTarget(_renderTarget); GraphicsDevice.Clear(Color.Transparent); GraphicsDevice.BlendState = BlendState.AlphaBlend; GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp; GraphicsDevice.RasterizerState = RasterizerState.CullNone;

  4. Draw what you need

  5. After you have finish to draw your game, reset the RenderTarget of the GraphicsDevice:
    GraphicsDevice.SetRenderTarget(null); GraphicsDevice.Clear(Color.CornflowerBlue); //I do this to have a background color

  6. Now you have a “Texture” of your “entire game”, simply draw it at the scale you want, here I put 640x480 (be sure the scaling is consistant if you want Perfect Pixel):
    SpriteBatch.Begin(samplerState: SamplerState.PointClamp); SpriteBatch.Draw(_renderTarget, destinationRectangle: new Rectangle(0, 0, 640, 480), color: Color.White); SpriteBatch.End();

  7. NOTE for Mongame.Extended.Tiled:
    If you have a instantiate your Camera2D with a ViewportAdapter, be sure to that it’s a DefaultViewportAdapter and not a BoxingViewportAdapter or ScalingViewportAdapter, these two seems to change the Viewport when the Window Size change (if somebody can help with that, it will be nice, but for now, it’s work with DefaultViewportAdapter)