Skip to content

[css-images-4] Undefined Hue angle when interpolating from neutrals #4928

Closed

Description

@svgeesus

Edit: skip to here to see the interaction with gradient stop interpolation

Noticed by Mike Bostock in the context of D3, but applicable to the color modification functions in Color5, too:

When you interpolate two colors in HCL colorspace, if one of the colors has undefined chroma or hue, the interpolator uses the chroma or hue from the opposite color. This can sometimes result in out-of-gamut colors that cannot be displayed in RGB colorspace. You may therefore wish to use Lab colorspace instead, or to specify the chroma explicitly to disable inheritance.

There are lots of helpful examples

Activity

  1. danburzo commented on Jul 5, 2020

    @danburzo

    When interpolating a color whose hue is undefined with a color with a defined hue, it works well for the undefined hue to be considered equal to the defined one.

    A lab(L 0 0) color (equivalent to the deprecated gray() syntax) will produce lch(L 0 0). When a color authored in a different color space is converted to lch() and its chroma ends up 0, it's fair to consider its hue undefined, to enable the behavior above. However, when authored in lch() directly, a color with zero chroma (e.g. lch(50 0 0)) I guess we should honor the explicit hue?

  2. danburzo commented on Jul 14, 2020

    @danburzo

    Hmm, I haven't fully fleshed out the idea, but could we do a chroma premultiplication (for lch()) or saturation premultiplication (for hsl()) similar to an alpha premultiplication? That would make colors with a small chroma component conntribute less of their hue to the interpolation and might satisfy @tabatkins's math requirements? (Edit: on a more attentive read, @tabatkins actually suggests this approach. 🤦‍♂️)

    I'll try a demo to see if it pans out.

  3. danburzo commented on Jul 14, 2020

    @danburzo

    I've made an interactive notebook to try it out. It works surprisingly well! It handles graciously and continuously zero, and near-zero, chroma:

    Screenshot 2020-07-14 at 15 02 12

    But it's arguably not the "correct" interpolation with noticeably large chroma:

    Screenshot 2020-07-14 at 15 02 44

  4. added and removed on Jan 30, 2021
  5. changed the title [-][css-color-5] Undefined Hue angle when interpolating from neutrals[/-] [+][css-color-4] Undefined Hue angle when interpolating from neutrals[/+] on Feb 6, 2021
  6. svgeesus commented on Feb 6, 2021

    @svgeesus
    CollaboratorAuthor

    But it's arguably not the "correct" interpolation with noticeably large chroma

    That was my conclusion also. A smooth transition away from the NaN fixup works for the "almost zero chroma" case at the expense of making all the small to large chroma values result in non-perceptually-uniform hue ramps. An abrupt transition is awkward. Maybe a fast transition where the chroma is still in the "very tiny but not zero" range?

  7. svgeesus commented on Sep 3, 2021

    @svgeesus
    CollaboratorAuthor

    Currently, the spec says

    If one of the angles has the value NaN, then for interpolation, NaN is replaced by the value of the other hue angle. If both angles have the value NaN, then for interpolation, NaN is replaced by the value 0 for both angles.

    (we already have Achromatic colors converted to hue-ish spaces should treat hue as "missing", not NaN so don't focus on the specific NaN or missing)

    This avoids the area of not-really-perceptually-uniform by making the cutoff between "has a defined hue" and "achromatic" very close to the achromatic axis, so we et well defined behavior in all cases.

    Is that sufficient, or is more needed?

  8. danburzo commented on Sep 4, 2021

    @danburzo

    I think for the scope of css-color-4 that note is sufficient. (Since it appears the longer hue interpolation leaves identical angles untouched, I don't see any possible interactions between hue fixup and NaN hues).

    In the context of css-images, I assume for gradients this adjustment is made on a piecewise basis. So the #888 in linear-gradient(red, #888, green) gets red's hue on the first segment and green's hue on the second, if the interpolation happens in a cylindrical polar space.

  9. changed the title [-][css-color-4] Undefined Hue angle when interpolating from neutrals[/-] [+][css-images-4] Undefined Hue angle when interpolating from neutrals[/+] on Sep 6, 2021
  10. svgeesus commented on Sep 6, 2021

    @svgeesus
    CollaboratorAuthor

    Thanks for the confirmation regarding css color 4.

    Re-tagging to css images and leaving open, so we don't forget

  11. added a commit that references this issue on Feb 14, 2022
  12. svgeesus commented on Dec 12, 2023

    @svgeesus
    CollaboratorAuthor

    @danburzo wrote:

    In the context of css-images, I assume for gradients this adjustment is made on a piecewise basis.

    Yes, and the spec now says so explicitly.

    So the #888 in linear-gradient(red, #888, green) gets red's hue on the first segment and green's hue on the second, if the interpolation happens in a cylindrical polar space.

    I have just added that exact example to CSS Images 4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions