facelessuser / coloraide

A library to aid in using colors
https://facelessuser.github.io/coloraide
MIT License
201 stars 12 forks source link

Correct negative saturation in HSL #380

Closed facelessuser closed 11 months ago

facelessuser commented 11 months ago

The HSL algorithm can, at times, return a negative saturation. When this occurs, the hue is rotated by 180˚ from what it actually is. This can easily be corrected simply by taking the absolute value of the negative saturation and rotating the hue by 180˚. We were able to run this on 363,630 conversion cases that caused negative saturation, and each time we were still able to successfully convert back to the original non-HSL color with a perfect round trip.

It should be noted that this logic does not translate to all color spaces like this, HSI, Oklch, Okhsv, and Cubehelix cannot convert back to the original color when saturation is negative, and correcting the saturation just gives different wrong results. At least for HSL, no negative side effects are seen. HSV doesn't seem to produce negative saturations. At most, HSV can sometimes produce extremely small negative values very close to zero. These are just floating point errors when converting some colors that are nearly black.

Currently, for consistency, we are evaluating the clamping of negative saturation for such colors as what we do with LCh colors. HSL and HSV can be modified to never return negative saturation and keep their round trip conversions, and the other cylindrical RGB spaces seem to completely break when they have negative saturation, so such results are basically worthless.

We really just need to fully evaluate these RGB cylindrical spaces, and if there is no useful benefit, we can just clamp the negative saturations.

facelessuser commented 11 months ago

A correction, saturation correction helps all the sRGB cylindrical spaces. It's a negative lightness that can still cause bad values for some, but there may not be anything that can be done there.

facelessuser commented 11 months ago

I think right now, we won't do this. Generally, it seems like it works fine for HSL and HSV, but I hesitate to change the results from what people may expect. While it seems to work on things like HSI as well, it does not work the same for things like CAM16, the algorithm simply does not calculate chroma and hue the same way, and though conceptually, one would assume it would work the same, mathematically it does not work for CAM16.