Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Window transparency enabled + a hidden screen-reading shader over a Camera3D makes the game window semi-transparent #83939

Open
anti-matt-er opened this issue Oct 25, 2023 · 5 comments

Comments

@anti-matt-er
Copy link

Godot version

v4.1.2.stable.official [399c9dc], v4.2.beta3.official [e8d57af], Forward+

System information

Godot v4.2.beta3 - Windows 10.0.19044 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3060 (NVIDIA; 31.0.15.3699) - Intel(R) Core(TM) i5-7600K CPU @ 3.80GHz (4 Threads)

Issue description

There seems to be a bug with sampling the screen texture when:

  1. Window transparency is enabled
  2. A canvas item that has a material with a screen-reading shader is hidden, i.e. this node's visibility is false
  3. The scene is 3D
  4. Only in Forward+

It only seems to happen when all of these are true.

transparency_bug

A workaround is to keep the node visible and instead set the alpha of its modulate to 0

I think #78207 could be related, but I haven't found any other issue with this problem

Steps to reproduce

  1. Start a project in Forward+
  2. Enable Window Transparency in the project settings (display/window/size/transparent, and other settings related to transparency do not seem to affect this issue)
  3. Add a ColorRect covering the screen, add a ShaderMaterial to it with the following shader:
shader_type canvas_item;

uniform sampler2D screen_texture : hint_screen_texture;

void fragment() {
    COLOR = texture(screen_texture, SCREEN_UV);
}
  1. Hide this node
  2. Add a Camera3D to the scene

Minimal reproduction project

Transparency Bug Minimal Repro.zip

@anti-matt-er
Copy link
Author

transparency_bug2

This screenshot may be a better indication of what I mean. This entire 3D scene is rendered semi-translucent due to this issue (looks like additive blending?), the expectation is that all of this should be opaque.

Note that I don't have any other of the "required" settings for a transparent window, like "per pixel transparency" (as per the docs: "For the background to be transparent, the root viewport must also be made transparent by enabling rendering/viewport/transparent_background." and "Note: This setting has no effect if display/window/per_pixel_transparency/allowed is set to false."), and I had only enabled the transparent window for the sake of having a transparent splash screen.

@Calinou
Copy link
Member

Calinou commented Oct 25, 2023

This is due to the alpha channel being set to 0.0, which means additive blending is used (because transparent windows use premultiplied alpha).

and I had only enabled the transparent window for the sake of having a transparent splash screen.

You should be able to turn off window transparency in DisplayServer after starting the project. We should probably add a specific project setting that enables transparency only during the splash screen phase.

@anti-matt-er
Copy link
Author

anti-matt-er commented Oct 28, 2023

Thanks for your response Calinou :)

This is due to the alpha channel being set to 0.0, which means additive blending is used (because transparent windows use premultiplied alpha).

This happens even when I manually do COLOR.a = 1.0, unless you mean visibility being false sets alpha to 0.0 behind the scenes?

You should be able to turn off window transparency in DisplayServer after starting the project. We should probably add a specific project setting that enables transparency only during the splash screen phase.

I actually tried several ways of doing this to no avail, iirc this is everything I tried:

get_window().transparent = false
get_window().transparent_bg = false
get_viewport().transparent_bg = false
DisplayServer.window_set_flag(DisplayServer.WINDOW_FLAG_TRANSPARENT, false)
ProjectSettings.set_setting("display/window/size/transparent", false)

I'm guessing the last line does nothing anyway, and that's one of those settings that gets read only on startup? But it's there for good measure I guess.

(I've tried waiting for both get_tree().process_frame and RenderingServer.frame_post_draw before doing this, just in case, and even manually triggering it after a long delay - all to no avail)

Is there another way that I'm missing?

@droqen
Copy link

droqen commented Feb 9, 2024

I have run into the same problem when attempting to enable Subsurface Scattering or DOF Blur; without these options enabled, transparency works as expected, but once either one is enabled, the problem reappears.

Perhaps not coincidentally, both of these options are only available in the Forward+ renderer, which leads me to suspect that the issue has something to do with Forward+ renderer being enabled/used, at the same time as window transparency.

Could someone who knows the renderer better than me speak to whether that even makes sense? When in Forward+ renderer mode, are parts of the renderer 'disabled' until a feature is used?

Alternative version of step 3 to reproduce the problem: enable Subsurface Scattering on any mesh, or DOF Blur on your camera's attributes.

@kitbdev
Copy link
Contributor

kitbdev commented Aug 1, 2024

  • Looks like it is fixed in master since v4.3.dev3, except for a moment when it starts.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants