-
Notifications
You must be signed in to change notification settings - Fork 4.6k
Theme: better max chroma detection for taperChroma #73625
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
Conversation
|
Size Change: -85 B (0%) Total Size: 2.54 MB
ℹ️ View Unchanged
|
| cPlanned = getCachedMaxChromaAtLH( lOut, hSeed, gamutSpace, cap ); | ||
| } | ||
|
|
||
| cPlanned = Math.min( cPlanned, cSeed ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I'm removing code that's effectively toGamut( sRGB ) with the lch.c method. We don't need to do the inGamut check, because a call to clampToGamut always follows anyway, and it will do the job.
| const cq = quantize( cap, 1e-3 ); | ||
| const lq = quantize( l, 0.05 ); | ||
| const hq = quantize( normalizeHue( h ), 10 ); | ||
| const cq = quantize( cap, 0.05 ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These quantize params will lead to a 20x36 grid for cached values. The previous step for hue was probably an oversight. The 1e-1 value leads to 0.1 step. That's 3600 steps from 0.0, 0.1, ... to 359.9, 360. Instead, we want 36 steps, 10 degrees each.
If you ever played with the oklch.com color picker, there is a 3D surface plotted:
That's exactly the surface we're calculating here. For each (L,H) point, the maximum chroma value C.
| // Let `toGamut` reduce the chroma to the gamut maximum. | ||
| const clamped = toGamut( probe, { space: gamutSpace, method: 'css' } ); | ||
|
|
||
| return get( clamped, [ OKLCH, 'c' ] ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much better method to find the max C value that's in gamut. Create a "probe" color with maximum C, and let toGamut to map it into gamut.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
aduth
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I appreciate the inline comments to help explain the changes 👍 Some of it is still over my head, but the comments help clarify the intent. A visual audit of both the code changes and visual result LGTM!
This PR is an optimization and cleanup of the
taperChromafunction. It speeds up the color ramp calculation again: my runs of the "buildRamps" unit test show an improvement from 1400ms to 800ms, almost 2x improvement.The
taperChromafunction makes some colors in the color ramp more gray than they would normally be. It's very visible especially with very vivid colors. The following image shows a ramp for pure blue (#00f). The top ramp is withtaperChroma, the lower ramp is without taper. There is big difference especially forfgSurfaceXcolors, and also forstrokeX.And this PR does several changes to
taperChroma:taperChromauses the sRGB gamut instead of P3. sRGB is where the final colors always are, so there's no point using P3.taperChromano longer does any gamut mapping (toGamut). That's a separate step happening aftertaperChroma. Previously we were doing the gamut mapping twice.toGamutCSSto clamp a color with too high chroma to an in-gamut value. You can read more details in this colorjs.io doc: https://colorjs.io/docs/gamut-mapping. The doc describes a "bad"lch.calgorithm, and that's exactly whattaperChromawas using previously. And it describes the "good" CSS algorithm, and that's what we're using now 🙂PlainColorObjecttype internally, instead of the more genericColorTypes. That's mainly becausecloneaccepts onlyPlainColorObjects.The net result is a much faster and cleaner
taperChroma, and imperceptible differences in generated colors.