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

SubViewport with transparent background results in premultiplied alpha colors in viewport texture #99715

Open
lostminds opened this issue Nov 26, 2024 · 2 comments

Comments

@lostminds
Copy link

Tested versions

Reproducible in 4.3.stable

System information

Godot v4.3.stable - macOS 15.1.1 - Vulkan (Mobile)

Issue description

Using a subviewport with the transparent background option results in colors in the viewport texture being premultiplied with the blending alpha. This means semi-transparent pixels will become darker in color if rendered with a material (like the default CanvasItem material) that assumes the colors not to be premultiplied with the alpha. This is consistent across Compatibility, Mobile and Forward + renderers for me.

There are multiple other issues like #88603 #91828 that seem related, but they contain some contradictory information like the issue being exclusive to Forward+ or related to sRGB conversion, and they are marked as requiring more testing to confirm the issue. These issues could probably be consolidated into one.

Steps to reproduce

  • Add a subviewport container to your scene to display a viewport texture
  • Add subviewport in the container and set it to have transparent background
  • Add a TextureRect in the subviewport and change the modulate of it to make it semi-transparent
  • Copy the TextureRect and place in outside the subviewport container to compare
  • Observe that the two TextureRects do not look the same and the one rendered via the subviewport is darker.

Image

  • To see that the issue seems to be alpha premultiplication you can add a second TextureRect to your scene, and assign the viewport texture to it as well. Now, assign a new CanvasItem material to this texture rect, and change only its blend mode to use premultiplied alpha. Observe that the colors here seem to be correct again.

Image

In other words you can compensate for this by creating a material that uses premultiplied alpha to show your viewport texture. However, this is not very obvious, and it might suffer from precision loss if color values are multiplied back/forth using the alpha. There's also the issue with this approach that if this is fixed/changed and the viewport texture colors stop being premultiplied this fix will make the colors incorrect again.

If changing/fixing this would be considered breaking compatibility too much a more conservative option could be to add information about that the viewport texture uses premultiplied alpha for transparent background viewports to the documentation. And maybe change the material used for the default SubViewportContainer to use premultiplied alpha to show blended colors in transparent viewports correctly.

Minimal reproduction project (MRP)

viewporttransparency.zip

@SleepProgger
Copy link

Can confirm this with another example.
I have a SubViewportContainer and the inner SubViewport has its background set to transparent.
The parent of the viewport has a white background.
Drawing a white line inside the viewport results in this noticeable outline artifact:

Image

but when unpremultiplying the texture in the SubViewportContainer shader like this:

void fragment() {
	vec4 txt = texture(TEXTURE, UV);
   	vec3 unpremultiplied_rgb = txt.a > 0.0 
    	? txt.rgb / txt.a 
    	: txt.rgb;
	COLOR.rgb = unpremultiplied_rgb.rgb;
	COLOR.a = txt.a;
}

... the result is a white image without the artifacts as expected.

@RevCosmosis
Copy link

I am also having this issue on v4.2.2.stable.official [15073af]. I am handling images with a lot of intermediate transparency, so the premultiplication artifacts are easy to see.

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

4 participants