SOLVED!: A year later, I still don't get Godot's scaling... Why does it do this?

Godot Version

Godot Engine v4.2.1.stable.mono.official [b09f793f5]

Question

A year later, I still don’t get Godot’s scaling… Why does it do this?

I’ve kind of just been ignoring this while working on other aspects of my game, but even a year later I STILL don’t understand why Godot has this weird scaling issue ONLY when the viewport X and/or Y is an odd number. When it’s an even number it’s fine, but when it’s odd, you get doubled or missing pixels, even at 1x zoom. Often there is a diagonal shearing too.

Why does it do that?

(The built-in integer scaling on the project settings page doesn’t have this problem, but then Godot will do bland black letterboxing instead of expanding to show the pretty border I placed around the camera.)

SOLVED! I fixed it myself after realizing it was because the camera is in the middle of a pixel on odd-numbered dimensions. I fixed it by checking for odd dimensions every time the window is resized and offsetting the camera by 0.5 pixels for that dimension. No more doubled or invisible pixels!

update 1: Actually, rather than 0.5, use 1 divided by the current integer scaling level (1, 2, 3, etc.), otherwise it won’t work for odd numbered dimensions after integer scaling once.

update 2: Oops, more like offset by 1/(n+1), where n is the current integer scale, but you get the idea.

update 3: Actually, just simply offsetting by 0.1 seems to always work for now. The 1/(n+1) incidentally works too, but is the result of me messing around and quickly posting a working solution because I was excited to finally fix it.

update 4: Okay this is weird, I tried running my un-fixed code on my brother’s computer, and even without off-setting the camera, and it just… works? Without any issue whatsoever. I have no idea why it is giving me doubled pixels on odd-numbered dimensions and not my brother, maybe was a problem with my GPU the whole time or something (I have an AMD GPU, and he has NVIDIA)?

4 Likes

After messing around with some visual aids in GIMP and doing some math, it seems like the perfect offset is 1/(2 x n), where n is the current integer scale (x1, x2, x3, etc.). The reason an offset of 0.5 doesn’t work at 2x scale is because you’re just ending up in the middle of a pixel again since we’re not account for the fact that each “logical” pixel is 2x2 “real” pixels. The offset needs to be 0.25, which 1/(2 x 2) gives you. For 3x scale, you get 0.166… and so on. At least, I think I have that right. It works for me in any case.