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