Skip to content

Commit

Permalink
Simplify logic based on how SLAB works
Browse files Browse the repository at this point in the history
SLAB will find the near and the far intersection past the end points
of the ray. We were clamping it prior. Allow the ray to extend, but
ensure the intersection that is returned is the first in the direction
start -> end. This allows us to simplify the code a bit more as it can
automatically search the intersection towards and away from the
achromatic point based on the origin without us doing extra work.
  • Loading branch information
facelessuser committed Mar 8, 2024
1 parent 821e343 commit 4f84eb6
Showing 1 changed file with 13 additions and 15 deletions.
28 changes: 13 additions & 15 deletions apps/gamut-mapping/methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,23 +73,22 @@ const methods = {
let achroma = mapColor.clone().set("c", 0).to("p3-linear").coords;
let gamutColor = mapColor.clone().to("p3-linear");

// Create a line from our color to color with zero lightness.
// Create a line from our color to color with zero chroma.
// Trace the line to the RGB cube finding the face and the point where it intersects.
// Take two rounds to get us as close as we can get.
// Additional attempts will find the intersection using the zero chroma color
// as the origin of the ray and the new color guiding the direction.
let coords;
let intersection;
let [xa, ya, za] = achroma;
for (let i = 0; i < 3; i++) {
// On subsequent runs correct L and H before continuing and
// then extend the vector in case we are now under saturated
// On subsequent runs correct L and H before before finding the intersection.
if (i) {
gamutColor.set({"oklch.l": mapColor.coords[0], "oklch.h": mapColor.coords[2]});
let [r, g, b] = gamutColor.coords;
coords = [xa + (r - xa) * 100, ya + (g - ya) * 100, za + (b - za) * 100];
intersection = methods.raytrace.raytrace_box(achroma, gamutColor.coords);
}
else {
coords = gamutColor.coords;
intersection = methods.raytrace.raytrace_box(gamutColor.coords, achroma);
}
let intersection = methods.raytrace.raytrace_box(coords, achroma);
if (intersection.length) {
gamutColor.setAll(gamutColor.space, intersection);
continue;
Expand Down Expand Up @@ -125,12 +124,6 @@ const methods = {
const bx = bmax[i];
direction.push(d);

// Both start and end of ray are outside the box on one side.
// Can occur with some parallel cases.
if ((a < bn && b < bn) || (a > bx && b > bx)) {
return [];
}

// Non parallel cases
if (d != 0) {
const inv_d = 1 / d;
Expand All @@ -141,7 +134,7 @@ const methods = {
}

// Impossible parallel case
else if (a < bmin[0] || a > bmax[1]) {
else if (a < bn || a > bx) {
return [];
}
}
Expand All @@ -151,6 +144,11 @@ const methods = {
return [];
}

// Favor the intersection first in the direction start -> end
if (tnear < 0) {
tnear = tfar;
}

// Calculate nearest intersection via interpolation
return [
start[0] + direction[0] * tnear,
Expand Down

0 comments on commit 4f84eb6

Please sign in to comment.