Skip to content

Commit

Permalink
feat: spectral rendering, hopefully more correct now!
Browse files Browse the repository at this point in the history
  • Loading branch information
Walther committed Oct 11, 2023
1 parent 0488870 commit 22e785f
Showing 1 changed file with 10 additions and 17 deletions.
27 changes: 10 additions & 17 deletions clovers/src/colorize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

use crate::{
color::Color,
colors::{sRGB, sRGB_Linear, XYZ_Normalized, XYZ_Tristimulus},
colors::XYZ_Tristimulus,
hitable::HitableTrait,
materials::MaterialType,
pdf::{HitablePDF, MixturePDF, PDFTrait, PDF},
ray::Ray,
scenes::Scene,
spectrum::spectrum_xyz_to_p,
Float, EPSILON_SHADOW_ACNE,
};
use rand::rngs::SmallRng;
Expand All @@ -29,36 +30,28 @@ pub fn colorize(ray: &Ray, scene: &Scene, depth: u32, max_depth: u32, rng: &mut
return scene.background_color;
};

// Spectral rendering: compute a tint based on the current ray's wavelength
// TODO: all color handling in XYZ space?
let tint: XYZ_Tristimulus = ray.wavelength.into();
let tint: XYZ_Normalized = tint.into();
let tint: sRGB_Linear = tint.into();
let tint: sRGB = tint.into();
let tint: Color = tint.into();

// Get the emitted color from the surface that we just hit
let mut emitted: Color = hit_record.material.emit(
let emitted: Color = hit_record.material.emit(
ray,
&hit_record,
hit_record.u,
hit_record.v,
hit_record.position,
);

// Tint the emitted light based on the wavelength. Emissive values do not need to be clamped, as they do not need to be energy-conserving.
emitted = emitted * tint;
let tint: XYZ_Tristimulus = ray.wavelength.into();
let tint: Color = tint.into();
let emitted = tint * emitted;

// Do we scatter?
let Some(scatter_record) = hit_record.material.scatter(ray, &hit_record, rng) else {
// No scatter, early return the emitted color only
return emitted;
};
// We have scattered, and received an attenuation from the material.
// Tint based on the wavelength. Reflective values need to be clamped to ensure the reflections are energy-conserving.
// TODO: verify correctness!
let attenuation = scatter_record.attenuation * tint;
let attenuation = attenuation.clamp();
let attenuation: XYZ_Tristimulus = scatter_record.attenuation.into();
let attenuation = attenuation * spectrum_xyz_to_p(ray.wavelength, attenuation);
let attenuation = attenuation.non_negative();
let attenuation: Color = attenuation.into();

// Check the material type and recurse accordingly:
match scatter_record.material_type {
Expand Down

0 comments on commit 22e785f

Please sign in to comment.