use crate::core::material::CreateMaterial; use crate::utils::{Arena, FileLoc, TextureParameterDictionary}; use shared::core::bxdf::HairBxDF; use shared::core::spectrum::Spectrum; use shared::core::texture::{GPUFloatTexture, GPUSpectrumTexture}; use shared::materials::complex::*; impl CreateMaterial for HairMaterial { fn create( parameters: &TextureParameterDictionary, normal_map: Option>, named_materials: &HashMap, loc: &FileLoc, arena: &mut Arena, ) -> Result { let sigma_a = parameters.get_spectrum_texture_or_null("sigma_a", SpectrumType::Unbounded); let reflectance = parameters .get_spectrum_texture_or_null("reflectance", SpectrumType::Albedo) .or_else(|| parameters.get_spectrum_texture_or_null("color", SpectrumType::Albedo)); let eumelanin = parameters.get_float_texture_or_null("eumelanin"); let pheomelanin = parameters.get_float_texture_or_null("pheomelanin"); let sigma_a = match ( sigma_a, reflectance, eumelanin.is_some() || pheomelanin.is_some(), ) { (Some(s), Some(_), _) => { warn( loc, r#"Ignoring "reflectance" parameter since "sigma_a" was provided."#, ); Some(s) } (Some(s), _, true) => { warn( loc, r#"Ignoring "eumelanin"/"pheomelanin" parameter since "sigma_a" was provided."#, ); Some(s) } (Some(s), None, false) => Some(s), (None, Some(r), true) => { warn( loc, r#"Ignoring "eumelanin"/"pheomelanin" parameter since "reflectance" was provided."#, ); Some(r) } (None, Some(r), false) => Some(r), (None, None, true) => None, // eumelanin/pheomelanin will be used (None, None, false) => Some(SpectrumConstantTexture::new(Spectrum::RGBUnbounded( RGBUnboundedSpectrum::new(HairBxDF::sigma_a_from_concentration(1.3, 0.0)), ))), }; let eta = parameters.get_flot_texture("eta", 1.55); let beta_m = parameters.get_float_texture("beta_m", 0.3); let beta_n = parameters.get_float_texture("beta_n", 0.3); let alpha = parameters.get_float_texture("alpha", 2.); let material = HairMaterial::new( sigma_a, reflectance, eumelanin, pheomelanin, eta, beta_m, beta_n, alpha, ); arena.alloc(material); return material; } } #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct MeasuredMaterial; impl MaterialTrait for MeasuredMaterial { fn get_bsdf( &self, _tex_eval: &T, _ctx: &MaterialEvalContext, _lambda: &SampledWavelengths, ) -> BSDF { todo!() } fn get_bssrdf( &self, _tex_eval: &T, _ctx: &MaterialEvalContext, _lambda: &SampledWavelengths, ) -> Option { todo!() } fn can_evaluate_textures(&self, _tex_eval: &dyn TextureEvaluator) -> bool { todo!() } fn get_normal_map(&self) -> *const Image { todo!() } fn get_displacement(&self) -> Ptr { todo!() } fn has_subsurface_scattering(&self) -> bool { todo!() } } #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct SubsurfaceMaterial; impl MaterialTrait for SubsurfaceMaterial { fn get_bsdf( &self, _tex_eval: &T, _ctx: &MaterialEvalContext, _lambda: &SampledWavelengths, ) -> BSDF { todo!() } fn get_bssrdf( &self, _tex_eval: &T, _ctx: &MaterialEvalContext, _lambda: &SampledWavelengths, ) -> Option { todo!() } fn can_evaluate_textures(&self, _tex_eval: &dyn TextureEvaluator) -> bool { todo!() } fn get_normal_map(&self) -> *const Image { todo!() } fn get_displacement(&self) -> Ptr { todo!() } fn has_subsurface_scattering(&self) -> bool { todo!() } }