upbge icon indicating copy to clipboard operation
upbge copied to clipboard

Alpha Mix Without 0...1 Clamp

Open adriansnetlis opened this issue 6 years ago • 3 comments

Currently using alpha transparency with HDR doesn't really work like I need it to do. The blending happens to colors that appear to be clamped. Basically, if you have a pixel in background with color (4.0, 4.1, 4.0) (e.g. brightly illuminated spot or kinda darkish light source) and then a new transparent pixel gets rendered on top with color (0.5, 0.4, 1.1, 0.4), then what you'd expect to get as the final pixel color is:

r = 4.0 * (1.0 - 0.4) + 0.5 * 0.4 = 2.6
g = 4.1 * (1.0 - 0.4) + 0.4 * 0.4 = 2.62
b = 4.0 * (1.0 - 0.4) + 1.1 * 0.4 = 2.84

Which would end up being still much closer to the background pixel color than foreground one since the background color is much brighter.

However, what you get instead is clamped colors:

r = 1.0 * (1.0 - 0.4) + 0.5 * 0.4 = 0.8
g = 1.0 * (1.0 - 0.4) + 0.4 * 0.4 = 0.76
b = 1.0 * (1.0 - 0.4) + 1.0 * 0.4 = 1.0

The result isn't quite realistic. The color is way too dark, dull and even isn't the expected hue (it's much bluer and closer to magenta while original color must have been bright, less saturated blue that leans toward cyan).

Would it be possible to change how this works & disable clamping for alpha?

adriansnetlis avatar Jul 15 '18 21:07 adriansnetlis

@adriansnetlis Could you provide a little example using non-normalized colors ?

panzergame avatar Jul 16 '18 20:07 panzergame

In my last test this issue appears to be gone? Somehow I am failing to replicate it (which is good), but I'll still check it.

Edit I was recalling the problem wrong. Here's the actual problem: http://pasteall.org/blend/index.php?id=50047

The transparent object itself doesn't properly behave depending on it's brightness. A sensible assumption in this scenario where object has color (10, 0, 0) and transparency of .1 as well as black background would be a color on screen equal to (1, 0, 0) since mix((0, 0, 0), (10, 0, 0), 0.1) should return (1, 0, 0). However, what we get instead is something else. It's very odd because increasing the red brightness of transparent material does increase the opacity of object seen on screen, but it's not natural linear increase. It doesn't appear to correspond with transparency correctly.

adriansnetlis avatar Jul 29 '18 16:07 adriansnetlis

Could you test in ge_color_management, I very don't like the fact that sRGB values are used for blending and even more I don't know if the blender conversion function is supposed to work with values higher than 1.

On my side I tested ge_color_management and get the expected color value of (1, 0, 0) with transparency of 0.1 and red (10, 0, 0) while rendering in linear space and the same in sRGB (which is normal following the conversion function).

panzergame avatar Sep 01 '18 17:09 panzergame