Skip to content

Commit 7308b52

Browse files
authored
Feature/switch raytrace (#498)
* Switch to OkLCh chroma compression, specifically the ray trace method
1 parent 908c5ab commit 7308b52

34 files changed

Lines changed: 201 additions & 158 deletions

coloraide/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
DEF_MIX = 0.5
1414
DEF_HUE_ADJ = "shorter"
1515
DEF_INTERPOLATE = "oklab"
16-
DEF_FIT = "lch-chroma"
16+
DEF_FIT = "raytrace"
1717
DEF_HARMONY = "oklch"
1818
DEF_DELTA_E = "76"
1919
DEF_AVERAGE = 'srgb-linear'

docs/src/markdown/about/changelog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@ icon: lucide/scroll-text
55

66
## 8.0
77

8+
- **NEW**: The `raytrace` gamut mapping algorithm is now the default and performs gamut mapping in OkLCh which
9+
matches the behavior in CSS. The old approach can be used via [`lch-chroma`](https://facelessuser.github.io/coloraide/gamut/#lch-chroma).
10+
To change the default see ["override default settings](https://facelessuser.github.io/coloraide/color/#override-default-settings).
811
- **NEW**: Align interpolation approach with CSS. Only noticeable difference will be when interpolating achromatic
912
colors using the `longer` hue approach. This affects all interpolation methods except `css-linear`. `css-linear`
1013
is now deprecated because it behaves exactly like `linear`.
14+
- **NEW**: `raytrace` approach is no longer considered experimental.
1115
- **FIX**: Clamp negative inputs for `rec2100-pq` like CSS does as the PQ algorithm is not well suited to these
1216
values.
1317
- **FIX**: Fix an issue where very small rays in the `raytrace` gamut mapping can cause unexpected results.

docs/src/markdown/advanced.md

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,32 @@ opaqueness beyond the range of [0, 1]. ColorAide clamps alpha on every set.
3030

3131
### What is Supported?
3232

33-
There are four features that allow ColorAide to mimic CSS behavior. All three features can be used on demand via special
34-
parameters when using the appropriate, related functions, but if desired, they can be forced to be enabled for a `Color`
35-
class. It should be noted that while all of these are defined in the CSS spec, some may not actually be implemented at
36-
this time. The four features are as follows:
37-
38-
1. Gamut mapping with `oklch-chroma` is the current CSS recommended approach. It provides a color space with better
39-
hue preservation, but the space does become a bit more distorted at very wide gamuts and can cause sane gamut
40-
mapping to break down. Gamut mapping colors that fall within the Rec. 2020 and Display P3 range should work
41-
reasonably well.
42-
43-
3. CSS defines a concept of auto powerless handling in CSS will force hues to be interpolated as powerless if under
33+
There are three features that allow ColorAide to mimic CSS behavior. All three features can be used on demand via
34+
special parameters when using the appropriate, related functions, but if desired, they can be forced to be enabled for a
35+
`Color` class. It should be noted that while all of these are defined in the CSS spec, some may not actually be
36+
implemented at this time. The four features are as follows:
37+
38+
1. Using chroma reduction in OkLCh is the recommend CSS approach. There are multiple algorithms that are suggested in
39+
the CSS spec, and ColorAide uses the `raytrace` approach that we developed. ColorAide also offers `oklch-chroma`
40+
which uses the MINDE approach. These are the defaults for ColorAide, and while the `raytrace` approach is the
41+
default, either approach can be used, and if one approach is preferred over the other, the default approach can be
42+
changed by subclassing `Color`.
43+
44+
It should be noted that current browsers have not yet implemented these and still only clip colors, but that will
45+
likely change in the future. If you want to mimic current browsers, you can subclass `Color` by using `clip` or
46+
changing the default to `clip`.
47+
48+
There is a further change being discussed that could change the CSS recommendation to gamut map with one of the
49+
aforementioned algorithms to `rec2020`, and then clip to `rec2020`, `display-p3`, or `srgb`. It can be noted this
50+
assumes gamuts that fit inside `rec2020` which ColorAide has a number that do not. It is unlikely that ColorAide
51+
will implement an approach so highly tailored to only three gamuts, and it would be suggested to just apply
52+
`#!py color.fit('rec2020').clip('srgb')` which would do exactly what they are proposing. We will likely re-evaluate
53+
our stance if/when such a change finally makes it to the CSS spec.
54+
55+
2. CSS defines a concept of auto powerless handling in CSS will force hues to be interpolated as powerless if under
4456
certain circumstances. This usually happens when a color space's chroma/saturation components are zero. While this
4557
behavior does make general sense, and ensures that a user is always treating achromatic colors as achromatic, it
46-
cripples the user's control of how a color is interpolated.
58+
cripples the user's control of how a color is interpolated, but may be preferred depending on how you use colors.
4759

4860
ColorAide, by default, respects what the user has explicitly specified. If a user has a component set as undefined,
4961
it is treated as undefined, if it is explicitly set to a numerical value, it is treated defined. This makes
@@ -54,7 +66,7 @@ this time. The four features are as follows:
5466
With all of this said, there are times when a user may want to force powerless hues, even when not explicitly
5567
defined, in these cases ColorAide can enforce this behavior during interpolation via the `powerless` parameter.
5668

57-
4. CSS also defines the idea of carrying forward undefined values during interpolation. Essentially, if a user
69+
3. CSS also defines the idea of carrying forward undefined values during interpolation. Essentially, if a user
5870
specifies an undefined component, but interpolation is performed in a different color space, after conversion, if
5971
the two color spaces have compatible components, the undefined values will be carried forward to the like
6072
components. This means that an undefined hue in HSL would be carried forward to LCh. A red component in sRGB would
@@ -70,7 +82,18 @@ base `Color` class. All four features can be forced as enabled by default as sho
7082
from coloraide import Color as Base
7183

7284
class Color(base):
73-
FIT = 'oklch-chroma'
85+
POWERLESS = True
86+
CARRYFORWARD = True
87+
```
88+
89+
To change the gamut mapping algorithm to either current browser approach (clipping) or to use the other suggested gamut
90+
mapping algorithm, see below.
91+
92+
```py
93+
from coloraide import Color as Base
94+
95+
class Color(base):
96+
FIT = "clip" # or "oklch-chroma"
7497
POWERLESS = True
7598
CARRYFORWARD = True
7699
```

0 commit comments

Comments
 (0)