Leave the profile's look table off by default
Every raw rendered through a camera profile — the library's DNGs with an embedded profile, and CR2s given one — now renders differently: more colourful in near-neutral tones. The profile's look table is no longer applied unless its slider is raised; PROFILE_LOOK names the strength the profile states. Against the photographer's earlier exports with no look applied, the default rendering scores the same with the look table at 100, 50 or 0 (held-out MSE 140, 140, 143), and is 9 % more colourful at 0: the table lowers the saturation of near-neutral tones, which is exactly where the default rendering was short of those exports. The user chose more colour.
This commit is contained in:
@@ -18,7 +18,7 @@ use dr_decode::{CfaPattern, CropRect, RawImage};
|
||||
use dr_gpu::{AdjustPass, Demosaicer, GpuContext};
|
||||
use dr_pipeline::descriptor::{Attribute, LocalizedKey, OpDescriptor, OpId, ParamId};
|
||||
use dr_pipeline::operation::{Operation, Stage, Uniform};
|
||||
use dr_pipeline::ops::camera_profile::{apply_reference, CameraProfile, APPLY, LOOK};
|
||||
use dr_pipeline::ops::camera_profile::{apply_reference, CameraProfile, APPLY, LOOK, PROFILE_LOOK};
|
||||
use dr_types::{HueSatTable, ProfileOrigin, ProfileTables, Transfer};
|
||||
|
||||
const SIZE: u32 = 16;
|
||||
@@ -151,6 +151,14 @@ fn render(ctx: &GpuContext, raw: &RawImage, op: CameraProfile) -> Vec<[u8; 3]> {
|
||||
pixels.chunks_exact(4).map(|p| [p[0], p[1], p[2]]).collect()
|
||||
}
|
||||
|
||||
/// The profile at the strength it states — the look table on, as the
|
||||
/// reference applies it at 1.0. Not the default, which leaves it off (D21).
|
||||
fn as_stated() -> CameraProfile {
|
||||
let mut op = CameraProfile::new();
|
||||
op.set_param(LOOK, PROFILE_LOOK);
|
||||
op
|
||||
}
|
||||
|
||||
fn encode(c: [f32; 3]) -> [i32; 3] {
|
||||
c.map(|v| (Transfer::Srgb.encode(v.clamp(0.0, 1.0)) * 255.0).round() as i32)
|
||||
}
|
||||
@@ -183,8 +191,12 @@ fn the_shader_agrees_with_the_cpu_reference() {
|
||||
return;
|
||||
};
|
||||
let tables = strong_tables();
|
||||
let got = render(&ctx, &frame(Some(tables.clone())), CameraProfile::new());
|
||||
assert_agrees(&got, |c| apply_reference(&tables, c, 1.0), "at defaults");
|
||||
let got = render(&ctx, &frame(Some(tables.clone())), as_stated());
|
||||
assert_agrees(
|
||||
&got,
|
||||
|c| apply_reference(&tables, c, 1.0),
|
||||
"as the profile states it",
|
||||
);
|
||||
|
||||
let mut doubled = CameraProfile::new();
|
||||
doubled.set_param(LOOK, 200.0);
|
||||
@@ -279,7 +291,7 @@ fn the_libraries_adobe_standard_renders_as_the_reference_does() {
|
||||
let tables = dr_decode::dcp::embedded_in(&bytes)
|
||||
.expect("Adobe Standard")
|
||||
.tables(5000.0, ProfileOrigin::Embedded);
|
||||
let got = render(&ctx, &frame(Some(tables.clone())), CameraProfile::new());
|
||||
let got = render(&ctx, &frame(Some(tables.clone())), as_stated());
|
||||
for (i, (c, g)) in colours().into_iter().zip(&got).enumerate() {
|
||||
let want = encode(apply_reference(&tables, c, 1.0));
|
||||
let g = g.map(i32::from);
|
||||
|
||||
@@ -47,9 +47,18 @@ pub const LOOK: ParamId = ParamId("look");
|
||||
|
||||
/// The look's strength at which the LookTable is applied as the profile
|
||||
/// states it, in percent.
|
||||
pub const DEFAULT_LOOK: f32 = 100.0;
|
||||
pub const PROFILE_LOOK: f32 = 100.0;
|
||||
/// The look's default strength: off.
|
||||
///
|
||||
/// Measured, not chosen. Against the photographer's earlier exports with no
|
||||
/// look applied, the default rendering scores the same with the table at 100,
|
||||
/// 50 or 0 (held-out MSE 140, 140, 143), and is 9 % more colourful without
|
||||
/// it: the table desaturates near-neutral tones, which is exactly where the
|
||||
/// default rendering was short of those exports. The table stays one slider
|
||||
/// away for anyone who wants the profile's look.
|
||||
pub const DEFAULT_LOOK: f32 = 0.0;
|
||||
/// Twice the profile's look.
|
||||
pub const MAX_LOOK: f32 = 200.0;
|
||||
pub const MAX_LOOK: f32 = 2.0 * PROFILE_LOOK;
|
||||
|
||||
/// Entries of the buffer's header, before the entries themselves: one
|
||||
/// `vec4` describing each table — `(hue divisions, saturation divisions,
|
||||
|
||||
@@ -2801,7 +2801,7 @@ curve a power of 1.5/1.4 about grey (`REFERENCE_CONTRAST` is where the curve is
|
||||
brightness needs nothing: baseline exposure and the curve together land where the earlier exports do. The
|
||||
profile's look strength, vibrance and saturation bought nothing measurable on those exports. The
|
||||
user chose to change every photograph rather than keep edited ones on the old rendering. The
|
||||
fitting tools live outside the repository (`darkroom-lrfit`).
|
||||
fitting tools live outside the repository (`darkroom-lrfit`). *Amended 2026-10-04:* the look strength now defaults to 0. It scored the same at 100, 50 and 0 (held-out MSE 140, 140, 143) and the rendering is 9 % more colourful without it — the table desaturates near-neutral tones, where the default was short of those exports; the user chose more colour.
|
||||
|
||||
*Amended earlier the same day:* the default was **not** decided. The measurement below was against
|
||||
Lightroom previews of photographs carrying the user's Lightroom edits — a house look of HSL
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user