diff --git a/ray-tracing-material-visualizer/src/bin/iridescent.rs b/ray-tracing-material-visualizer/src/bin/iridescent.rs index 3bc8047..8aef3a2 100644 --- a/ray-tracing-material-visualizer/src/bin/iridescent.rs +++ b/ray-tracing-material-visualizer/src/bin/iridescent.rs @@ -1,17 +1,40 @@ use core::f32; -use plotters::{prelude::*, style::full_palette::GREEN}; +use plotters::{coord::Shift, prelude::*, style::full_palette::GREEN}; use rand::{rngs::SmallRng, Rng, SeedableRng}; use ray_tracing_material::iridescent::Iridescent; fn main() -> Result<(), Box> { - let root = BitMapBackend::new("iridescent_sweep.png", (800, 600)).into_drawing_area(); + let root = BitMapBackend::new("iridescent_sweep.png", (2200, 1200)).into_drawing_area(); root.fill(&WHITE)?; - let mut chart = ChartBuilder::on(&root) + + let d = root.split_evenly((3, 5)); + + let ds = [0.1, 0.3, 0.5, 0.7, 0.9]; + let deltas = [244.0, 500.0, 988.0]; + + for (i, c) in d.into_iter().enumerate() { + draw_subplot(deltas[i / 5], 1.0 - ds[i % 5], &c)?; + } + + root.present()?; + + Ok(()) +} + +fn draw_subplot( + delta: f32, + d2: f32, + c: &DrawingArea, +) -> Result<(), Box> +where + ::ErrorType: 'static, +{ + let mut chart = ChartBuilder::on(c) .margin(5) .x_label_area_size(30) .y_label_area_size(30) - .build_cartesian_2d(0f32..f32::consts::FRAC_PI_2, 0f32..1f32)?; + .build_cartesian_2d(0f32..f32::consts::FRAC_PI_2, 0f32..1.1f32)?; chart.configure_mesh().draw()?; @@ -20,7 +43,7 @@ fn main() -> Result<(), Box> { let height_per_pixel = 1.0 / (pixel_range_y.end - pixel_range_y.start) as f32; let samples = 10000; - let m = Iridescent::new(0.5 * 244.0, 0.5 * 244.0, 1.0, 1.5, 20); + let m = Iridescent::new((1.0 - d2) * delta, d2 * delta, 1.0, 1.5, 20); let mut data = Vec::new(); @@ -38,10 +61,16 @@ fn main() -> Result<(), Box> { ); s += m.monte_carlo_reflectance(theta1, &mut rng); s_wavelength += ray_tracing_core::color::Color::new( - m.averaged_reflectance(595.0, theta1), + m.averaged_reflectance(599.0, theta1), m.averaged_reflectance(556.0, theta1), m.averaged_reflectance(442.0, theta1), ); + // let theta2 = f32::asin(f32::sin(theta1) * 1.0 / 1.5); + // s_wavelength += ray_tracing_core::color::Color::new( + // m.abs_C_squared(599.0, theta1, theta2, false), + // m.abs_C_squared(556.0, theta1, theta2, false), + // m.abs_C_squared(442.0, theta1, theta2, false), + // ); } let c = s / samples as f32; @@ -49,12 +78,12 @@ fn main() -> Result<(), Box> { // data.push(c); data.push(s_wavelength / samples as f32); // dbg!(c); - for j in 0..10 { + for j in 0..20 { plotting_area .draw_pixel( ( f32::consts::FRAC_PI_2 * (i as f32 / buckets as f32), - 1.0 - (height_per_pixel * (j as f32)), + 1.1 - (height_per_pixel * (j as f32)), ), &RGBColor( (c.r() * 256.0) as u8, @@ -96,7 +125,5 @@ fn main() -> Result<(), Box> { &BLUE, ))?; - root.present()?; - Ok(()) } diff --git a/ray-tracing-material/src/iridescent.rs b/ray-tracing-material/src/iridescent.rs index 7519486..945ee16 100644 --- a/ray-tracing-material/src/iridescent.rs +++ b/ray-tracing-material/src/iridescent.rs @@ -22,26 +22,24 @@ impl Iridescent { } } - fn fresnel_reflection(&self, theta1: f32, theta2: f32, s_polaized: bool) -> f32 { + fn fresnel_reflection(n1: f32, n2: f32, theta1: f32, theta2: f32, s_polaized: bool) -> f32 { if s_polaized { - (self.n1 * theta1.cos() - self.n2 * theta2.cos()) - / (self.n1 * theta1.cos() + self.n2 * theta2.cos()) + (n1 * theta1.cos() - n2 * theta2.cos()) / (n1 * theta1.cos() + n2 * theta2.cos()) } else { - (self.n2 * theta1.cos() - self.n1 * theta2.cos()) - / (self.n2 * theta1.cos() + self.n1 * theta2.cos()) + (n2 * theta1.cos() - n1 * theta2.cos()) / (n2 * theta1.cos() + n1 * theta2.cos()) } } fn abs_r_1_squared(&self, l: f32, theta1: f32, theta2: f32, s_polaized: bool) -> f32 { - let r12 = self.fresnel_reflection(theta1, theta2, s_polaized); + let r12 = Self::fresnel_reflection(self.n1, self.n2, theta1, theta2, s_polaized); let phi = 2.0 * f32::consts::PI * self.n2 * self.d2 * theta2.cos() / l; let num_real = r12 * (1.0 - f32::cos(-2.0 * phi)); - let num_imag = r12 * (1.0 - f32::sin(-2.0 * phi)); + let num_imag = r12 * (-1.0 * f32::sin(-2.0 * phi)); let denom_real = 1.0 - r12 * r12 * f32::cos(-2.0 * phi); - let denom_imag = 1.0 - r12 * r12 * f32::sin(-2.0 * phi); + let denom_imag = 0.0 - r12 * r12 * f32::sin(-2.0 * phi); let real = (num_real * denom_real + num_imag * denom_imag) / (denom_real * denom_real + denom_imag * denom_imag); @@ -59,10 +57,10 @@ impl Iridescent { real * real + imag * imag } - fn abs_C_squared(&self, l: f32, theta1: f32, theta2: f32, s_polaized: bool) -> f32 { + pub fn abs_C_squared(&self, l: f32, theta1: f32, theta2: f32, s_polaized: bool) -> f32 { let local_abs_r_1_squared = self.abs_r_1_squared(l, theta1, theta2, s_polaized); - local_abs_r_1_squared / (local_abs_r_1_squared + 1.0) + local_abs_r_1_squared / (1.0 - local_abs_r_1_squared) } fn cos_K_Delta(&self, l: f32, theta1: f32, theta2: f32, s_polaized: bool) -> f32 {