Fix iridescent material
This commit is contained in:
parent
543bf7e1bf
commit
b1351747b7
2 changed files with 45 additions and 20 deletions
|
|
@ -1,17 +1,40 @@
|
||||||
use core::f32;
|
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 rand::{rngs::SmallRng, Rng, SeedableRng};
|
||||||
use ray_tracing_material::iridescent::Iridescent;
|
use ray_tracing_material::iridescent::Iridescent;
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
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)?;
|
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<DB: DrawingBackend>(
|
||||||
|
delta: f32,
|
||||||
|
d2: f32,
|
||||||
|
c: &DrawingArea<DB, Shift>,
|
||||||
|
) -> Result<(), Box<dyn std::error::Error>>
|
||||||
|
where
|
||||||
|
<DB as plotters::prelude::DrawingBackend>::ErrorType: 'static,
|
||||||
|
{
|
||||||
|
let mut chart = ChartBuilder::on(c)
|
||||||
.margin(5)
|
.margin(5)
|
||||||
.x_label_area_size(30)
|
.x_label_area_size(30)
|
||||||
.y_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()?;
|
chart.configure_mesh().draw()?;
|
||||||
|
|
||||||
|
|
@ -20,7 +43,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let height_per_pixel = 1.0 / (pixel_range_y.end - pixel_range_y.start) as f32;
|
let height_per_pixel = 1.0 / (pixel_range_y.end - pixel_range_y.start) as f32;
|
||||||
let samples = 10000;
|
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();
|
let mut data = Vec::new();
|
||||||
|
|
||||||
|
|
@ -38,10 +61,16 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
);
|
);
|
||||||
s += m.monte_carlo_reflectance(theta1, &mut rng);
|
s += m.monte_carlo_reflectance(theta1, &mut rng);
|
||||||
s_wavelength += ray_tracing_core::color::Color::new(
|
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(556.0, theta1),
|
||||||
m.averaged_reflectance(442.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;
|
let c = s / samples as f32;
|
||||||
|
|
@ -49,12 +78,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
// data.push(c);
|
// data.push(c);
|
||||||
data.push(s_wavelength / samples as f32);
|
data.push(s_wavelength / samples as f32);
|
||||||
// dbg!(c);
|
// dbg!(c);
|
||||||
for j in 0..10 {
|
for j in 0..20 {
|
||||||
plotting_area
|
plotting_area
|
||||||
.draw_pixel(
|
.draw_pixel(
|
||||||
(
|
(
|
||||||
f32::consts::FRAC_PI_2 * (i as f32 / buckets as f32),
|
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(
|
&RGBColor(
|
||||||
(c.r() * 256.0) as u8,
|
(c.r() * 256.0) as u8,
|
||||||
|
|
@ -96,7 +125,5 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
&BLUE,
|
&BLUE,
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
root.present()?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
if s_polaized {
|
||||||
(self.n1 * theta1.cos() - self.n2 * theta2.cos())
|
(n1 * theta1.cos() - n2 * theta2.cos()) / (n1 * theta1.cos() + n2 * theta2.cos())
|
||||||
/ (self.n1 * theta1.cos() + self.n2 * theta2.cos())
|
|
||||||
} else {
|
} else {
|
||||||
(self.n2 * theta1.cos() - self.n1 * theta2.cos())
|
(n2 * theta1.cos() - n1 * theta2.cos()) / (n2 * theta1.cos() + n1 * theta2.cos())
|
||||||
/ (self.n2 * theta1.cos() + self.n1 * theta2.cos())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn abs_r_1_squared(&self, l: f32, theta1: f32, theta2: f32, s_polaized: bool) -> f32 {
|
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 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_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_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)
|
let real = (num_real * denom_real + num_imag * denom_imag)
|
||||||
/ (denom_real * denom_real + denom_imag * denom_imag);
|
/ (denom_real * denom_real + denom_imag * denom_imag);
|
||||||
|
|
@ -59,10 +57,10 @@ impl Iridescent {
|
||||||
real * real + imag * imag
|
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);
|
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 {
|
fn cos_K_Delta(&self, l: f32, theta1: f32, theta2: f32, s_polaized: bool) -> f32 {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue