How to properly maintain 1:1 pixel scaling

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By GameDev252

I’m trying to set up an option that lets you double the in-game resolution, going from 600x480 to 1200x960.
Currently my stretch settings are Mode:viewport and Aspect:keep. Pixel snap is also enabled. I’ve played around with all options, but with no luck. I’ve also searched excessively both on these forums and other sites, and while I have found people with somewhat similar issues, none of the proposed solutions worked for me. The code I am using to change the window size is simply OS.set_window_size(NewResolution)

The heart of the matter:
This is a screenshot of the game running at it’s base resolution. It looks the way it’s supposed to.
Original resolution screenshot

This is a screenshot of the game running at precisely double resolution.
Doubled resolution screenshot

The differences might not be immediately noticeable, but I’ve zoomed in on a specific example for convenience’s sake.

This is what the pixels are supposed to look like, scaled up manually from it’s original resolution.
Scaled up correct example

And here’s what the pixels look like at the doubled resolution, scaled up manually to preserve aspect ratio as well
enter image description here

As you can tell, some pixels that should have become 2x2 pixels have instead arbitrarily become 1x2 or 2x1 pixels.

If anyone can tell me what I can do to preserve the individual pixel aspect ratio when doubling the game’s resolution, I would greatly appreciate it. Thank you in advance.

Edit (01-03-2021):
Just some additional information, the issue still persists. I’ve updated to godot 3.2.3, just on the off-chance this was a bug that had been fixed, but to no avail.

I’m using a Camera2D node to display the game, and if I keep the base resolution but have the camera be at x2 zoom (so that the sprites increase by the same amount), they look the way they’re supposed to, with every pixel being at the appropriate 2x2. Obviously this still doesn’t fix the problem, as playing at x2 zoom cuts off 75% of the game display, but I thought it was an interesting piece of information.

For the sake of clarity, this issue is not only for the specific purple-ship sprite I’ve posted in the screenshots, but for every sprite in the game.
The incorrect pixels are not consistent, and seem to change whenever the sprite moves, whether it by along the y vector or the x vector. Even if they move at exclusively whole integers, the sprites still morph. I set up a script that constantly prints out the Vector2D position to ensure that they weren’t accidentally moving across any decimal vectors.

To completely ensure that I am increasing the resolution correctly, I’ve set up temporary code within the resolution_change function, a single line of code stating
OS.set_window_size(OS.window_size*2), so that there can be no mistake that the resolution is exactly double.

Thank you for all the replies so far.

Scaling by a whole number factor should be pixel perfect. I checked the sizes of your images: the first one is 397x460 and the second one is 763x795. Are you sure it’s actually 200%?

exuin | 2021-02-19 07:11

Oh, yes, that’s my mistake, it’s simply because the screenshots were not cropped perfectly. Sorry for the confusion, but there’s no doubt that it’s exactly doubled.

GameDev252 | 2021-02-19 09:05

Okay, so I have 3.2.3 and not 3.1.1 so I don’t think I can really test anything here. Sorry.

exuin | 2021-02-19 15:36

Are you using an hiDPI display? If it has a fractional scale factor (e.g. 125% instead of 200%), it will likely introduce such differences when trying to resize the window.

Make sure Allow Hidpi is enabled in the Project Settings.

Calinou | 2021-02-19 21:11

I do not have a hiDPI display, no. Allow Hidpi was not enabled in the settings, and I tried toggling it on and off just now, and it did not appear to make any difference.

GameDev252 | 2021-02-20 06:19

try with OS.window_fullscreen and check the resolution it puts you and if the error persists…

with mode: viewport, aspect: keep and resizable checked you should have no problem unless you are trying incompatible resolutions… but also check Pixel Snap and the orientantion of screen… hope it helps

Surtarso | 2021-02-26 00:21

The problem persists with os.window_fullscreen, as my full screen resolution is 1600x900, which is not compatible with the base resolution of 600x480.

GameDev252 | 2021-02-26 17:12

With mode viewport and aspect keep and resizable, os.fullscreen should have added black bars around where there should be no pixels…same with resize dragging the sides… Thats how I configure most of my projects

You got something mixed there between project settings and code, that would be my best bet

Surtarso | 2021-02-26 23:25

os.fullscreen does indeed add black bars, yes, but the pixels do not scale correctly. When working with precise pixel art, the only way to keep the pixels consistent is by multiplying the resolution by a whole number. If I am to go into fullscreen, the resolution will go from 600 on the x vector to 1600 on the x vector, which is a multiplication of 2.6667. My code takes it from 600 to 1200, multiplying it by 2, a whole number, and yet I still have incorrect pixel scaling, which is where my problem lies. I apologize if my initial post was not clear enough. It is not a matter of problems with the aspect ratio, but the ratio of individual pixels in the sprites.

GameDev252 | 2021-02-28 10:16

have you tried with Aspect: keep_width or keep_height?

on asset import, are you using lossless and disabling filter? (or using the 2d pixel preset)

are you by any chance changing the scale of the sprites/pixelart?

it’s an odd problem you have there. My projects are all pixelart as well and I never encountered that, or maybe never noticed…

Surtarso | 2021-02-28 12:07

Thank you for your response. I have attempted with both keep_width and keep_height, but neither seem to have an effect. I am using the lossless import, as well as disabling the filter. I’ve looked over my code several times, and nowhere are the scales of the individual sprites being changed. I’d like to reiterate that everything looks fine at the base resolution, it is only when I double it that problems begin to occur.

GameDev252 | 2021-03-01 10:03

I’m months late and don’t have an answer, but I do think I have an explanation as I’m dealing with the same issue. It seems that if the viewport resolution isnt a perfect multiple of the window resolution, you’ll get weird scaling issues at random parts of the screen. For me, I’m dealing with 16x16 px sprites, and if the resolution isnt a multiple of my viewport resolution, the sprites stretch depending on their location of the screen. I think we have slightly different end goals, but I found your question while trying to solve mine and I hope I could at least give some answers as to why its happening even if I dont have a solution.

draogn1freak | 2021-07-04 22:15