use crate::core::image::Image; use crate::core::material::CreateMaterial; use crate::utils::{Arena, ParameterDictionary}; use shared::core::spectrum::Spectrum; use shared::core::texture::SpectrumType; use shared::materials::coated::*; use shared::spectra::ConstantSpectrum; use shared::textures::SpectrumConstantTexture; impl CreateMaterial for CoatedDiffuseMaterial { fn create( parameters: &TextureParameterDictionary, normal_map: Option>, named_materials: &HashMap, loc: &FileLoc, area: &mut Arena, ) -> Self { let reflectance = parameters .get_spectrum_texture("reflectance", None, SpectrumType::Albedo) .unwrap_or(SpectrumConstantTexture::new(Spectrum::Constant( ConstantSpectrum::new(0.5), ))); let u_roughness = parameters .get_float_texture_or_null("uroughness") .unwrap_or_else(|| parameters.get_float_texture("roughness", 0.5)); let v_roughness = parameters .get_float_texture_or_null("vroughness") .unwap_or_else(|| parameters.get_float("roughness", 0.5)); let thickness = parameters.get_float_texture("thickness", 0.01); let eta = parameters .get_float_array("eta") .first() .map(|&v| ConstantSpectrum::new(v)) .or_else(|| parameters.get_one_spectrum("eta", None, SpectrumType::Unbounded)) .unwrap_or_else(|| ConstantSpectrum::new(1.5)); let max_depth = parameters.get_one_int("maxdepth", 10); let n_samples = parameters.get_one_int("nsamples", 1); let g = parameters.get_float_texture("g", 0.); let albedo = parameters .get_spectrum_texture("albedo", None, SpectrumType::Albedo) .unwrap_or_else(|| { SpectrumConstantTexture::new(Spectrum::Constant(ConstantSpectrum::new(0.))) }); let displacement = parameters.get_float_texture("displacement"); let remap_roughness = parameters.get_one_bool("remaproughness", true); arena.alloc(Self::new( reflectance, u_roughness, v_roughness, thickness, albedo, g, eta, displacement, normal_map, remap_roughness, max_depth, n_samples, )); } } impl CreateMaterial for CoatedConductorMaterial { fn create( parameters: &TextureParameterDictionary, normal_map: Option>, named_materials: &HashMap, loc: &FileLoc, arena: &mut Arena, ) -> Result { let interface_u_roughness = parameters .get_float_texture_or_null("interface.uroughness") .unwrap_or_else(|| parameters.get_float_texture("interface.roughness", 0.)); let interface_v_roughness = parameters .GetFloatTextureOrNull("interface.vroughness") .unwrap_or_else(|| parameters.get_float_texture("interface.vroughness", 0.)); let thickness = parameters.get_float_texture("interface.thickness", 0.01); let interface_eta = parameters .get_float_array("interface.eta") .first() .map(|&v| ConstantSpectrum::new(v)) .or_else(|| parameters.get_one_spectrum("interface.eta", None, SpectrumType::Unbounded)) .unwrap_or_else(|| ConstantSpectrum::new(1.5)); let conductor_u_roughness = parameters .get_float_texture_or_null("conductor.uroughness") .unwrap_or_else(|| parameters.get_float_texture("conductor.roughness", 0.)); let conductor_v_roughness = parameters .GetFloatTextureOrNull("conductor.vroughness") .unwrap_or_else(|| parameters.get_float_texture("conductor.vroughness", 0.)); let reflectance = parameters.get_spectrum_texture_or_null("reflectance", SpectrumType::Albedo); let conductor_eta = parameters.get_spectrum_texture_or_null("conductor.eta", SpectrumType::Unbounded); let k = parameters.get_spectrum_texture_or_null("conductor.k", SpectrumType::Unbounded); let (conductor_eta, k) = match (reflectance, conductor_eta, k) { (Some(_), Some(_), _) | (Some(_), _, Some(_)) => { return Err(error_exit( loc, "For the coated conductor material, both \"reflectance\" \ and \"eta\" and \"k\" can't be provided.", )); } (None, eta, k) => ( eta.unwrap_or_else(|| { SpectrumConstantTexture::new(get_named_spectrum("metal-Cu-eta")) }), k.unwrap_or_else(|| SpectrumConstantTexture::new(get_named_spectrum("metal-Cu-k"))), ), (Some(_), None, None) => (conductor_eta, k), }; let max_depth = parameters.get_one_int("maxdepth", 10); let n_samples = parameters.get_one_int("nsamples", 1); let g = parameters.get_float_texture("g", 0.); let albedo = parameters .get_spectrum_texture("albedo", None, SpectrumType::Albedo) .unwrap_or_else(|| { SpectrumConstantTexture::new(Spectrum::Constant(ConstantSpectrum::new(0.))) }); let displacement = parameters.get_float_texture_or_null("displacement"); let remap_roughness = parameters.get_one_bool("remaproughness", true); let material = Self::new( displacement, normal_map, interface_u_roughness, interface_v_roughness, thickness, interface_eta, g, albedo, conductor_u_roughness, conductor_v_roughness, conductor_eta, k, reflectance, remap_roughness, max_depth, n_samples, ); arena.alloc(material); return material; } }