godotengine / godotengine/godot
SubViewport with transparent background results in premultiplied alpha colors in viewport texture
- 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.

- 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.

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
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