godotengine / godot

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

2D WorldEnvironment Glow depends on the camera Zoom #94245

Open conde2 opened 1 month ago

conde2 commented 1 month ago

Tested versions

v4.3.beta2.mono.official [b75f0485b]

System information

Godot v4.3.beta2.mono - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3060 Ti (NVIDIA; 31.0.15.3623) - AMD Ryzen 7 3700X 8-Core Processor (16 Threads)

Issue description

When having small sprites with RAW module changed to Glow, if the camera zoom is a little far from the object no glow can be seen. It looks like a bug to me. Tried searching everywehere how to disable it, but no success.

https://github.com/user-attachments/assets/71f6333f-b31b-46bf-b48a-1b3c0e54aa4b

Steps to reproduce

Just add a a World Environment enable Glow with Additive blend mode add a sprite 2D and RAW Module to (2,2,2)

Minimal reproduction project (MRP)

new-game-project.zip

Calinou commented 1 month ago

As explained in https://github.com/godotengine/godot/issues/56452, glow on small objects is expected to disappear if far away enough from the camera. This phenomenon also occurs in 2D when the Camera2D zooms out. This was improved upon significantly in 4.2, but not much can be done to further improve this now. You could try adjusting the glow levels based on the camera zoom in a script, but this will some fiddling to get right.

You can avoid this by using premade glow sprites instead of relying on real-time glow for these objects. The glow sprite is a child of the main sprite and has a CanvasItemMaterial with its blend mode set to Add. The glow sprite is generated using an image editor such as GIMP's Filters > Blur > Gaussian Blur effect.

As a bonus, this technique is more selective and allows you to apply glow on certain sprites only. It also works in all rendering methods without requiring 2D HDR to be enabled.

It's possible to generate the glow in real-time using a sprite shader as well, but this is significantly slower. It can be worth doing for complex animated sprites (or sprites displaying a ViewportTexture), but premade sprites remain the most performant option.

Here's an example: test_glow_sprite.zip

Glow sprites

conde2 commented 1 month ago

Thanks for the clarification, there is some workarounds to this. I was just about to ask the case of animated sprites, having them separated and try to sync them seemed to be much more trouble, but you just explained it.

Also looking at the issue you mentioned, seems like other game engines are doing this automatically, maybe something can still be improved?

image

Calinou commented 1 month ago

Also looking at the issue you mentioned, seems like other game engines are doing this automatically, maybe something can still be improved?

That screenshot was taken with Godot 4.0. With Godot 4.2 and later, the situation has improved significantly since.

conde2 commented 1 month ago

I'm still experiencing the same issues as shown in the screenshot using Godot 4.3 beta3.

I also tried your suggested approach, but it has its own challenges. When using a TileSet and TileMapLayer, it's very difficult to add a CanvasItemMaterial to each individual TileSet item that I want to glow, you need 2 TileSet to do that.

Additionally, glow effects are typically used with sprites that have movement (e.g., animated sprites). Applying glow effects to a TileMapLayer seems nearly impossible. I attempted to create a simple animated fireplace with a nice glow, but I encountered significant difficulties.

Why can't the renderer draw the glow effect the same way it does when the camera is close, even when it is far away? Is there any other way to use glow without the hassle of creating it manually it to every single TileSet item?

Calinou commented 1 month ago

Why can't the renderer draw the glow effect the same way it does when the camera is close, even when it is far away?

Glow implementations work with an average of screen pixels. If a glowing region is very small, it can't be represented accurately unless you are willing to have it flicker in and out a lot (a common problem with many glow implementations). See https://github.com/godotengine/godot/pull/82353.

Adjusting the glow levels based on camera zoom is a way to have control over that, but be advised that you may see flicker when the camera moves at low zoom levels (e.g. during panning shots).

conde2 commented 1 month ago

@Calinou another problem I found is that HDR changes canvas items that are equal or below HDR treshold, maybe this is a bug, but I would like to confirm here before creating a new issue.

Calinou commented 1 month ago

another problem I found is that HDR changes canvas items that are equal or below HDR treshold, maybe this is a bug, but I would like to confirm here before creating a new issue.

This is being tracked in https://github.com/godotengine/godot/issues/80868.