Open donmccurdy opened 2 weeks ago
// apply gamma to opacity to make it visually "linear"
On second thought ... maybe what was intended by the original commit was to blend in linear space? That would certainly be a valid goal! But Math.pow(opacity, 1 / 2.2)
doesn't accomplish this... it would be necessary to convert all colors from "srgb" to "srgb-linear" (using WebGPU definitions) before compositing, and then convert the drawing buffer back to "srgb" in a post-processing pass. This requires considerable care with color management throughout a codebase.
It was a long time ago, but I recall that this change represented a big visual improvement as before this opacity was extremely non-linear and visually unpredictable, and there was fairly broad agreement that this was worthwhile.
That said all your comments are on point, it is of course not a scientific approach.
It's very possible that I've misunderstood what this change does! I'm interpreting it as saying that if we draw two polygons, in this order...
... vs. ...
...we get two very different results, because 50% is converted to 73%.
It would also be reasonable to just say, "deck.gl applies a power curve to opacity, to improve ease of use." Having a toe on the curve near zero (as sRGB does) could certainly make it easier to precisely select low opacities. Ease-in or ease-in-ease-out would also work ...
Source: https://developer.mozilla.org/en-US/docs/Web/CSS/easing-function
... where the curve is mostly linear, but if it's the sRGB curve by historical accident, and no one has complained, then no need to change it. If that's accurate, I will maybe just reword the comment to clarify.
Yes... This was done a long time ago but I seem to recall things ended up very "dark" before we made this change, the effect of a certain percentage was not at all what one would have expected.
I don't think I thought through things like idempotency, i.e. how order affects the results. It definitely improved things for trivial usage but quite possibly it makes things harder in other cases.
Given how many applications may have been "visually tuned" based on the current behavior, I wouldn't change this "default" if we don't have strong reasons to, though offering an option to disable it or use more advanced corrections would of course be fine.
Ok, sounds good to me – I will just open a PR clarifying the comment then.
Thanks for surfacing this. I think it would be useful to also update the docs
Very interesting. I've wondered why opacity falls off non-linearly while animating near zero.. do you think this is related? Whatever the case, the built-in curves become very clear when applying a property transition or hubble animation.. it could be nice to be able to opt-out or be given an easing function to undo it.
Here's a quick render test sweeping opacity from 1 to 0 over ~3.33 seconds at 30 fps to create about 1000 steps. Qualitatively, the low end (from about 0.25 to 0) has a more dramatic change compared to the rest.
https://github.com/visgl/deck.gl/assets/2461547/03a07488-3097-495f-8c4d-c6ff4b4a7501
https://github.com/visgl/deck.gl/assets/2461547/4fa4094b-c923-452c-b3f3-0e30bd97ecc3
Compare this to a matching animation created in After Effects, and the result is more like what I'd expect to see:
https://github.com/visgl/deck.gl/assets/2461547/9d4d3913-e438-4af2-804e-1733073e8d42
Maybe add an opacityAdjustment
/ opacityCorrection
/ opacityEasing
prop to Layer
'gamma'
(default) - as isfalse
- no easing(number) => number
- correction / easing function
Description
I don't believe opacity should be gamma corrected. Gamma provides a (very rough) approximation of perceived linearity of lightness in RGB colors, but there's no perceptual basis for applying gamma to opacity. When using sRGB (source of the 2.2 value) the gamma is not applied to alpha channels. Possible unwanted effects:
I see this has been around for a while (https://github.com/visgl/deck.gl/commit/aa58f4f42e2b4af2215cab3e649e467b2ccac0ca) ... has it been an issue in practice? I guess if not, perhaps it's more trouble than it's worth to change now?
Related code:
https://github.com/visgl/deck.gl/blob/cccc99e5b5980914718b686b4c9d96c97055d998/modules/core/src/lib/layer.ts#L1069-L1071
Flavors
Expected Behavior
Opacity should be passed to the shader as-is, linear, without gamma correction.
Steps to Reproduce
n/a
Environment
n/a
Logs
No response