godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
90.92k stars 21.15k forks source link

Renderer: Visible color banding on minimal 2D scene #87894

Open Ivorforce opened 9 months ago

Ivorforce commented 9 months ago

Tested versions

System information

Godot v4.1.1.stable - macOS 13.6.0 - Vulkan (Forward+) - dedicated AMD Radeon RX 6600 XT - 11th Gen Intel(R) Core(TM) i7-11700K @ 3.60GHz (16 Threads)

Issue description

The renderer has visible color banding even on a minimal project. SCR-20240203-kkxo

The problem is the same in compatibility render mode, but notably worse when using the mobile renderer: SCR-20240203-kklq

It's especially annoying in less minimal setups, it can get very obvious in specific situations (e.g. the same but with pow(d, 16) applied, still Forward+): SCR-20240203-kpya

Maybe these are the artifacts described in the 3D limitations. I kind of doubt it because switching the tonemapper affects the bands' brightness, but not their shape. I think the artifacts may already be present before tonemapping. Enabling "debanding" doesn't help, by the way. One thing that does affect the bands' shapes is switching the final line from vec4(vec3(1.0), d) to vec4(vec3(d), 1.0). It makes the innermost shape wider, though this may also be an alpha epsilon artifact. SCR-20240203-kutl

Still, if it really is the tonemapper causing the issue, I'd suggest adding a simple "clamp" tonemapper and increasing the color precision on the HDR -> SDR downsampling. This wouldn't be great because you'd be stuck in SDR, but I don't use HDR so that would be sufficient.

Steps to reproduce

Use this shader in a 2D scene:

shader_type canvas_item;

float length_sq(vec2 v) {
    return dot(v, v);
} 

void fragment() {
    float d = length_sq(UV - 0.5) * 4.0;
    COLOR = vec4(vec3(1.0), d);
//  COLOR = vec4(vec3(1.0), pow(d, 16));
}

This is already enough to get visible bands.

Minimal reproduction project (MRP)

https://github.com/Ivorforce/Godot-Color-Banding

The project notably includes an environment for convenient switching of the tonemapper, which affects the bands' colors, but not the bands' shapes.

Calinou commented 9 months ago

Try enabling 2D HDR and Use Debanding in the Project Settings, then set the WorldEnvironment background mode to Canvas.

Ivorforce commented 9 months ago

Debanding is already enabled, and the WorldEnvironment background mode is already set to Canvas.

How do I enable 2D HDR? I've seen people set it in the "Viewport" settings but I have no such option. SCR-20240203-ocax

Calinou commented 9 months ago

How do I enable 2D HDR? I've seen people set it in the "Viewport" settings but I have no such option.

The project setting is actually called HDR 2D, so you need to type it in that order in the Filter Settings box.

Ivorforce commented 9 months ago

Ok, I upgraded to Godot 4.2 and found the setting (it did not exist in 4.1). Now, debanding does seem to help!

In the editor: SCR-20240205-tzfn

Ingame: SCR-20240205-tzho

Significantly better! It does not do anything in the editor, and can lead to visible dither artifacts, but that's far more bearable imo.

Thanks for the help! Feel free to close the issue if you do not plan on fixing the color banding in the editor. For me, it's outside the scope of what I need.

clayjohn commented 8 months ago

@Ivorforce Can you confirm that once you restart the editor the banding is gone in the editor too? There is no reason that it would behave differently than at run time.

Ivorforce commented 8 months ago

I just opened the project again. The color bands exist in the editor, but not ingame, exactly as in the images posted above. Debanding does not seem to run in the editor, for me, in this project.

You may see the same if you clone the project I posted. I updated it with the suggested settings: https://github.com/Ivorforce/Godot-Color-Banding

clayjohn commented 8 months ago

I can't reproduce the issue in 4.2.1. Opening your project there is no banding unless I switch the renderer to the mobile renderer.

If I switch to the mobile renderer I get banding, but it goes away when I enable HDR_2D. Upon enabling HDR_2D, the results also look the same in the editor and in the running game.

image

Ivorforce commented 8 months ago

I see a few color bands in your screenshot, close to the middle. Close to the center is where I get the color bands as well, in my own project. Try zooming in (a lot). Edit: I added a commit that brings the color bands right into the camera center so it's easier to discern.

djrain commented 2 months ago

Can reproduce on M1 Mac in 4.3 stable (also noticed in my own project).

forward+ with HDR and debanding. notice banding in editor only (yes I restarted it)

forward HDR

mobile with HDR and debanding

mobile HDR