From 8bc6b240047ec20d89d30f85959fc81119043fb8 Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Mon, 1 Aug 2022 22:04:14 -0700 Subject: [PATCH] Switch to CIE XYZ lookup tables. --- Cargo.lock | 7 +++++++ Cargo.toml | 2 +- src/color.rs | 47 ++++++++++++++++++++++++++++++++++++----------- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d8e1ef4..2d9ec2d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -127,6 +127,12 @@ dependencies = [ name = "color" version = "0.1.0" +[[package]] +name = "colorbox" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d27d55561009760957654f467735e73806f8bc2d081cc4a22e93403ecd156fc" + [[package]] name = "compact" version = "0.1.0" @@ -329,6 +335,7 @@ dependencies = [ "bvh_order", "clap", "color", + "colorbox", "compact", "copy_in_place", "crossbeam", diff --git a/Cargo.toml b/Cargo.toml index c9724c5..a97adbf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,7 +36,7 @@ rustc-serialize = "0.3" scoped_threadpool = "0.1" time = "0.1" fastapprox = "0.3" - +colorbox = "0.3" # Local crate dependencies diff --git a/src/color.rs b/src/color.rs index 9e68b70..e438609 100644 --- a/src/color.rs +++ b/src/color.rs @@ -608,21 +608,46 @@ fn xyz_to_spectrum_4(xyz: (f32, f32, f32), wavelengths: Float4) -> Float4 { /// From the paper "Simple Analytic Approximations to the CIE XYZ Color Matching /// Functions" by Wyman et al. pub fn x_1931(wavelength: f32) -> f32 { - let t1 = (wavelength - 442.0) * (if wavelength < 442.0 { 0.0624 } else { 0.0374 }); - let t2 = (wavelength - 599.8) * (if wavelength < 599.8 { 0.0264 } else { 0.0323 }); - let t3 = (wavelength - 501.1) * (if wavelength < 501.1 { 0.0490 } else { 0.0382 }); - (0.362 * fast_exp(-0.5 * t1 * t1)) + (1.056 * fast_exp(-0.5 * t2 * t2)) - - (0.065 * fast_exp(-0.5 * t3 * t3)) + use colorbox::tables::cie_1931_xyz::{MAX_WAVELENGTH, MIN_WAVELENGTH, X}; + + let norm = 1.0 / (MAX_WAVELENGTH - MIN_WAVELENGTH); + let n = (wavelength - MIN_WAVELENGTH) * norm; + + if n < 0.0 { + X[0] + } else if n > 1.0 { + *X.last().unwrap() + } else { + crate::lerp::lerp_slice(X, n) + } } pub fn y_1931(wavelength: f32) -> f32 { - let t1 = (wavelength - 568.8) * (if wavelength < 568.8 { 0.0213 } else { 0.0247 }); - let t2 = (wavelength - 530.9) * (if wavelength < 530.9 { 0.0613 } else { 0.0322 }); - (0.821 * fast_exp(-0.5 * t1 * t1)) + (0.286 * fast_exp(-0.5 * t2 * t2)) + use colorbox::tables::cie_1931_xyz::{MAX_WAVELENGTH, MIN_WAVELENGTH, Y}; + + let norm = 1.0 / (MAX_WAVELENGTH - MIN_WAVELENGTH); + let n = (wavelength - MIN_WAVELENGTH) * norm; + + if n < 0.0 { + Y[0] + } else if n > 1.0 { + *Y.last().unwrap() + } else { + crate::lerp::lerp_slice(Y, n) + } } pub fn z_1931(wavelength: f32) -> f32 { - let t1 = (wavelength - 437.0) * (if wavelength < 437.0 { 0.0845 } else { 0.0278 }); - let t2 = (wavelength - 459.0) * (if wavelength < 459.0 { 0.0385 } else { 0.0725 }); - (1.217 * fast_exp(-0.5 * t1 * t1)) + (0.681 * fast_exp(-0.5 * t2 * t2)) + use colorbox::tables::cie_1931_xyz::{MAX_WAVELENGTH, MIN_WAVELENGTH, Z}; + + let norm = 1.0 / (MAX_WAVELENGTH - MIN_WAVELENGTH); + let n = (wavelength - MIN_WAVELENGTH) * norm; + + if n < 0.0 { + Z[0] + } else if n > 1.0 { + *Z.last().unwrap() + } else { + crate::lerp::lerp_slice(Z, n) + } }