godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
88.71k stars 20.12k forks source link

viewport texture using transparency is darker colour (or brighter with premult on) #88603

Open RichMakeGame opened 6 months ago

RichMakeGame commented 6 months ago

EDIT: discovered this is an issue in forward+ but apparently not in compatibility mode

Tested versions

v4.2.stable.official [46dc27791]

System information

Godot v4.2.stable - Windows 10.0.19045 - Vulkan (Forward+) - dedicated NVIDIA GeForce GTX 1650 (NVIDIA; 31.0.15.4633) - Intel(R) Core(TM) i3-10100 CPU @ 3.60GHz (8 Threads)

Issue description

I'm rendering a quad with 50% grey material, 50% opacity to a viewport texture with transparent background placing the viewport texture on a TextureRect over a ColorRect of 50% grey, the texture is a different darker grey I believe the rendered texture should blend in seamlessly to the grey background? I have tried giving the TextureRect a material with Premultiplied Alpha, which results in a lighter grey

Note: when the quad material is at 0 or 100 opacity the render texture does indeed blend in, so I don't think it's a linear colour space issue?

I did see another issue relating to viewport transparency but it was stated the premuliply setting fixed it and it does NOT in this case

thanks!

premult

Steps to reproduce

(simple version): open the example project and observe the partially transparent render texture is visible when placed over a solid color rect of exactly the same value. the upper grey square on the left is set to mix and the lower set to premultiply, both are visible against the color rect


create 2 sets of subviewport container with subviewport children, in the upper one add camera3d and position in front a meshinstance with quad, with material 50% grey, unshaded, alpha mix on, 50% transparent. make sure viewport transparency is on

in the lower subviewport add a colorrect at 50% grey, and beneath a texturerect displaying the above viewport texture. toggle the texturerect and notice a difference in value (darker) adding a material and setting it to premultiplied alpha will make it appear lighter than 50% grey instead

Minimal reproduction project (MRP)

premult_issue.zip

Calinou commented 4 months ago

This is likely a duplicate of https://github.com/godotengine/godot/issues/32615 and/or https://github.com/godotengine/godot/issues/84787.

Use a black transparent clear color in the SubViewports to prevent premultiplied alpha from acting as additive blending.

RichMakeGame commented 4 months ago

Hi, I went into the test project and made sure the camera3D and SubViewport both have an environment with clear colour of black w/ alpha 0, but it still looks the same- here's the updated file premult_issue.zip

RichMakeGame commented 3 months ago

Just to add some context here I'm working on a paint app, (which I realise is niche, but this affects anyone working with transparent render textures that need accuracy) and I am currently having to use almost twice the necessary (precious) gpu memory because I'm rendering everything twice to get colour and alpha separately, where in most cases I could be processing them together in a shader and using the results. If only viewporttextures could have pre-multiplied alpha disabled (as I think was an option in 3) or I could accurately get the colour from pre-multiplied viewporttextures. please let me know if I'm making an error in my usage and it does work

edit: I don't mean to come across as entitled I'm just passionate about this project and using godot! thanks to all Godot contributors I'm very grateful to have come this far

paint

RichMakeGame commented 2 months ago

here are the transparent grey squares on a black bg with their values shown. The camera has a tonemap set to linear- shouldn't 50% grey colour pre-multiplied with 50% transparency give 25%? ( top is mix, bottom is with pre-multiplied set in material)

greys

RichMakeGame commented 2 months ago

just out of curiosity I switched to compatibility renderer- pre-multiplied material setting works correctly! does this confirm there is a bug in forward+? compat

RichMakeGame commented 2 months ago

This test to me confirms a bug in forward+ premultiplied alpha rgb values. Using a shader that shows render texture with blend_disabled, the rgb values are precisely as expected with alpha of 1 (so linear tonemap is working fine there) - however when the alpha is 0.5 the rgb values are not halved as could be expected. for reference the compatibility renderer DOES output grey of .25 and .15 which I think is correct. premult_off