godotengine / godotengine/godot

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

Open
#99,715 10 comments 23 reactions 0 assignees View on GitHub
bug topic:gui topic:rendering
Dominant language
C++
Stars
117k
Forks
26.8k
PR merge metrics
PR metrics pending

Description

### 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 https://github.com/godotengine/godot/issues/88603 https://github.com/godotengine/godot/issues/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](https://github.com/user-attachments/assets/812c70a0-eebc-491b-809c-324392e03eee)

- 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](https://github.com/user-attachments/assets/1e5e8267-f103-4f10-b839-02ea0731404d)

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](https://docs.godotengine.org/en/stable/classes/class_viewporttexture.html#class-viewporttexture). 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](https://github.com/user-attachments/files/17922231/viewporttransparency.zip)

Contributor guide

Open the contributing guide

Research direction

Start with the attached viewporttransparency.zip reproduction and compare the transparent SubViewport texture with the directly rendered TextureRect across the listed renderers. Read the ViewportTexture documentation and SubViewportContainer behavior described in the issue, then establish the intended alpha contract and verify whether the result or documentation and default presentation need updating.

Written by the indexing model from the issue text.

Assessment

Domain
computer-graphics
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.