Plowing straight ahead
This commit is contained in:
parent
050698c1d0
commit
44099dffa9
14 changed files with 87 additions and 126 deletions
|
|
@ -1045,7 +1045,7 @@ const SRGB_TO_LINEAR_LUT: [Float; 256] = [
|
||||||
pub const RES: u32 = 64;
|
pub const RES: u32 = 64;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Debug, Default)]
|
#[derive(Clone, Copy, Debug, Default, PartialEq)]
|
||||||
pub struct Coeffs {
|
pub struct Coeffs {
|
||||||
pub c0: Float,
|
pub c0: Float,
|
||||||
pub c1: Float,
|
pub c1: Float,
|
||||||
|
|
@ -1099,10 +1099,10 @@ impl Mul<Float> for Coeffs {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
#[derive(Clone, Debug, PartialEq)]
|
||||||
pub struct RGBToSpectrumTable {
|
pub struct RGBToSpectrumTable {
|
||||||
pub z_nodes: Ptr<Float>,
|
pub z_nodes: GVec<Float>,
|
||||||
pub coeffs: Ptr<Coeffs>,
|
pub coeffs: GVec<Coeffs>,
|
||||||
pub n_nodes: u32,
|
pub n_nodes: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1113,7 +1113,7 @@ impl RGBToSpectrumTable {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn get_coeffs(&self, bucket: u32, z: u32, y: u32, x: u32) -> Coeffs {
|
fn get_coeffs(&self, bucket: u32, z: u32, y: u32, x: u32) -> Coeffs {
|
||||||
let offset = bucket * (RES * RES * RES) + z * (RES * RES) + y * (RES) + x;
|
let offset = bucket * (RES * RES * RES) + z * (RES * RES) + y * (RES) + x;
|
||||||
unsafe { *self.coeffs.add(offset as usize) }
|
unsafe { *self.coeffs.as_ptr().add(offset as usize) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn evaluate(&self, rgb: RGB) -> RGBSigmoidPolynomial {
|
pub fn evaluate(&self, rgb: RGB) -> RGBSigmoidPolynomial {
|
||||||
|
|
@ -1153,7 +1153,7 @@ impl RGBToSpectrumTable {
|
||||||
let x = coord_a / z;
|
let x = coord_a / z;
|
||||||
let y = coord_b / z;
|
let y = coord_b / z;
|
||||||
|
|
||||||
let z_nodes = unsafe { core::slice::from_raw_parts(self.z_nodes.as_raw(), RES as usize) };
|
let z_nodes = &self.z_nodes;
|
||||||
let zi = find_interval(RES, |i| z_nodes[i as usize] < z) as usize;
|
let zi = find_interval(RES, |i| z_nodes[i as usize] < z) as usize;
|
||||||
let dz = (z - z_nodes[zi]) / (z_nodes[zi + 1] - z_nodes[zi]);
|
let dz = (z - z_nodes[zi]) / (z_nodes[zi + 1] - z_nodes[zi]);
|
||||||
let x_float = x * (RES - 1) as Float;
|
let x_float = x * (RES - 1) as Float;
|
||||||
|
|
|
||||||
|
|
@ -18,5 +18,5 @@ pub mod textures;
|
||||||
pub mod utils;
|
pub mod utils;
|
||||||
|
|
||||||
pub use core::pbrt::*;
|
pub use core::pbrt::*;
|
||||||
pub use utils::alloc::{gbox, gvec, gvec_from_slice, gvec_with_capacity, GVec, GBox};
|
pub use utils::alloc::{gbox, gvec, gvec_from_slice, gvec_with_capacity, leak, GBox, GVec};
|
||||||
pub use utils::{Array2D, PBRTOptions, Ptr, Transform};
|
pub use utils::{Array2D, PBRTOptions, Ptr, Transform};
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ impl ColorSpaceId {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct RGBColorSpace {
|
pub struct RGBColorSpace {
|
||||||
pub r: Point2f,
|
pub r: Point2f,
|
||||||
pub g: Point2f,
|
pub g: Point2f,
|
||||||
|
|
@ -71,7 +71,7 @@ pub struct RGBColorSpace {
|
||||||
pub xyz_from_rgb: SquareMatrix3f,
|
pub xyz_from_rgb: SquareMatrix3f,
|
||||||
pub rgb_from_xyz: SquareMatrix3f,
|
pub rgb_from_xyz: SquareMatrix3f,
|
||||||
pub illuminant: Ptr<DenselySampledSpectrum>,
|
pub illuminant: Ptr<DenselySampledSpectrum>,
|
||||||
pub rgb_to_spectrum_table: RGBToSpectrumTable,
|
pub rgb_to_spectrum_table: Ptr<RGBToSpectrumTable>,
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for RGBColorSpace {}
|
unsafe impl Send for RGBColorSpace {}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
|
|
||||||
|
use crate::utils::ptr::Ptr;
|
||||||
use alloc::alloc::Global;
|
use alloc::alloc::Global;
|
||||||
use alloc::vec::Vec;
|
|
||||||
use alloc::boxed::Box;
|
use alloc::boxed::Box;
|
||||||
|
use alloc::vec::Vec;
|
||||||
use core::alloc::{AllocError, Allocator, Layout};
|
use core::alloc::{AllocError, Allocator, Layout};
|
||||||
use core::ptr::NonNull;
|
use core::ptr::NonNull;
|
||||||
|
|
||||||
|
|
@ -200,3 +201,9 @@ pub fn gvec_from_slice<T: Clone>(slice: &[T]) -> GVec<T> {
|
||||||
pub fn gbox<T>(value: T) -> GBox<T> {
|
pub fn gbox<T>(value: T) -> GBox<T> {
|
||||||
Box::new_in(value, GpuAlloc::default())
|
Box::new_in(value, GpuAlloc::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn leak<T: 'static>(val: T) -> Ptr<T> {
|
||||||
|
let b = gbox(val);
|
||||||
|
let leaked: &'static T = Box::leak(b);
|
||||||
|
Ptr::from(leaked)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -827,6 +827,12 @@ impl DigitPermutation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn compute_radical_inverse_permutations(seed: u64) -> GVec<DigitPermutation> {
|
||||||
|
let mut result = gvec();
|
||||||
|
result.extend(PRIMES.iter().map(|&base| DigitPermutation::new(base as i32, seed)));
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
pub fn scrambled_radical_inverse(base_index: u32, mut a: u64, perm: &DigitPermutation) -> Float {
|
pub fn scrambled_radical_inverse(base_index: u32, mut a: u64, perm: &DigitPermutation) -> Float {
|
||||||
let base = PRIMES[base_index as usize] as u64;
|
let base = PRIMES[base_index as usize] as u64;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ pub enum FloatTexture {
|
||||||
Mix(FloatMixTexture),
|
Mix(FloatMixTexture),
|
||||||
DirectionMix(FloatDirectionMixTexture),
|
DirectionMix(FloatDirectionMixTexture),
|
||||||
// #[device(custom = "upload_image", variant_type = "GPUFloatImageTexture")]
|
// #[device(custom = "upload_image", variant_type = "GPUFloatImageTexture")]
|
||||||
|
Scaled(FloatScaledTexture)
|
||||||
Image(FloatImageTexture),
|
Image(FloatImageTexture),
|
||||||
Bilerp(FloatBilerpTexture),
|
Bilerp(FloatBilerpTexture),
|
||||||
}
|
}
|
||||||
|
|
@ -105,6 +106,7 @@ impl FloatTexture {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
pub enum SpectrumTexture {
|
pub enum SpectrumTexture {
|
||||||
Constant(SpectrumConstantTexture),
|
Constant(SpectrumConstantTexture),
|
||||||
Checkerboard(SpectrumCheckerboardTexture),
|
Checkerboard(SpectrumCheckerboardTexture),
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::globals::get_options;
|
use crate::globals::get_options;
|
||||||
use crate::utils::math::compute_radical_inverse_permutations;
|
use shared::utils::math::compute_radical_inverse_permutations;
|
||||||
use anyhow::{Result, anyhow};
|
use anyhow::{Result, anyhow};
|
||||||
use shared::core::geometry::Point2i;
|
use shared::core::geometry::Point2i;
|
||||||
use shared::core::sampler::{HaltonSampler, MAX_HALTON_RESOLUTION, RandomizeStrategy};
|
use shared::core::sampler::{HaltonSampler, MAX_HALTON_RESOLUTION, RandomizeStrategy};
|
||||||
|
|
|
||||||
|
|
@ -258,12 +258,12 @@ impl TriQuadMesh {
|
||||||
TriangleMesh::new(
|
TriangleMesh::new(
|
||||||
render_from_object,
|
render_from_object,
|
||||||
reverse_orientation,
|
reverse_orientation,
|
||||||
self.tri_indices,
|
&self.tri_indices,
|
||||||
self.p,
|
&self.p,
|
||||||
self.n,
|
&self.n,
|
||||||
Vec::new(),
|
&Vec::new(),
|
||||||
self.uv,
|
&self.uv,
|
||||||
self.face_indices,
|
&self.face_indices,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ pub trait CreateRGBColorSpace {
|
||||||
r: Point2f,
|
r: Point2f,
|
||||||
g: Point2f,
|
g: Point2f,
|
||||||
b: Point2f,
|
b: Point2f,
|
||||||
illuminant: Arc<DenselySampledSpectrum>,
|
illuminant: &DenselySampledSpectrum,
|
||||||
rgb_to_spectrum_table: Ptr<RGBToSpectrumTable>,
|
rgb_to_spectrum_table: &RGBToSpectrumTable,
|
||||||
) -> Self;
|
) -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -22,11 +22,12 @@ impl CreateRGBColorSpace for RGBColorSpace {
|
||||||
r: Point2f,
|
r: Point2f,
|
||||||
g: Point2f,
|
g: Point2f,
|
||||||
b: Point2f,
|
b: Point2f,
|
||||||
illuminant: Arc<DenselySampledSpectrum>,
|
illuminant: &DenselySampledSpectrum,
|
||||||
rgb_to_spectrum_table: Ptr<RGBToSpectrumTable>,
|
rgb_to_spectrum_table: &RGBToSpectrumTable,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let stdspec = get_spectra_context();
|
let stdspec = get_spectra_context();
|
||||||
let illum_spectrum = Spectrum::Dense(illuminant.as_ref().clone());
|
let illum_ptr = Ptr::from(illuminant);
|
||||||
|
let illum_spectrum = Spectrum::Dense(illuminant);
|
||||||
let w_xyz: XYZ = illum_spectrum.to_xyz(&stdspec);
|
let w_xyz: XYZ = illum_spectrum.to_xyz(&stdspec);
|
||||||
let w = w_xyz.xy();
|
let w = w_xyz.xy();
|
||||||
|
|
||||||
|
|
@ -49,8 +50,8 @@ impl CreateRGBColorSpace for RGBColorSpace {
|
||||||
g,
|
g,
|
||||||
b,
|
b,
|
||||||
w,
|
w,
|
||||||
illuminant: Ptr::from(illuminant.as_ref()),
|
illuminant: illum_ptr,
|
||||||
rgb_to_spectrum_table,
|
rgb_to_spectrum_table: Ptr::from(rgb_to_spectrum_table),
|
||||||
xyz_from_rgb,
|
xyz_from_rgb,
|
||||||
rgb_from_xyz,
|
rgb_from_xyz,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use shared::Float;
|
|
||||||
use shared::core::spectrum::Spectrum;
|
use shared::core::spectrum::Spectrum;
|
||||||
use shared::spectra::cie::*;
|
use shared::spectra::cie::*;
|
||||||
use shared::spectra::{PiecewiseLinearSpectrum, DenselySampledSpectrum};
|
use shared::spectra::{DenselySampledSpectrum, PiecewiseLinearSpectrum};
|
||||||
|
use shared::{gbox, leak, Float, Ptr};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
|
|
||||||
|
|
@ -17,7 +17,7 @@ pub fn create_cie(data: &[Float]) -> DenselySampledSpectrum {
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let buffer = PiecewiseLinearSpectrum::new(lambdas, data.to_vec());
|
let buffer = PiecewiseLinearSpectrum::new(lambdas, data.to_vec());
|
||||||
let spec = Spectrum::Piecewise(buffer);
|
let spec = Spectrum::Piecewise(Ptr::from(&*buffer));
|
||||||
DenselySampledSpectrum::from_spectrum(&spec)
|
DenselySampledSpectrum::from_spectrum(&spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ pub static NAMED_SPECTRA: LazyLock<HashMap<String, Spectrum>> = LazyLock::new(||
|
||||||
macro_rules! add {
|
macro_rules! add {
|
||||||
($name:expr, $data:expr, $norm:expr) => {
|
($name:expr, $data:expr, $norm:expr) => {
|
||||||
let buffer = PiecewiseLinearSpectrum::from_interleaved($data, $norm);
|
let buffer = PiecewiseLinearSpectrum::from_interleaved($data, $norm);
|
||||||
let spectrum = Spectrum::Piecewise(buffer);
|
let spectrum = Spectrum::Piecewise(leak(buffer));
|
||||||
m.insert($name.to_string(), spectrum);
|
m.insert($name.to_string(), spectrum);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -49,7 +49,6 @@ pub static NAMED_SPECTRA: LazyLock<HashMap<String, Spectrum>> = LazyLock::new(||
|
||||||
add!("stdillum-F12", &CIE_ILLUM_F12, true);
|
add!("stdillum-F12", &CIE_ILLUM_F12, true);
|
||||||
add!("illum-acesD60", &ACES_ILLUM_D60, true);
|
add!("illum-acesD60", &ACES_ILLUM_D60, true);
|
||||||
|
|
||||||
// --- Glasses ---
|
|
||||||
add!("glass-BK7", &GLASS_BK7_ETA, false);
|
add!("glass-BK7", &GLASS_BK7_ETA, false);
|
||||||
add!("glass-BAF10", &GLASS_BAF10_ETA, false);
|
add!("glass-BAF10", &GLASS_BAF10_ETA, false);
|
||||||
add!("glass-FK51A", &GLASS_FK51A_ETA, false);
|
add!("glass-FK51A", &GLASS_FK51A_ETA, false);
|
||||||
|
|
@ -58,7 +57,6 @@ pub static NAMED_SPECTRA: LazyLock<HashMap<String, Spectrum>> = LazyLock::new(||
|
||||||
add!("glass-F10", &GLASS_SF10_ETA, false);
|
add!("glass-F10", &GLASS_SF10_ETA, false);
|
||||||
add!("glass-F11", &GLASS_SF11_ETA, false);
|
add!("glass-F11", &GLASS_SF11_ETA, false);
|
||||||
|
|
||||||
// --- Metals ---
|
|
||||||
add!("metal-Ag-eta", &AG_ETA, false);
|
add!("metal-Ag-eta", &AG_ETA, false);
|
||||||
add!("metal-Ag-k", &AG_K, false);
|
add!("metal-Ag-k", &AG_K, false);
|
||||||
add!("metal-Al-eta", &AL_ETA, false);
|
add!("metal-Al-eta", &AL_ETA, false);
|
||||||
|
|
@ -74,87 +72,70 @@ pub static NAMED_SPECTRA: LazyLock<HashMap<String, Spectrum>> = LazyLock::new(||
|
||||||
add!("metal-TiO2-eta", &TIO2_ETA, false);
|
add!("metal-TiO2-eta", &TIO2_ETA, false);
|
||||||
add!("metal-TiO2-k", &TIO2_K, false);
|
add!("metal-TiO2-k", &TIO2_K, false);
|
||||||
|
|
||||||
// --- Canon EOS 100D ---
|
|
||||||
add!("canon_eos_100d_r", &CANON_EOS_100D_R, false);
|
add!("canon_eos_100d_r", &CANON_EOS_100D_R, false);
|
||||||
add!("canon_eos_100d_g", &CANON_EOS_100D_G, false);
|
add!("canon_eos_100d_g", &CANON_EOS_100D_G, false);
|
||||||
add!("canon_eos_100d_b", &CANON_EOS_100D_B, false);
|
add!("canon_eos_100d_b", &CANON_EOS_100D_B, false);
|
||||||
|
|
||||||
// --- Canon EOS 1DX MkII ---
|
|
||||||
add!("canon_eos_1dx_mkii_r", &CANON_EOS_1DX_MKII_R, false);
|
add!("canon_eos_1dx_mkii_r", &CANON_EOS_1DX_MKII_R, false);
|
||||||
add!("canon_eos_1dx_mkii_g", &CANON_EOS_1DX_MKII_G, false);
|
add!("canon_eos_1dx_mkii_g", &CANON_EOS_1DX_MKII_G, false);
|
||||||
add!("canon_eos_1dx_mkii_b", &CANON_EOS_1DX_MKII_B, false);
|
add!("canon_eos_1dx_mkii_b", &CANON_EOS_1DX_MKII_B, false);
|
||||||
|
|
||||||
// --- Canon EOS 200D ---
|
|
||||||
add!("canon_eos_200d_r", &CANON_EOS_200D_R, false);
|
add!("canon_eos_200d_r", &CANON_EOS_200D_R, false);
|
||||||
add!("canon_eos_200d_g", &CANON_EOS_200D_G, false);
|
add!("canon_eos_200d_g", &CANON_EOS_200D_G, false);
|
||||||
add!("canon_eos_200d_b", &CANON_EOS_200D_B, false);
|
add!("canon_eos_200d_b", &CANON_EOS_200D_B, false);
|
||||||
|
|
||||||
// --- Canon EOS 200D MkII ---
|
|
||||||
add!("canon_eos_200d_mkii_r", &CANON_EOS_200D_MKII_R, false);
|
add!("canon_eos_200d_mkii_r", &CANON_EOS_200D_MKII_R, false);
|
||||||
add!("canon_eos_200d_mkii_g", &CANON_EOS_200D_MKII_G, false);
|
add!("canon_eos_200d_mkii_g", &CANON_EOS_200D_MKII_G, false);
|
||||||
add!("canon_eos_200d_mkii_b", &CANON_EOS_200D_MKII_B, false);
|
add!("canon_eos_200d_mkii_b", &CANON_EOS_200D_MKII_B, false);
|
||||||
|
|
||||||
// --- Canon EOS 5D ---
|
|
||||||
add!("canon_eos_5d_r", &CANON_EOS_5D_R, false);
|
add!("canon_eos_5d_r", &CANON_EOS_5D_R, false);
|
||||||
add!("canon_eos_5d_g", &CANON_EOS_5D_G, false);
|
add!("canon_eos_5d_g", &CANON_EOS_5D_G, false);
|
||||||
add!("canon_eos_5d_b", &CANON_EOS_5D_B, false);
|
add!("canon_eos_5d_b", &CANON_EOS_5D_B, false);
|
||||||
|
|
||||||
// --- Canon EOS 5D MkII ---
|
|
||||||
add!("canon_eos_5d_mkii_r", &CANON_EOS_5D_MKII_R, false);
|
add!("canon_eos_5d_mkii_r", &CANON_EOS_5D_MKII_R, false);
|
||||||
add!("canon_eos_5d_mkii_g", &CANON_EOS_5D_MKII_G, false);
|
add!("canon_eos_5d_mkii_g", &CANON_EOS_5D_MKII_G, false);
|
||||||
add!("canon_eos_5d_mkii_b", &CANON_EOS_5D_MKII_B, false);
|
add!("canon_eos_5d_mkii_b", &CANON_EOS_5D_MKII_B, false);
|
||||||
|
|
||||||
// --- Canon EOS 5D MkIII ---
|
|
||||||
add!("canon_eos_5d_mkiii_r", &CANON_EOS_5D_MKIII_R, false);
|
add!("canon_eos_5d_mkiii_r", &CANON_EOS_5D_MKIII_R, false);
|
||||||
add!("canon_eos_5d_mkiii_g", &CANON_EOS_5D_MKIII_G, false);
|
add!("canon_eos_5d_mkiii_g", &CANON_EOS_5D_MKIII_G, false);
|
||||||
add!("canon_eos_5d_mkiii_b", &CANON_EOS_5D_MKIII_B, false);
|
add!("canon_eos_5d_mkiii_b", &CANON_EOS_5D_MKIII_B, false);
|
||||||
|
|
||||||
// --- Canon EOS 5D MkIV ---
|
|
||||||
add!("canon_eos_5d_mkiv_r", &CANON_EOS_5D_MKIV_R, false);
|
add!("canon_eos_5d_mkiv_r", &CANON_EOS_5D_MKIV_R, false);
|
||||||
add!("canon_eos_5d_mkiv_g", &CANON_EOS_5D_MKIV_G, false);
|
add!("canon_eos_5d_mkiv_g", &CANON_EOS_5D_MKIV_G, false);
|
||||||
add!("canon_eos_5d_mkiv_b", &CANON_EOS_5D_MKIV_B, false);
|
add!("canon_eos_5d_mkiv_b", &CANON_EOS_5D_MKIV_B, false);
|
||||||
|
|
||||||
// --- Canon EOS 5DS ---
|
|
||||||
add!("canon_eos_5ds_r", &CANON_EOS_5DS_R, false);
|
add!("canon_eos_5ds_r", &CANON_EOS_5DS_R, false);
|
||||||
add!("canon_eos_5ds_g", &CANON_EOS_5DS_G, false);
|
add!("canon_eos_5ds_g", &CANON_EOS_5DS_G, false);
|
||||||
add!("canon_eos_5ds_b", &CANON_EOS_5DS_B, false);
|
add!("canon_eos_5ds_b", &CANON_EOS_5DS_B, false);
|
||||||
|
|
||||||
// --- Canon EOS M ---
|
|
||||||
add!("canon_eos_m_r", &CANON_EOS_M_R, false);
|
add!("canon_eos_m_r", &CANON_EOS_M_R, false);
|
||||||
add!("canon_eos_m_g", &CANON_EOS_M_G, false);
|
add!("canon_eos_m_g", &CANON_EOS_M_G, false);
|
||||||
add!("canon_eos_m_b", &CANON_EOS_M_B, false);
|
add!("canon_eos_m_b", &CANON_EOS_M_B, false);
|
||||||
|
|
||||||
// --- Hasselblad L1D 20C ---
|
|
||||||
add!("hasselblad_l1d_20c_r", &HASSELBLAD_L1D_20C_R, false);
|
add!("hasselblad_l1d_20c_r", &HASSELBLAD_L1D_20C_R, false);
|
||||||
add!("hasselblad_l1d_20c_g", &HASSELBLAD_L1D_20C_G, false);
|
add!("hasselblad_l1d_20c_g", &HASSELBLAD_L1D_20C_G, false);
|
||||||
add!("hasselblad_l1d_20c_b", &HASSELBLAD_L1D_20C_B, false);
|
add!("hasselblad_l1d_20c_b", &HASSELBLAD_L1D_20C_B, false);
|
||||||
|
|
||||||
// --- Nikon D810 ---
|
|
||||||
add!("nikon_d810_r", &NIKON_D810_R, false);
|
add!("nikon_d810_r", &NIKON_D810_R, false);
|
||||||
add!("nikon_d810_g", &NIKON_D810_G, false);
|
add!("nikon_d810_g", &NIKON_D810_G, false);
|
||||||
add!("nikon_d810_b", &NIKON_D810_B, false);
|
add!("nikon_d810_b", &NIKON_D810_B, false);
|
||||||
|
|
||||||
// --- Nikon D850 ---
|
|
||||||
add!("nikon_d850_r", &NIKON_D850_R, false);
|
add!("nikon_d850_r", &NIKON_D850_R, false);
|
||||||
add!("nikon_d850_g", &NIKON_D850_G, false);
|
add!("nikon_d850_g", &NIKON_D850_G, false);
|
||||||
add!("nikon_d850_b", &NIKON_D850_B, false);
|
add!("nikon_d850_b", &NIKON_D850_B, false);
|
||||||
|
|
||||||
// --- Sony ILCE 6400 ---
|
|
||||||
add!("sony_ilce_6400_r", &SONY_ILCE_6400_R, false);
|
add!("sony_ilce_6400_r", &SONY_ILCE_6400_R, false);
|
||||||
add!("sony_ilce_6400_g", &SONY_ILCE_6400_G, false);
|
add!("sony_ilce_6400_g", &SONY_ILCE_6400_G, false);
|
||||||
add!("sony_ilce_6400_b", &SONY_ILCE_6400_B, false);
|
add!("sony_ilce_6400_b", &SONY_ILCE_6400_B, false);
|
||||||
|
|
||||||
// --- Sony ILCE 7M3 ---
|
|
||||||
add!("sony_ilce_7m3_r", &SONY_ILCE_7M3_R, false);
|
add!("sony_ilce_7m3_r", &SONY_ILCE_7M3_R, false);
|
||||||
add!("sony_ilce_7m3_g", &SONY_ILCE_7M3_G, false);
|
add!("sony_ilce_7m3_g", &SONY_ILCE_7M3_G, false);
|
||||||
add!("sony_ilce_7m3_b", &SONY_ILCE_7M3_B, false);
|
add!("sony_ilce_7m3_b", &SONY_ILCE_7M3_B, false);
|
||||||
|
|
||||||
// --- Sony ILCE 7RM3 ---
|
|
||||||
add!("sony_ilce_7rm3_r", &SONY_ILCE_7RM3_R, false);
|
add!("sony_ilce_7rm3_r", &SONY_ILCE_7RM3_R, false);
|
||||||
add!("sony_ilce_7rm3_g", &SONY_ILCE_7RM3_G, false);
|
add!("sony_ilce_7rm3_g", &SONY_ILCE_7RM3_G, false);
|
||||||
add!("sony_ilce_7rm3_b", &SONY_ILCE_7RM3_B, false);
|
add!("sony_ilce_7rm3_b", &SONY_ILCE_7RM3_B, false);
|
||||||
|
|
||||||
// --- Sony ILCE 9 ---
|
|
||||||
add!("sony_ilce_9_r", &SONY_ILCE_9_R, false);
|
add!("sony_ilce_9_r", &SONY_ILCE_9_R, false);
|
||||||
add!("sony_ilce_9_g", &SONY_ILCE_9_G, false);
|
add!("sony_ilce_9_g", &SONY_ILCE_9_G, false);
|
||||||
add!("sony_ilce_9_b", &SONY_ILCE_9_B, false);
|
add!("sony_ilce_9_b", &SONY_ILCE_9_B, false);
|
||||||
|
|
|
||||||
|
|
@ -28,19 +28,16 @@ fn get_d65_illuminant_buffer() -> Arc<DenselySampledSpectrum> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cie_x() -> Spectrum {
|
pub fn cie_x() -> Spectrum {
|
||||||
Spectrum::Dense(CIE_X_DATA)
|
Spectrum::Dense(Ptr::from(&*CIE_X_DATA))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cie_y() -> Spectrum {
|
pub fn cie_y() -> Spectrum {
|
||||||
Spectrum::Dense(CIE_Y_DATA)
|
Spectrum::Dense(Ptr::from(&*CIE_Y_DATA))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cie_z() -> Spectrum {
|
pub fn cie_z() -> Spectrum {
|
||||||
Spectrum::Dense(CIE_Z_DATA)
|
Spectrum::Dense(Ptr::from(&*CIE_Z_DATA))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cie_d65() -> Spectrum {
|
pub fn cie_d65() -> Spectrum {
|
||||||
Spectrum::Dense(CIE_D65_DATA)
|
Spectrum::Dense(Ptr::from(&*CIE_D65_DATA))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_spectra_context() -> StandardSpectra {
|
pub fn get_spectra_context() -> StandardSpectra {
|
||||||
|
|
@ -52,6 +49,7 @@ pub fn get_spectra_context() -> StandardSpectra {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub static SRGB: LazyLock<Arc<RGBColorSpace>> = LazyLock::new(|| {
|
pub static SRGB: LazyLock<Arc<RGBColorSpace>> = LazyLock::new(|| {
|
||||||
let illum = get_d65_illuminant_buffer();
|
let illum = get_d65_illuminant_buffer();
|
||||||
let r = Point2f::new(0.64, 0.33);
|
let r = Point2f::new(0.64, 0.33);
|
||||||
|
|
@ -85,7 +83,7 @@ pub static ACES: LazyLock<Arc<RGBColorSpaceData>> = LazyLock::new(|| {
|
||||||
let r = Point2f::new(0.7347, 0.2653);
|
let r = Point2f::new(0.7347, 0.2653);
|
||||||
let g = Point2f::new(0.0000, 1.0000);
|
let g = Point2f::new(0.0000, 1.0000);
|
||||||
let b = Point2f::new(0.0001, -0.0770);
|
let b = Point2f::new(0.0001, -0.0770);
|
||||||
let table_ptr = Ptr::from(&ACES_TABLE.view);
|
let table_ptr = Ptr::from(&ACES_TABLE);
|
||||||
Arc::new(RGBColorSpace::new(r, g, b, illum, table_ptr))
|
Arc::new(RGBColorSpace::new(r, g, b, illum, table_ptr))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -120,10 +118,10 @@ pub fn get_colorspace_context() -> StandardColorSpaces {
|
||||||
|
|
||||||
pub fn get_colorspace_device() -> DeviceStandardColorSpaces {
|
pub fn get_colorspace_device() -> DeviceStandardColorSpaces {
|
||||||
DeviceStandardColorSpaces {
|
DeviceStandardColorSpaces {
|
||||||
srgb: Ptr::from(&*SRGB),
|
srgb: Ptr::from(&**SRGB),
|
||||||
dci_p3: Ptr::from(&*DCI_P3),
|
dci_p3: Ptr::from(&**DCI_P3),
|
||||||
rec2020: Ptr::from(&*REC2020),
|
rec2020: Ptr::from(&**REC2020),
|
||||||
aces2065_1: Ptr::from(&*ACES),
|
aces2065_1: Ptr::from(&**ACES),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,59 +0,0 @@
|
||||||
use half::f16;
|
|
||||||
use shared::utils::hash::hash_buffer;
|
|
||||||
use shared::utils::math::{permutation_element, DigitPermutation, PRIMES};
|
|
||||||
use shared::Float;
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn f16_to_f32(bits: u16) -> f32 {
|
|
||||||
#[cfg(feature = "cuda")]
|
|
||||||
{
|
|
||||||
// Use hardware intrinsic on CUDA
|
|
||||||
// Cast bits to cuda_f16, then cast to f32
|
|
||||||
let half_val = unsafe { core::mem::transmute::<u16, cuda_std::f16>(bits) };
|
|
||||||
half_val.to_f32()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(feature = "vulkan")]
|
|
||||||
{
|
|
||||||
// Use shared logic or spirv-std intrinsics if available.
|
|
||||||
// Sadly, f16 support in rust-gpu is still maturing.
|
|
||||||
// A manual bit-conversion function is often safest here.
|
|
||||||
f16_to_f32_software(bits)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(any(feature = "cuda", feature = "vulkan")))]
|
|
||||||
{
|
|
||||||
f16::from_bits(bits).to_f32()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn compute_radical_inverse_permutations(seed: u64) -> (Vec<u16>, Vec<DigitPermutation>) {
|
|
||||||
let temp_data: Vec<Vec<u16>> = PRIMES
|
|
||||||
.iter()
|
|
||||||
.map(|&base| DigitPermutation::new(base as i32, seed).permutations)
|
|
||||||
.collect();
|
|
||||||
let mut storage: Vec<u16> = Vec::with_capacity(temp_data.iter().map(|v| v.len()).sum());
|
|
||||||
|
|
||||||
for vec in &temp_data {
|
|
||||||
storage.extend_from_slice(vec);
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut views = Vec::with_capacity(PRIMES.len());
|
|
||||||
// let mut current_offset = 0;
|
|
||||||
|
|
||||||
// let storage_base_ptr = storage.as_ptr();
|
|
||||||
|
|
||||||
for (i, &base) in PRIMES.iter().enumerate() {
|
|
||||||
let len = temp_data[i].len();
|
|
||||||
let n_digits = len as u32 / base as u32;
|
|
||||||
|
|
||||||
// let ptr_to_data = storage_base_ptr.add(current_offset);
|
|
||||||
|
|
||||||
views.push(DigitPermutation::new(base as i32, n_digits as u64));
|
|
||||||
|
|
||||||
// current_offset += len;
|
|
||||||
}
|
|
||||||
|
|
||||||
(storage, views)
|
|
||||||
}
|
|
||||||
|
|
@ -28,3 +28,28 @@ pub type Arena = arena::Arena<backend::cuda::CudaAllocator>;
|
||||||
|
|
||||||
#[cfg(not(any(feature = "cuda", feature = "vulkan")))]
|
#[cfg(not(any(feature = "cuda", feature = "vulkan")))]
|
||||||
pub type Arena = arena::Arena<backend::SystemAllocator>;
|
pub type Arena = arena::Arena<backend::SystemAllocator>;
|
||||||
|
|
||||||
|
use half::f16;
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn f16_to_f32(bits: u16) -> f32 {
|
||||||
|
#[cfg(feature = "cuda")]
|
||||||
|
{
|
||||||
|
// Use hardware intrinsic on CUDA
|
||||||
|
// Cast bits to cuda_f16, then cast to f32
|
||||||
|
let half_val = unsafe { core::mem::transmute::<u16, cuda_std::f16>(bits) };
|
||||||
|
half_val.to_f32()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "vulkan")]
|
||||||
|
{
|
||||||
|
// Use shared logic or spirv-std intrinsics if available.
|
||||||
|
// Keep an eye on rust-gpu
|
||||||
|
f16_to_f32_software(bits)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(any(feature = "cuda", feature = "vulkan")))]
|
||||||
|
{
|
||||||
|
f16::from_bits(bits).to_f32()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::core::spectrum::SPECTRUM_FILE_CACHE;
|
use crate::core::spectrum::SPECTRUM_FILE_CACHE;
|
||||||
use crate::spectra::piecewise::ReadFromFile;
|
|
||||||
use crate::core::texture::{FloatTexture, SpectrumTexture};
|
use crate::core::texture::{FloatTexture, SpectrumTexture};
|
||||||
use crate::spectra::data::get_named_spectrum;
|
use crate::spectra::data::get_named_spectrum;
|
||||||
|
use crate::spectra::piecewise::ReadFromFile;
|
||||||
use crate::utils::FileLoc;
|
use crate::utils::FileLoc;
|
||||||
use anyhow::{bail, Result};
|
use anyhow::{bail, Result};
|
||||||
use shared::core::color::RGB;
|
use shared::core::color::RGB;
|
||||||
|
|
@ -655,11 +655,11 @@ impl ParameterDictionary {
|
||||||
})
|
})
|
||||||
.unzip();
|
.unzip();
|
||||||
|
|
||||||
vec![Spectrum::Piecewise(PiecewiseLinearSpectrum {
|
vec![Spectrum::Piecewise(leak(PiecewiseLinearSpectrum {
|
||||||
lambdas: lambdas.as_ptr().into(),
|
lambdas: gvec_from_slice(lambdas),
|
||||||
values: values.as_ptr().into(),
|
values: gvec_from_slice(values),
|
||||||
count: lambdas.len() as u32,
|
count: lambdas.len() as u32,
|
||||||
})]
|
}))]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn extract_file_spectrum(&self, param: &ParsedParameter) -> Vec<Spectrum> {
|
fn extract_file_spectrum(&self, param: &ParsedParameter) -> Vec<Spectrum> {
|
||||||
|
|
@ -681,18 +681,18 @@ fn read_spectrum_from_file(filename: &str) -> Result<Spectrum, String> {
|
||||||
{
|
{
|
||||||
let cache = SPECTRUM_FILE_CACHE.lock();
|
let cache = SPECTRUM_FILE_CACHE.lock();
|
||||||
if let Some(s) = cache.get(&fn_key) {
|
if let Some(s) = cache.get(&fn_key) {
|
||||||
return Ok(s.clone());
|
return Ok(*s); // Spectrum is Copy, so just copy it
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let pls = PiecewiseLinearSpectrum::read(&fn_key)
|
let pls = PiecewiseLinearSpectrum::read(&fn_key)
|
||||||
.ok_or_else(|| format!("unable to read or parse spectrum file '{}'", fn_key))?;
|
.ok_or_else(|| format!("unable to read or parse spectrum file '{}'", fn_key))?;
|
||||||
|
|
||||||
let spectrum = Spectrum::Piecewise(*pls);
|
let spectrum = Spectrum::Piecewise(leak(pls));
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut cache = SPECTRUM_FILE_CACHE.lock();
|
let mut cache = SPECTRUM_FILE_CACHE.lock();
|
||||||
cache.insert(fn_key, spectrum.clone());
|
cache.insert(fn_key, spectrum);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(spectrum)
|
Ok(spectrum)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue