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

Screen texture alpha of transparent viewport is always 1.0 when sampled in shaders #78207

Open
Zylann opened this issue Jun 13, 2023 · 6 comments

Comments

@Zylann
Copy link
Contributor

Zylann commented Jun 13, 2023

Godot version

Godot 4.0.3, Forward+

System information

Windows 10 64 bits NVIDIA GeForce GTX 1060

Issue description

I use a transparent viewport in which I need to read all 4 components of the previously rendered frame. I do this by sampling a uniform sampler2D u_screen_texture : hint_screen_texture; in a shader.
But even though the viewport is transparent, the alpha I get from the screen texture is always 1.0. I expected the alpha component to not be cleared.

Note:
In my project, the viewport renders twice or more and never clears. The first render draws something transparent, and the second render draws something else that makes use of the screen texture.
The image I get just after the first render with viewport.get_texture().get_image() has correct alpha (I did not include that in the MRP, needs more work), but the result of the second render shows that this alpha hasn't been preserved in the screen texture.

Steps to reproduce

Render a 3D scene that would normally render transparent, and add a sprite on top with a shader that renders the screen texture. It should not show a difference, but currently it makes the environment "appear" while it should not have (and should never have been rendered to begin with, but was rendered anyways, perhaps a different problem).

image

Note: in my project I don't use 3D, but the problem is the same.

Minimal reproduction project

ScreenTextureAlpha.zip

@BastiaanOlij
Copy link
Contributor

BastiaanOlij commented Jun 14, 2023

OK, went down a rabbit hole first looking at this logic in the 3D pipeline, which works as advertised. This issue is in the 2D pipeline and looks intentional.

The offending code is in TextureStorage::render_target_copy_to_back_buffer (and presumably it's GLES3 counterpart): https://github.com/godotengine/godot/blob/master/servers/rendering/renderer_rd/storage_rd/texture_storage.cpp#L3301

	if (RendererSceneRenderRD::get_singleton()->_render_buffers_can_be_storage()) {
		copy_effects->copy_to_rect(rt->color, rt->backbuffer_mipmap0, region, false, false, false, true, true);
	} else {
		copy_effects->copy_to_fb_rect(rt->color, rt->backbuffer_fb, region, false, false, false, false, RID(), false, true);
	}

Note all the default parameters being passed so p_alpha_to_one can be set to true. I've verified setting this to false makes it work as @Zylann expects it to work.

However seeing this effort is done my conclusion is that there must be a reason to set alpha to 1, possibly so the gaussian blur logic works correctly when populating the miplevels (which are used for various effects that also use the back buffer). So fixing this may have negative flow on effects.

We'll need to investigate why alpha is removed here to ensure this is fixed in a way that we can retain our alpha values.

cc @clayjohn

@clayjohn
Copy link
Member

We probably need to add explicit support for a transparent viewport to all the screen effects. That's what we ended up doing in 3.x, but we did it after the split between 3.x and 4.x so not everything got carried over

@yulongyu
Copy link

I had the same problem, how did you solve it?

@Zylann
Copy link
Contributor Author

Zylann commented Jul 24, 2023

In this particular use case, I solved it by using 2 alternating viewports instead of a single one.

@EIREXE
Copy link
Contributor

EIREXE commented Jul 28, 2023

Do note that this behavior is completely fine when using the opengl renderer, the vulkan one is the one with the issues

@Anixias
Copy link

Anixias commented May 3, 2024

This is still an issue in v4.3.dev6.mono.official [89850d5]. I'm attempting to have a screen-reading shader applied to all embedded subwindows (so tooltips can receive the shader as well), and alpha is always 1. This means that when I apply the shader to tooltips (for example), they will end up having black corners:

Recording.2024-05-02.210727.mp4

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

7 participants