Fix semi-transparent colors appearing too bright#5824
Conversation
|
Preview available at https://egui-pr-preview.github.io/pr/5824-emilkfix-transparency-blending |
3732629 to
7abb45c
Compare
Wumpf
left a comment
There was a problem hiding this comment.
this blending in gamma space business drives me nuts, but apparently this produces the results everyone expects so great catch! 👍
|
As mentioned in one of the line comment threads I think we need to properly specify and document what Color32 stores in respect to a linear, unmultiplied rgba value: a) Or expressed differently: Do we gamma encode in linear space or in premultiplied space? If I understand your changes to For what it is worth, I think b) is the right way to go about this, as a) behaves weirdly when blending between non-opaque colors. However: From going through the egui codebase, my impression is that code pretty consistently assumes that we are doing a). This includes conversions between with Sidenote: Should Another place is the shader code, which currently directly transforms between gamma and linear encoding, but would have to be changed to transform between premult / unmult before doing any gamma transforms. Also in the shader code, the texture read (which currently happens from an sRGBA aware texture) might be affected. From a first glance the automatic conversion on the driver level works with a), but not b). Phew, sorry for the wall of text. My brain is smoking, and I concur with @Wumpf that this is driving me nuts, so please take all of it with a big pile of salt. |
c493103 to
d9b5b74
Compare
|
@karhu you are right to point that out… I'll try to make things a bit more consistent. EDIT: now the Color32 <-> Rgba conversions does the alpha unmultiply… it's not pretty, but it works. |
e0f1cec to
69a54a1
Compare
Wumpf
left a comment
There was a problem hiding this comment.
nice, feels a looot more rigorous now!
Co-authored-by: Andreas Reich <andreas@rerun.io>
Co-authored-by: Andreas Reich <andreas@rerun.io>
Without any conversion, an old saved value appears as a completely different color because it's assumed to be a gamma-premultiplied value (which it wasn't when serialized with egui < 0.32). This then lead e.g. the color picker to do wrong conversions and mess up the tint color. We now check if the session was written with the latest or an old version and fix the misinterpreted color values if needed. Note that while the values are correct after conversion, the image can still appear darker due to the blending changes in egui. Relates to: emilk/egui#5824 Relates to: emilk/egui#7311
The bug was in `Color32::from_rgba_unmultiplied` and by extension affects: * `Color32::from_rgba_unmultiplied` * `hex_color!` * `HexColor` * `ColorImage::from_rgba_unmultiplied` * All images with transparency (png, webp, …) * `Color32::from_white_alpha` The bug caused translucent colors to appear too bright. ## More Color is hard. When I started out egui I thought "linear space is objectively better, for everything!" and then I've been slowly walking that back for various reasons: * sRGB textures not available everywhere * gamma-space is more _perceptually_ even, so it makes sense to use for anti-aliasing * other applications do everything in gamma space, so that's what people expect (this PR) Similarly, pre-multiplied alpha _makes sense_ for blending colors. It also enables additive colors, which is nice. But it does complicate things. Especially when mixed with sRGB/gamma (As @karhu [points out](emilk#5824 (comment))). ## Related * Closes emilk#5751 * Closes emilk#5771 ? (probably; hard to tell without a repro) * But not emilk#5810 ## TODO * [x] I broke the RGBA u8 color picker. Fix it --------- Co-authored-by: Andreas Reich <andreas@rerun.io>
The bug was in
Color32::from_rgba_unmultipliedand by extension affects:Color32::from_rgba_unmultipliedhex_color!HexColorColorImage::from_rgba_unmultipliedColor32::from_white_alphaThe bug caused translucent colors to appear too bright.
More
Color is hard.
When I started out egui I thought "linear space is objectively better, for everything!" and then I've been slowly walking that back for various reasons:
Similarly, pre-multiplied alpha makes sense for blending colors. It also enables additive colors, which is nice. But it does complicate things. Especially when mixed with sRGB/gamma (As @karhu points out).
Related
Rgba::From<Color32>does not consider alpha #5771 ? (probably; hard to tell without a repro)TODO