How to control scaling algorithm?

Godot Version

4.3

Question

The Image class can set an upscaler (although it’s called interpolator for some reason)

Image.INTERPOLATE_LANCZOS

Is there a way to do this project wide? A global upscaler setting? Like for instance when the window is scaled and the stretching functionality is used:

Or when a 2d sprite is scaled.

I want it to use a decent upscaler like Lanczos or FSR or just about almost anything that is not Bicubic which is what godot seems to be using by default.

I feel like this is extremely important for 2D games.

Hi. In general, you can create a specific set of settings directly in the project settings. There you can create new global variables with a given data type, and then manage them through ProjectSettings.get_setting() and ProjectSettings.set_setting().
For example, make a separate branch inside the settings or add a new parameter “Render Type” inside an existing rendering branch.

2 Likes

Global settings is very useful information I didn’t know about, but how can I use this to control the scaling algorithm used for rescaled objects or the window as a whole?

As far as I have been able to find no function exists to do that in the first place (which is why i’m asking about it, only exception is for the image class which supports it, but since most of the time i’ll be scaling textures not images and ImageTexture does not have any special upscaling settings)

  1. You need to create a new parameter inside your settings.
  2. Then you need to access these settings using ProjectSettings. There are several Enums inside the Image class. They can switch the global parameter using their index or convert in dictionary to use String or StringName.
var image_upscale_mode = Image.INTERPOLATE_LANCZOS
ProjectSettings.set_setting("render/upscale_mode", image_upscale_mode)
  1. When you change a setting, you need to redraw your canvas for the changes to take effect, you may need to check the update() function in IMAGE class and the DisplayServer class.
1 Like

The Image class’ filtering methods are not used for real-time viewport scaling. They are only used when you manually resize an image on the CPU. See Multiple resolutions in the documentation instead, specifically stretch scale mode for pixel art games.

The default 2D texture filter is governed by the Rendering > Textures > Canvas Textures > Default Texture Filter project setting. You’ll want to set it to Nearest for most pixel art games.

3 Likes

Aw man, it only support nearest, linear and nearest/linear mipmap :confused: I wanted to use a higher quality upscaling algorithm like lanczos or FSR (at the very least, those are bare minimum).

It’s starting to look like it just plain isn’t supported in the engine (sorta unacceptable for a 2D game engine imo), I can see godot supports FSR but only for 3D (strange, FSR, at least before FSR2 is pretty much just an upscaling algorithm that can be used for 2D just as well as 3D, much like lanczos, not sure if FSR2+ are still viable for 2D but FSR is…)

I think the setting that actually would have suited my project would be this:

But if it’s just a choice between linear and bilinear (worthless and just as worthless) scaling it’s kinda pointless to mess with it.

@GorevAndrew thanks, that is good to know a way to default the image interpolation to lanczos at least is good.

I think I technically could use this but it’d be messy as fuck since i’d have to be jumping back and forth between image and imagetexture whenever something needs rescaling but I could work it that way, it’s just disappointing that I have to.

This is kinda just a basic method of futureproofing, we don’t know what resolutions people will be using 10 years from now, and also if i’m say developing a gamme with idk 1080p images, having a good upscaler helps make sure the game will still look at least mostly acceptable on up to a 4k display.

Why is this not a feature, wasn’t godot primarily a 2D engine for most of it’s lifespan? I would expect this to be a pretty basic feature in a 2D engine.

1 Like

I wouldn’t fret too much about future displays. 1080p looks pretty good when scaled to 4K using integer scaling, and it will continue to do so on 6K and 8K displays. In fact, 8K is highly versatile when it comes to integer scaling, since it can handle all current common resolutions with it: 720p (6×), 1080p (4×), 1440p (3×) and 2160p (2×).

No, Godot started its life as a 3D-only engine before adding 2D support shortly before being open sourced in 2014.

As far as I know, most 2D engines don’t provide real-time filters (other than bilinear and nearest, which are implemented on the hardware itself, unlike bicubic or FSR). FSR1 is also not designed with 2D art in mind, so using bilinear or nearest is preferred most of the time. Bicubic can work somewhat OK for HD 2D games (albeit with some ringing artifacts), but it’s really not ideal for pixel art as it breaks the intended look.

2 Likes

I could have sworn godot only added 3D in godot 3. I mean look at this Godot Engine reaches 2.0 stable – Godot Engine

There is barely any mention of 3D features… Maybe it only became an actually viable 3D engine in 3.0?

But i dug deeper, all the way back to 1.0 and it looks like it had both 2d and 3d features as far back as that.