-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add color math operations (Add, Sub) and Animatable
support for cylindrical color spaces
#12617
Comments
The only way I can see this working is to consider the cylinder as being unwrapped and periodically repeating. This means that we make the hue axis span If you desire to interpolate through the repeat, you use a colour from the next period over. ie: If you want to go from Red through the entire rainbow and back to Red, you interpolate between: This brings the obvious caveats: Colours can be represented with many different hues, but this hue information is relevant for interpolation. IIRC colour-conversions do not (and likely cannot) account for this, at the very least they'd lose the period information (because it does not affect the resulting colour). You cannot use any sort of modular arithmetic to define operations on a vector space, because linear algebra tells us, that all real n-dimensional vector spaces are isomorphic to R^n (think Vec[n]), but addition with modulo isn't isomorphic to addition of real numbers. Example of how it would break down: Note: Addition mod 2pi works just fine, is commutative and associative and it has negatives and 0 and all that, the problem is with scalar multiplication, which cannot be defined in such a way as to be compatible with the modular addition and form a vector space. |
Aha, that makes sense. I think we should be able to do |
Animatable
support for cylindrical color spacesAnimatable
support for cylindrical color spaces
Apparently implementing this on |
Yes, I would agree that color math on Srgba would be useful, and not too surprising. While it's not "linear" in the mathematical sense, it has a continuity which matches user expectations in some circumstances. |
Personally not a huge fan of hue getting treated specially like this, it goes against all the other implementations of Add and Sub. Just like other channels don't/shouldn't clamp, hue shouldn't wrap. Also for this reason Add and Sub (without Mul) is not very useful, as adding two HSL colours will produce an object with a valid Hue, but most likely have some other invalid channel, the only operations that are guaranteed to work are convex combinations (on account of the gamut being a convex set in its induced geometry). |
This brings me to a question (not necesarily aimed at @viridia, just in general), what do we mean when we say that a colour space is "linear". When I talk about linear spaces, it means that we endow it with an Euclidean geometry which is backed by a vector space, which has certain linearity requirements on its operations (This then lets us do things like draw lines or splines in this space). Technical Note: We don't even endow it with an entire euclidean geometry, only make it an affine space, the distinction is that euclidean geometry takes place in an affine space, but also has measurements of lengths and angles. (And these measurements follow Euclid's axioms.) |
This has finally made me see the merits of the
|
# Objective - Implements maths and `Animatable` for `Srgba` as suggested [here](#12617 (comment)). ## Solution - Implements `Animatable` and maths for `Srgba` just like their implemented for other colors. --- ## Changelog - Updated the example to mention `Srgba`. ## Migration Guide - The previously existing implementation of mul/div for `Srgba` did not modify `alpha` but these operations do modify `alpha` now. Users need to be aware of this change.
@alice-i-cecile Can we consider this "done"? |
I'd still like to try the ColorVec approach for Hsla and similar. |
Looked into this a bit more and changed my mind. There's no reason to do algebra in a cylindrical model of a space when you have a linear model of the same space available. I think we can close this. |
What problem does this solve or what need does it fill?
Many of our existing color spaces have a robust set of operations that can be used for blending, animating and otherwise mixing colors:
Mix
trait.Point
trait, for interop with the splines inbevy_math
.Animatable
, for interop withbevy_animation
.However, this is only currently done for "straightforwardly linear" color spaces. Some (like
Srgba
) are neither perceptually nor physically linear, and therefore are simply not a good choice to interpolate through.But others, like
Hsla
,Hsva
orLcha
have a different problem: their "hue" parameter loops around on itself. Rather than representing the space of colors as a straighforward "cube", with three independent orthogonal linear axes, the third axis behaves like an angle. For this reason, they are called "cylindrical color spaces": the hue parameter acts as a polar coordinate.We should be able to define an intuitive set of linear operations over this space: it's simply trickier and will require the use of the
.rem_euclid
family of methods to perform modular arithmetic on floats.Interpolating colors in these spaces is a nice quality of life feature (as they're often quite intuitive to work in and are exported by a wide range of art software). But it also provides new functionality for users: being able to interpolate between orange and purple the "short way around" (through red), rather than the "long way around" (through green).
What solution would you like?
For each of the cylindrical color spaces, implement:
and f32 multiplication.ThePoint
trait frombevy_math
, to enable use with splines.Animatable
trait, to enable color blending via animation graphs.EDIT: As noted below, we cannot implement float multiplication in a reasonable way on these types, and so cannot use splines.
Be sure to add tests to ensure that the appropriate properties of addition, subtraction and multiplication behave as you might expect in a linear space.
After that PR, the only color types that don't implement these would be
Srgba
(really terrible to interpolate through) and the universal enumColor
(very implicit as to which color space is used).What alternative(s) have you considered?
Convert to a flat linear color space before interpolating. This won't always give you the behavior you want though: being able to cycle around the red -> purple edge of the hues is a reasonable artistic choice that is not easily done in the existing flat color spaces, even if it's not particularly physical.
We could also implement these traits for
Srgba
(please, separate PR) and simply warn users that this is a probably a bad idea in the docs.Additional context
This is a follow-up to #12202, and was split out to reduce controversy.
The text was updated successfully, but these errors were encountered: