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 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<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)?;
|
||||
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)
|
||||
.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<dyn std::error::Error>> {
|
|||
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<dyn std::error::Error>> {
|
|||
);
|
||||
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<dyn std::error::Error>> {
|
|||
// 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<dyn std::error::Error>> {
|
|||
&BLUE,
|
||||
))?;
|
||||
|
||||
root.present()?;
|
||||
|
||||
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 {
|
||||
(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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue