godotengine / godot

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

DrawString does not work when material blend mode is PremultAlpha #73601

Open pcen opened 1 year ago

pcen commented 1 year ago

Godot version

4.0.rc2.mono

System information

MacOS Ventura 13.1, M1, Vulkan 1.2.231

Issue description

Using DrawString with a Node2D where the material blend mode is set to PremultAlpha renders text as solid rectangles instead of the expected text. This happens when the material blend mode is set from the editor, or via an attached script. With default material:

Screenshot 2023-02-19 at 4 19 46 PM

With CanvasItemMaterial, blend mode set to PremultAlpha:

Screenshot 2023-02-19 at 4 20 47 PM

Steps to reproduce

Minimal reproduction project

TestText.zip

Calinou commented 1 year ago

This is due to how premultiplied alpha rendering works. The font's pixels are always white, but its alpha value changes depending on the pixel. However, with premultiplied alpha, this will always result in white pixels being displayed, as the alpha value only determines the blend mode (0.0 = add, 1.0 = mix).

The font texture needs to be generated differently to be rendered correctly with premultiplied alpha. The problem is that doing so breaks rendering with standard alpha rendering (which Godot uses by default for all 2D rendering). The breakage is subtle, but once you start seeing it, you can't unsee it :slightly_smiling_face:

An import option in the font could work in theory, but it would break font rendering in any material that doesn't use premultiplied alpha. At this stage, this begs the question whether we should have a project setting to use premultiplied alpha in all 2D rendering by default, which would also adjust font rendering accordingly.