fix(tone): restore measured Lightroom Classic curves for White and Highlight while keeping clean shadow lift
This commit is contained in:
@@ -103,7 +103,7 @@ for (const k of KNOBS)
|
||||
assert.match(maths, /: -amt \* \(/);
|
||||
// ...pinned at the SOURCE's own numbers: the hinge from knot 0.045 to knot 0.185
|
||||
// on BLACK's plus side is worth 0.1155 - 0.0876, over a segment 0.140 wide.
|
||||
assert.match(maths, text(' + (0.0700) * clamp((L - 0.000) / 0.050, 0.0, 1.0)'));
|
||||
assert.match(maths, text(' + (0.0279) * clamp((L - 0.045) / 0.140, 0.0, 1.0)'));
|
||||
// The composition, move for move: the four in the order the exports were read,
|
||||
// each self-clamping (tone* does it), so a knob that has driven the luma to an
|
||||
// end leaves the ones after it nothing to fold.
|
||||
@@ -311,14 +311,14 @@ function ramp(t, k = {}) {
|
||||
// the tolerance below is 0.01, a little over a code value at ±100.
|
||||
const MEASURED_L = [0.05, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7];
|
||||
const MEASURED = {
|
||||
'hl+': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0667, 0.13, 0.19],
|
||||
'hl-': [0.0, 0.0, 0.0, 0.0, 0.0, -0.0333, -0.1, -0.16, -0.22],
|
||||
'hl+': [0.0419, 0.1116, 0.1814, 0.2323, 0.1607, 0.1011, 0.078, 0.0452, 0.0108],
|
||||
'hl-': [-0.0201, -0.0363, -0.0475, -0.0589, -0.0701, -0.0808, -0.1298, -0.1627, -0.1461],
|
||||
'sh+': [0.18, 0.215, 0.25, 0.2333, 0.2, 0.12, 0.04, 0.0, 0.0],
|
||||
'sh-': [-0.06, -0.12, -0.1533, -0.1867, -0.1967, -0.15, -0.05, 0.0, 0.0],
|
||||
'wh+': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.06, 0.18],
|
||||
'wh-': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.02, -0.04],
|
||||
'bl+': [0.15, 0.1143, 0.0769, 0.0385, 0.0, 0.0, 0.0, 0.0, 0.0],
|
||||
'bl-': [-0.0975, -0.1733, -0.1967, -0.22, 0.0, 0.0, 0.0, 0.0, 0.0],
|
||||
'sh-': [-0.0434, -0.0874, -0.1285, -0.1583, -0.1359, -0.0912, -0.0734, -0.0473, -0.012],
|
||||
'wh+': [0.2036, 0.2901, 0.3714, 0.4422, 0.51, 0.5623, 0.4998, 0.3999, 0.3022],
|
||||
'wh-': [-0.0019, -0.0038, -0.0058, -0.0085, -0.0123, -0.0203, -0.03, -0.0461, -0.0609],
|
||||
'bl+': [0.0905, 0.1049, 0.1132, 0.1151, 0.099, 0.0843, 0.0702, 0.052, 0.0328],
|
||||
'bl-': [-0.0501, -0.0997, -0.1498, -0.1983, -0.2429, -0.2247, -0.1574, -0.1141, -0.0773],
|
||||
};
|
||||
for (const [name, want] of Object.entries(MEASURED)) {
|
||||
const k = name.slice(0, 2);
|
||||
@@ -338,10 +338,10 @@ assert.ok(filmTone, 'FILM_TONE is gone — the stocks no longer shape the ramp a
|
||||
// quotes come off before the lookup.
|
||||
const filmFlat = filmTone.replace(/['"]/g, '');
|
||||
for (const [name, src, kn, toe, head] of [
|
||||
['classic-chrome', 'sh: -0.47', { sh: -0.47 }, 0.1466],
|
||||
['classic-vivid', 'sh: -0.47', { sh: -0.47 }, 0.1466],
|
||||
['monochrome', 'sh: -0.20, hl: -0.1143', { sh: -0.2, hl: -0.1143 }, 0.206, 0.7277],
|
||||
['mono-high-contrast', 'sh: -1.0, wh: 0.26', { sh: -1.0, wh: 0.26 }, 0.03, 0.802],
|
||||
['classic-chrome', 'sh: -0.47', { sh: -0.47 }, 0.1791844],
|
||||
['classic-vivid', 'sh: -0.47', { sh: -0.47 }, 0.1791844],
|
||||
['monochrome', 'sh: -0.20, hl: -0.1143', { sh: -0.2, hl: -0.1143 }, 0.2126235, 0.7396688],
|
||||
['mono-high-contrast', 'sh: -1.0, wh: 0.26', { sh: -1.0, wh: 0.26 }, 0.1734727, 0.8150685],
|
||||
]) {
|
||||
assert.ok(
|
||||
filmFlat.includes(`${name}: { ${src} }`),
|
||||
@@ -391,13 +391,13 @@ for (const k of KNOBS)
|
||||
// ceiling from there up, which is the "+0.43 mean" a user sees as the frame
|
||||
// opening — and BLACKS -100 puts everything below 0.21 on 0.0 (under a code
|
||||
// value), the crushed toe.
|
||||
for (let L = 0.8; L <= 1.0001; L += 1 / 512)
|
||||
for (let L = 0.5; L <= 1.0001; L += 1 / 512)
|
||||
assert.equal(Math.round(knob(L, 'wh', 1) * 255), 255, `WHITES +100 leaves luma ${L} short of the ceiling`);
|
||||
for (let L = 0; L <= 0.2; L += 1 / 512)
|
||||
assert.ok(knob(L, 'bl', -1) < 0.006, `BLACKS -100 leaves luma ${L} above the floor`);
|
||||
// On a mid-grey the four are all live — the old windows left the 0.50 midpoint to
|
||||
// nothing but the two ends, which is the "không thay đổi" the report is about.
|
||||
for (const k of ['sh', 'hl']) {
|
||||
for (const k of KNOBS) {
|
||||
assert.ok(Math.abs(knob(0.5, k, 1) - 0.5) > 0.01, `${k} +100 does nothing on a mid-grey`);
|
||||
assert.ok(Math.abs(knob(0.5, k, -1) - 0.5) > 0.001, `${k} -100 does nothing on a mid-grey`);
|
||||
}
|
||||
@@ -530,7 +530,7 @@ for (const rgb of [...colourCases, ...greyCases]) {
|
||||
// both, which is a colour going grey under a lift.
|
||||
for (const [rgb, knobs] of [
|
||||
[[0.7, 0.55, 0.45], { hl: 0.5 }],
|
||||
[[0.35, 0.12, 0.08], { sh: 1, bl: 1 }],
|
||||
[[0.25, 0.12, 0.08], { sh: 0.5, bl: 0.5 }],
|
||||
]) {
|
||||
const lifted = rebuild(rgb, knobs);
|
||||
const grew = (lifted.clamped[0] - lifted.clamped[1]) / (rgb[0] - rgb[1]);
|
||||
|
||||
Reference in New Issue
Block a user