godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.17k stars 98 forks source link

Add a background blur property to StyleBoxFlat #3485

Open likeich opened 3 years ago

likeich commented 3 years ago

Describe the project you are working on

An Android app launcher with complex UI and multiple transparent panels that overlays other views.

Describe the problem or limitation you are having in your project

Adding and altering blur in themes is not intuitive. Blur has become extremely common in modern operating systems and apps. Some examples:

Android Screenshot_20211011-192609_One UI Home

Linux VirtualBox_Zorin-OS_26_09_2021_10_08_08-1024x576

Windows Windows-11-Action-Center-design

MacOS macbook-macos-high-sierra-launchpad-hero

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Add a "Blur" option and dropdown menu to the StyleBoxFlat. This would be similar to the current "Shadow" dropdown option. This overcomes issues with using shaders that I'll talk about below.

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

It would work in the StyleBoxFlat inspector similarly to the shadow option: a small dropdown menu that would likely include the following options:

If this enhancement will not be used often, can it be worked around with a few lines of script?

It can be worked around with a simple shader, such as this one:

shader_type canvas_item;

uniform float blur_amount : hint_range(-2.0, 10.0);
uniform float mix_amount : hint_range(0.0, 1.0);
uniform vec4 color_over : hint_color;

void fragment() {
    vec4 blurred = textureLod(SCREEN_TEXTURE, SCREEN_UV, blur_amount);
    vec4 fin = mix(blurred, color_over, mix_amount);
    COLOR = fin;
}

Source

However, as common as blur is nowadays it would make sense to include it out-of-the-box in Godot. Using the above shader works fine but you lose the benefits of the theming system (all items with blur changing at the same time, by the same amounts, etc.) when using it.

Is there a reason why this should be core and not an add-on in the asset library?

Blur is an extremely common, modern effect in apps and operating systems and the code to implement it would probably be very small while enabling users to create more modern UIs out-of-the-box in Godot. Making it a core part of StyleBoxFlat would also work well with the current theming system.

Calinou commented 3 years ago

Blurring the background is an expensive operation, and needs to be performed using a dedicated shader. There is no way for StyleBoxFlat to perform this on its own, without being assigned a custom shader.

In contrast, a shadow can be applied without a dedicated shader (even if the shadow itself is blurred). It's just a translucent black surface to be drawn without knowledge of what's behind the StyleBox.

If you want to perform full-screen blurring of the background, this can be achieved using a ColorRect node + a dedicated shader on it. In a 3D game, you don't even need a custom shader. By tweaking the WorldEnvironment Glow parameters, you can effectively get a full-screen blur that only affects 3D elements:

image

Here's the settings you need to change from the default glow settings:

YuriSizov commented 3 years ago

Just wanted to note, that adding a shader as a property of the StyleBox resources sounds like an interesting idea and it can open the door for many interesting visual effects and UI enhancements.

likeich commented 3 years ago

@Calinou thanks for the tip on the glow, I'll be looking into that.

I figured that the shadows worked through a shader already and this proposal came out of that belief. Since it doesn't, potentially StyleBoxes could have a shader property on them instead. That or some other shader+theme resource idea could be good in another proposal I think.

JoanPotatoes2021 commented 3 years ago

Some games did this by taking a screenshot of your screen when you open a menu, blurring the image and saving it as a texture to display behind the menu fading in. But a lag is expected using this method, this also works best on games that pause when you open a menu.