Add iridescent material
This commit is contained in:
		
							parent
							
								
									d475c1ef04
								
							
						
					
					
						commit
						c26a4bece0
					
				
					 8 changed files with 276 additions and 34 deletions
				
			
		
							
								
								
									
										3
									
								
								.cargo/config.toml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.cargo/config.toml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | ||||||
|  | 
 | ||||||
|  | [build] | ||||||
|  | rustflags = ["-C raget-cpu=native"] | ||||||
							
								
								
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -1,2 +1,3 @@ | ||||||
| target | target | ||||||
| **.exr | **.exr | ||||||
|  | **.png | ||||||
|  |  | ||||||
							
								
								
									
										52
									
								
								flake.nix
									
										
									
									
									
								
							
							
						
						
									
										52
									
								
								flake.nix
									
										
									
									
									
								
							|  | @ -6,15 +6,23 @@ | ||||||
|     flake-utils.url = "github:numtide/flake-utils"; |     flake-utils.url = "github:numtide/flake-utils"; | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   outputs = { self, nixpkgs, flake-utils }: |   outputs = | ||||||
|     flake-utils.lib.eachDefaultSystem (system: |     { | ||||||
|  |       self, | ||||||
|  |       nixpkgs, | ||||||
|  |       flake-utils, | ||||||
|  |     }: | ||||||
|  |     flake-utils.lib.eachDefaultSystem ( | ||||||
|  |       system: | ||||||
|       let |       let | ||||||
|         pkgs = nixpkgs.legacyPackages.${system}; |         pkgs = nixpkgs.legacyPackages.${system}; | ||||||
|         # Read the file relative to the flake's root |         # Read the file relative to the flake's root | ||||||
|         overrides = (builtins.fromTOML (builtins.readFile (self + "/rust-toolchain.toml"))); |         overrides = (builtins.fromTOML (builtins.readFile (self + "/rust-toolchain.toml"))); | ||||||
|         libPath = with pkgs; lib.makeLibraryPath [ |         libPath = | ||||||
|           # load external libraries that you need in your rust project here |           with pkgs; | ||||||
|         ]; |           lib.makeLibraryPath [ | ||||||
|  |             # load external libraries that you need in your rust project here | ||||||
|  |           ]; | ||||||
|       in |       in | ||||||
|       { |       { | ||||||
|         devShells.default = pkgs.mkShell rec { |         devShells.default = pkgs.mkShell rec { | ||||||
|  | @ -31,6 +39,7 @@ | ||||||
|             python3 |             python3 | ||||||
|           ]; |           ]; | ||||||
|           buildInputs = with pkgs; [ |           buildInputs = with pkgs; [ | ||||||
|  |             fontconfig | ||||||
|             clang |             clang | ||||||
|             llvmPackages.bintools |             llvmPackages.bintools | ||||||
|             rustup |             rustup | ||||||
|  | @ -38,7 +47,7 @@ | ||||||
| 
 | 
 | ||||||
|           # VULKAN_SDK = "${vulkan-validation-layers}/share/vulkan/explicit_layer.d"; |           # VULKAN_SDK = "${vulkan-validation-layers}/share/vulkan/explicit_layer.d"; | ||||||
| 
 | 
 | ||||||
|           LD_LIBRARY_PATH="${pkgs.wayland}/lib:${pkgs.libxkbcommon}/lib:${pkgs.vulkan-loader}/lib:${pkgs.vulkan-validation-layers}/lib"; |           LD_LIBRARY_PATH = "${pkgs.wayland}/lib:${pkgs.libxkbcommon}/lib:${pkgs.vulkan-loader}/lib:${pkgs.vulkan-validation-layers}/lib"; | ||||||
|           VK_LAYER_PATH = "${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d"; |           VK_LAYER_PATH = "${pkgs.vulkan-validation-layers}/share/vulkan/explicit_layer.d"; | ||||||
| 
 | 
 | ||||||
|           RUSTC_VERSION = overrides.toolchain.channel; |           RUSTC_VERSION = overrides.toolchain.channel; | ||||||
|  | @ -53,26 +62,27 @@ | ||||||
|           ''; |           ''; | ||||||
| 
 | 
 | ||||||
|           # Add precompiled library to rustc search path |           # Add precompiled library to rustc search path | ||||||
|           RUSTFLAGS = (builtins.map (a: ''-L ${a}/lib'') [ |           RUSTFLAGS = ( | ||||||
|             # add libraries here (e.g. pkgs.libvmi) |             builtins.map (a: ''-L ${a}/lib'') [ | ||||||
|           ]); |               # add libraries here (e.g. pkgs.libvmi) | ||||||
|  |             ] | ||||||
|  |           ); | ||||||
| 
 | 
 | ||||||
|           # LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath (buildInputs ++ nativeBuildInputs); |           # LD_LIBRARY_PATH = pkgs.lib.makeLibraryPath (buildInputs ++ nativeBuildInputs); | ||||||
| 
 | 
 | ||||||
|            |  | ||||||
|           # Add glibc, clang, glib, and other headers to bindgen search path |           # Add glibc, clang, glib, and other headers to bindgen search path | ||||||
|           BINDGEN_EXTRA_CLANG_ARGS = |           BINDGEN_EXTRA_CLANG_ARGS = | ||||||
|           # Includes normal include path |             # Includes normal include path | ||||||
|           (builtins.map (a: ''-I"${a}/include"'') [ |             (builtins.map (a: ''-I"${a}/include"'') [ | ||||||
|             # add dev libraries here (e.g. pkgs.libvmi.dev) |               # add dev libraries here (e.g. pkgs.libvmi.dev) | ||||||
|             pkgs.glibc.dev |               pkgs.glibc.dev | ||||||
|           ]) |             ]) | ||||||
|           # Includes with special directory paths |             # Includes with special directory paths | ||||||
|           ++ [ |             ++ [ | ||||||
|             ''-I"${pkgs.llvmPackages_latest.libclang.lib}/lib/clang/${pkgs.llvmPackages_latest.libclang.version}/include"'' |               ''-I"${pkgs.llvmPackages_latest.libclang.lib}/lib/clang/${pkgs.llvmPackages_latest.libclang.version}/include"'' | ||||||
|             ''-I"${pkgs.glib.dev}/include/glib-2.0"'' |               ''-I"${pkgs.glib.dev}/include/glib-2.0"'' | ||||||
|             ''-I${pkgs.glib.out}/lib/glib-2.0/include/'' |               ''-I${pkgs.glib.out}/lib/glib-2.0/include/'' | ||||||
|           ]; |             ]; | ||||||
|         }; |         }; | ||||||
|       } |       } | ||||||
|     ); |     ); | ||||||
|  |  | ||||||
|  | @ -10,6 +10,7 @@ use rand::{rngs::SmallRng, SeedableRng}; | ||||||
| use ray_tracing_core::prelude::*; | use ray_tracing_core::prelude::*; | ||||||
| use ray_tracing_material::{ | use ray_tracing_material::{ | ||||||
|     diffuse::DiffuseMaterial, |     diffuse::DiffuseMaterial, | ||||||
|  |     iridescent::Iridescent, | ||||||
|     microfacet::{BeckmannDistribution, Microfacet}, |     microfacet::{BeckmannDistribution, Microfacet}, | ||||||
|     mirror::Mirror, |     mirror::Mirror, | ||||||
|     oren_nayar::OrenNayar, |     oren_nayar::OrenNayar, | ||||||
|  | @ -35,6 +36,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> { | ||||||
|     let m = OrenNayar::new(0.5, color); |     let m = OrenNayar::new(0.5, color); | ||||||
|     generate_chart("oren-nayar.png", &m, 100, w_in)?; |     generate_chart("oren-nayar.png", &m, 100, w_in)?; | ||||||
| 
 | 
 | ||||||
|  |     let m = Iridescent::new(300.0, 300.0, 1.0, 1.5, 10); | ||||||
|  |     generate_chart("iridescent.png", &m, 2, w_in)?; | ||||||
|  | 
 | ||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										207
									
								
								ray-tracing-material/src/iridescent.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								ray-tracing-material/src/iridescent.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,207 @@ | ||||||
|  | use core::f32; | ||||||
|  | 
 | ||||||
|  | use ray_tracing_core::prelude::*; | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct Iridescent { | ||||||
|  |     d1: f32, | ||||||
|  |     d2: f32, | ||||||
|  |     n1: f32, | ||||||
|  |     n2: f32, | ||||||
|  |     n: f32, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl Iridescent { | ||||||
|  |     pub fn new(d1: f32, d2: f32, n1: f32, n2: f32, n: u32) -> Self { | ||||||
|  |         Self { | ||||||
|  |             d1, | ||||||
|  |             d2, | ||||||
|  |             n1, | ||||||
|  |             n2, | ||||||
|  |             n: n as f32, | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn fresnel_reflection(&self, 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()) | ||||||
|  |         } else { | ||||||
|  |             (self.n2 * theta1.cos() - self.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 { | ||||||
|  |         let r12 = self.fresnel_reflection(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 denom_real = 1.0 - r12 * r12 * f32::cos(-2.0 * phi); | ||||||
|  |         let denom_imag = 1.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); | ||||||
|  | 
 | ||||||
|  |         let imag = (num_imag * denom_real - num_real * denom_imag) | ||||||
|  |             / (denom_real * denom_real + denom_imag * denom_imag); | ||||||
|  | 
 | ||||||
|  |         real * real + imag * imag | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     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) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn cos_K_Delta(&self, l: f32, theta1: f32, theta2: f32, s_polaized: bool) -> f32 { | ||||||
|  |         let k1z = 2.0 * f32::consts::PI * self.n1 * theta1.cos() / l; | ||||||
|  |         let k2z = 2.0 * f32::consts::PI * self.n2 * theta2.cos() / l; | ||||||
|  | 
 | ||||||
|  |         let omega = if s_polaized { | ||||||
|  |             k2z / k1z + k1z / k2z | ||||||
|  |         } else { | ||||||
|  |             (self.n1 * self.n1 * k2z) / (self.n2 * self.n2 * k1z) | ||||||
|  |                 + (self.n2 * self.n2 * k1z) / (self.n1 * self.n1 * k2z) | ||||||
|  |         }; | ||||||
|  | 
 | ||||||
|  |         f32::cos(k1z * self.d1) * f32::cos(k2z * self.d2) | ||||||
|  |             - 0.5 * omega * f32::sin(k1z * self.d1) * f32::sin(k2z * self.d2) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn reflectance(&self, l: f32, theta1: f32, s_polaized: bool) -> f32 { | ||||||
|  |         let theta2 = f32::asin(f32::sin(theta1) * self.n1 / self.n2); | ||||||
|  | 
 | ||||||
|  |         let local_cos_k_delta = self.cos_K_Delta(l, theta1, theta2, s_polaized); | ||||||
|  | 
 | ||||||
|  |         let local_c_squred = self.abs_C_squared(l, theta1, theta2, s_polaized); | ||||||
|  | 
 | ||||||
|  |         if !local_c_squred.is_normal() || !local_cos_k_delta.is_normal() { | ||||||
|  |             dbg!(( | ||||||
|  |                 l, | ||||||
|  |                 theta1, | ||||||
|  |                 theta2, | ||||||
|  |                 local_cos_k_delta, | ||||||
|  |                 local_c_squred, | ||||||
|  |                 s_polaized | ||||||
|  |             )); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         if local_cos_k_delta.abs() <= 1.0 { | ||||||
|  |             let k_delta = f32::acos(local_cos_k_delta); | ||||||
|  | 
 | ||||||
|  |             if !k_delta.is_normal() { | ||||||
|  |                 dbg!(( | ||||||
|  |                     l, | ||||||
|  |                     theta1, | ||||||
|  |                     theta2, | ||||||
|  |                     local_cos_k_delta, | ||||||
|  |                     local_c_squred, | ||||||
|  |                     s_polaized, | ||||||
|  |                     k_delta, | ||||||
|  |                 )); | ||||||
|  |             } | ||||||
|  |             let u = f32::sin(k_delta) / f32::sin(self.n * k_delta); | ||||||
|  | 
 | ||||||
|  |             local_c_squred / (local_c_squred + u * u) | ||||||
|  |         } else { | ||||||
|  |             let imk_delta = -f32::ln(f32::abs( | ||||||
|  |                 local_cos_k_delta - f32::sqrt(local_cos_k_delta * local_cos_k_delta - 1.0), | ||||||
|  |             )); | ||||||
|  | 
 | ||||||
|  |             if !imk_delta.is_normal() { | ||||||
|  |                 dbg!(( | ||||||
|  |                     l, | ||||||
|  |                     theta1, | ||||||
|  |                     theta2, | ||||||
|  |                     local_cos_k_delta, | ||||||
|  |                     local_c_squred, | ||||||
|  |                     s_polaized, | ||||||
|  |                     imk_delta, | ||||||
|  |                 )); | ||||||
|  |             } | ||||||
|  |             let u = f32::sinh(imk_delta) / f32::sinh(self.n * imk_delta); | ||||||
|  | 
 | ||||||
|  |             local_c_squred / (local_c_squred + u * u) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn averaged_reflectance(&self, l: f32, theta1: f32) -> f32 { | ||||||
|  |         0.5 * (self.reflectance(l, theta1, true) + self.reflectance(l, theta1, false)) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn piecewise_gaussian(l: f32, mu: f32, tau1: f32, tau2: f32) -> f32 { | ||||||
|  |         if l < mu { | ||||||
|  |             let s = tau1 * (l - mu); | ||||||
|  |             f32::exp(-0.5 * s * s) | ||||||
|  |         } else { | ||||||
|  |             let s = tau2 * (l - mu); | ||||||
|  |             f32::exp(-0.5 * s * s) | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn color_matching_function(l: f32) -> Color { | ||||||
|  |         Color::new( | ||||||
|  |             1.056 * Self::piecewise_gaussian(l, 599.8, 0.0264, 0.0323) | ||||||
|  |                 + 0.362 * Self::piecewise_gaussian(l, 442.0, 0.0624, 0.0374) | ||||||
|  |                 - 0.065 * Self::piecewise_gaussian(l, 501.1, 0.0490, 0.0382), | ||||||
|  |             0.821 * Self::piecewise_gaussian(l, 568.8, 0.0213, 0.0247) | ||||||
|  |                 + 0.286 * Self::piecewise_gaussian(l, 530.9, 0.0613, 0.0322), | ||||||
|  |             1.217 * Self::piecewise_gaussian(l, 437.0, 0.0845, 0.0278) | ||||||
|  |                 + 0.681 * Self::piecewise_gaussian(l, 459.0, 0.0385, 0.0725), | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn monte_carlo_reflectance<R: Rng>(&self, theta1: f32, rng: &mut R) -> Color { | ||||||
|  |         let range = 400.0..800.0; | ||||||
|  |         let size = range.end - range.start; | ||||||
|  | 
 | ||||||
|  |         let l = rng.gen_range(range); | ||||||
|  | 
 | ||||||
|  |         let r = self.averaged_reflectance(l, theta1); | ||||||
|  | 
 | ||||||
|  |         if !r.is_normal() { | ||||||
|  |             dbg!((theta1, l, r)); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         let color = Self::color_matching_function(l); | ||||||
|  | 
 | ||||||
|  |         if !color.r().is_normal() || !color.g().is_normal() || !color.b().is_normal() { | ||||||
|  |             dbg!(color); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         color * r | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<R: Rng> Material<R> for Iridescent { | ||||||
|  |     fn eval( | ||||||
|  |         &self, | ||||||
|  |         w_in: ray_tracing_core::prelude::Dir3, | ||||||
|  |         w_out: ray_tracing_core::prelude::Dir3, | ||||||
|  |         rng: &mut R, | ||||||
|  |     ) -> ray_tracing_core::prelude::Color { | ||||||
|  |         let _ = w_in; | ||||||
|  |         let _ = w_out; | ||||||
|  |         let _ = rng; | ||||||
|  |         Color::black() | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn sample(&self, w_in: Dir3, rng: &mut R) -> ray_tracing_core::material::SampleResult { | ||||||
|  |         let w_out = (2.0 * Dir3::up() * w_in.y()) - w_in; | ||||||
|  | 
 | ||||||
|  |         let color = self.monte_carlo_reflectance(f32::acos(w_out.z()), rng); | ||||||
|  | 
 | ||||||
|  |         ray_tracing_core::material::SampleResult::new(w_out, color, true) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     fn pdf(&self, w_in: Dir3, w_out: Dir3) -> Float { | ||||||
|  |         let _ = w_out; | ||||||
|  |         let _ = w_in; | ||||||
|  |         0.0 | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| pub mod default; | pub mod default; | ||||||
| pub mod diffuse; | pub mod diffuse; | ||||||
|  | pub mod iridescent; | ||||||
| pub mod microfacet; | pub mod microfacet; | ||||||
| pub mod mirror; | pub mod mirror; | ||||||
| pub mod oren_nayar; | pub mod oren_nayar; | ||||||
|  |  | ||||||
|  | @ -1,4 +1,7 @@ | ||||||
| use ray_tracing_core::{prelude::*, scene::Scene}; | use ray_tracing_core::{prelude::*, scene::Scene}; | ||||||
|  | use ray_tracing_material::iridescent::Iridescent; | ||||||
|  | use ray_tracing_material::microfacet::{BeckmannDistribution, Microfacet}; | ||||||
|  | use ray_tracing_material::mirror::Mirror; | ||||||
| use std::collections::HashMap; | use std::collections::HashMap; | ||||||
| use std::fmt::Debug; | use std::fmt::Debug; | ||||||
| 
 | 
 | ||||||
|  | @ -19,9 +22,21 @@ pub fn example_scenes<R: Rng + Debug + 'static>() -> HashMap<&'static str, Box<d | ||||||
|     let mut map: HashMap<&str, Box<dyn ExampleScene<R>>> = HashMap::new(); |     let mut map: HashMap<&str, Box<dyn ExampleScene<R>>> = HashMap::new(); | ||||||
|     map.insert("basic_cornel", Box::new(basic_cornell::BasicCornell::new())); |     map.insert("basic_cornel", Box::new(basic_cornell::BasicCornell::new())); | ||||||
|     map.insert("cornel2", Box::new(cornell2::Cornell2::new())); |     map.insert("cornel2", Box::new(cornell2::Cornell2::new())); | ||||||
|  |     let color = Color::new(0.2, 0.2, 0.9); | ||||||
|  |     let material = Microfacet::new(BeckmannDistribution::new(0.01), color); | ||||||
|     map.insert( |     map.insert( | ||||||
|         "stanford_dragon", |         "stanford_dragon_microfacet", | ||||||
|         Box::new(stanford_dragon::StanfordDragon::new()), |         Box::new(stanford_dragon::StanfordDragon::new(material)), | ||||||
|  |     ); | ||||||
|  |     let material = Iridescent::new(300.0, 300.0, 1.0, 1.5, 10); | ||||||
|  |     map.insert( | ||||||
|  |         "stanford_dragon_iridescent", | ||||||
|  |         Box::new(stanford_dragon::StanfordDragon::new(material)), | ||||||
|  |     ); | ||||||
|  |     let material = Mirror::new(Color::white()); | ||||||
|  |     map.insert( | ||||||
|  |         "stanford_dragon_mirror", | ||||||
|  |         Box::new(stanford_dragon::StanfordDragon::new(material)), | ||||||
|     ); |     ); | ||||||
|     map.insert( |     map.insert( | ||||||
|         "stanford_dragon_as", |         "stanford_dragon_as", | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ use ray_tracing_material::{ | ||||||
|     microfacet::{BeckmannDistribution, Microfacet}, |     microfacet::{BeckmannDistribution, Microfacet}, | ||||||
|     oren_nayar::OrenNayar, |     oren_nayar::OrenNayar, | ||||||
| }; | }; | ||||||
| use std::cell::OnceCell; | use std::cell::{Cell, OnceCell}; | ||||||
| 
 | 
 | ||||||
| use crate::{ | use crate::{ | ||||||
|     parse_obj::ObjData, |     parse_obj::ObjData, | ||||||
|  | @ -13,19 +13,21 @@ use crate::{ | ||||||
| 
 | 
 | ||||||
| use super::ExampleScene; | use super::ExampleScene; | ||||||
| 
 | 
 | ||||||
| pub struct StanfordDragon<R: Rng> { | pub struct StanfordDragon<R: Rng, M: Material<R>> { | ||||||
|     scene: OnceCell<TriangleBVH<R>>, |     scene: OnceCell<TriangleBVH<R>>, | ||||||
|  |     material: Cell<Option<M>>, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<R: Rng> StanfordDragon<R> { | impl<R: Rng, M: Material<R>> StanfordDragon<R, M> { | ||||||
|     pub fn new() -> Self { |     pub fn new(material: M) -> Self { | ||||||
|         Self { |         Self { | ||||||
|             scene: OnceCell::new(), |             scene: OnceCell::new(), | ||||||
|  |             material: Cell::new(Some(material)), | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl<R: Rng + 'static> ExampleScene<R> for StanfordDragon<R> { | impl<R: Rng + 'static, M: Material<R> + 'static> ExampleScene<R> for StanfordDragon<R, M> { | ||||||
|     fn get_scene(&self) -> Box<dyn Scene<R> + Sync> { |     fn get_scene(&self) -> Box<dyn Scene<R> + Sync> { | ||||||
|         let s = self.scene.get_or_init(|| { |         let s = self.scene.get_or_init(|| { | ||||||
|             let obj = ObjData::new("ray-tracing-scene/obj/stanford_dragon.obj").unwrap(); |             let obj = ObjData::new("ray-tracing-scene/obj/stanford_dragon.obj").unwrap(); | ||||||
|  | @ -35,9 +37,8 @@ impl<R: Rng + 'static> ExampleScene<R> for StanfordDragon<R> { | ||||||
|                 .map(|t| Triangle::new(t.v, 0)) |                 .map(|t| Triangle::new(t.v, 0)) | ||||||
|                 .collect::<Vec<_>>(); |                 .collect::<Vec<_>>(); | ||||||
| 
 | 
 | ||||||
|             let color = Color::new(0.2, 0.2, 0.9); |  | ||||||
|             let materials = vec![ |             let materials = vec![ | ||||||
|                 BVHMaterial::new_material(Microfacet::new(BeckmannDistribution::new(0.01), color)), |                 BVHMaterial::new_material(self.material.take().unwrap()), | ||||||
|                 BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.8, 0.8, 0.8))), |                 BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.8, 0.8, 0.8))), | ||||||
|                 BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.9, 0.0, 0.0))), |                 BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.9, 0.0, 0.0))), | ||||||
|                 BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.0, 0.9, 0.0))), |                 BVHMaterial::new_material(OrenNayar::new(0.5, Color::new(0.0, 0.9, 0.0))), | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue