diff --git a/shared/src/textures/bilerp.rs b/shared/src/textures/bilerp.rs index 57fd128..1bfbeb6 100644 --- a/shared/src/textures/bilerp.rs +++ b/shared/src/textures/bilerp.rs @@ -39,8 +39,12 @@ impl FloatBilerpTexture { } } - pub fn evaluate(&self, _ctx: &TextureEvalContext) -> Float { - todo!() + pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float { + let c = self.mapping.map(ctx); + (1. - c.st[0]) * (1. - c.st[1]) * self.v00 + + c.st[0] * (1. - c.st[1]) * self.v10 + + (1. - c.st[0]) * c.st[1] * self.v01 + + c.st[0] * c.st[1] * self.v11 } } diff --git a/shared/src/textures/marble.rs b/shared/src/textures/marble.rs index f5a2685..3418a4f 100644 --- a/shared/src/textures/marble.rs +++ b/shared/src/textures/marble.rs @@ -23,6 +23,24 @@ pub struct MarbleTexture { } impl MarbleTexture { + pub fn new( + mapping: TextureMapping3D, + octaves: i32, + omega: Float, + scale: Float, + variation: Float, + colorspace: Ptr, + ) -> Self { + Self { + mapping, + octaves: octaves.try_into().unwrap(), + omega, + scale, + variation, + colorspace, + } + } + pub fn evaluate( &self, ctx: &TextureEvalContext, diff --git a/src/core/texture.rs b/src/core/texture.rs index 745a550..7f765ad 100644 --- a/src/core/texture.rs +++ b/src/core/texture.rs @@ -9,8 +9,8 @@ use shared::core::geometry::Vector3f; use shared::core::image::WrapMode; use shared::core::texture::SpectrumType; use shared::core::texture::{ - CylindricalMapping, PlanarMapping, PointTransformMapping, SphericalMapping, - TextureEvalContext, TextureMapping2D, TextureMapping3D, UVMapping, + CylindricalMapping, PlanarMapping, PointTransformMapping, SphericalMapping, TextureEvalContext, + TextureMapping2D, TextureMapping3D, UVMapping, }; use shared::spectra::{SampledSpectrum, SampledWavelengths}; use shared::textures::{ @@ -115,26 +115,53 @@ impl SpectrumTexture { arena: &Arena, ) -> Result { match name { - "constant" => { - SpectrumConstantTexture::create(render_from_texture, params, spectrum_type, loc, arena) - } - "scale" => { - SpectrumScaledTexture::create(render_from_texture, params, spectrum_type, loc, arena) - } - "mix" => SpectrumMixTexture::create(render_from_texture, params, spectrum_type, loc, arena), - "directionmix" => { - SpectrumDirectionMixTexture::create(render_from_texture, params, spectrum_type, loc, arena) - } - "bilerp" => { - SpectrumBilerpTexture::create(render_from_texture, params, spectrum_type, loc, arena) + "constant" => SpectrumConstantTexture::create( + render_from_texture, + params, + spectrum_type, + loc, + arena, + ), + "scale" => SpectrumScaledTexture::create( + render_from_texture, + params, + spectrum_type, + loc, + arena, + ), + "mix" => { + SpectrumMixTexture::create(render_from_texture, params, spectrum_type, loc, arena) } + "directionmix" => SpectrumDirectionMixTexture::create( + render_from_texture, + params, + spectrum_type, + loc, + arena, + ), + "bilerp" => SpectrumBilerpTexture::create( + render_from_texture, + params, + spectrum_type, + loc, + arena, + ), "imagemap" => { SpectrumImageTexture::create(render_from_texture, params, spectrum_type, loc, arena) } - "checkerboard" => { - SpectrumCheckerboardTexture::create(render_from_texture, params, spectrum_type, loc, arena) + "checkerboard" => SpectrumCheckerboardTexture::create( + render_from_texture, + params, + spectrum_type, + loc, + arena, + ), + "dots" => { + SpectrumDotsTexture::create(render_from_texture, params, spectrum_type, loc, arena) + } + "marble" => { + MarbleTexture::create(render_from_texture, params, spectrum_type, loc, arena) } - "dots" => SpectrumDotsTexture::create(render_from_texture, params, spectrum_type, loc, arena), _ => Err(anyhow!( "Spectrum texture type '{}' unknown at {}", name, @@ -209,7 +236,6 @@ impl CreateTextureMapping for TextureMapping3D { let mapping = PointTransformMapping::new(render_from_texture.inverse()); Ok(TextureMapping3D::PointTransform(mapping)) } - } pub static TEXTURE_CACHE: OnceLock>>> = OnceLock::new(); diff --git a/src/textures/marble.rs b/src/textures/marble.rs index 6137c2a..e8e69e2 100644 --- a/src/textures/marble.rs +++ b/src/textures/marble.rs @@ -1,19 +1,29 @@ -use crate::core::texture::{CreateSpectrumTexture, SpectrumTexture}; -use crate::utils::{FileLoc, TextureParameterDictionary}; use crate::Arena; +use crate::core::texture::{CreateSpectrumTexture, CreateTextureMapping, SpectrumTexture}; +use crate::spectra::get_colorspace_device; +use crate::utils::{FileLoc, TextureParameterDictionary}; use anyhow::Result; use shared::Transform; -use shared::core::texture::SpectrumType; +use shared::core::texture::{SpectrumType, TextureMapping3D}; use shared::textures::MarbleTexture; impl CreateSpectrumTexture for MarbleTexture { fn create( - _render_from_texture: Transform, - _parameters: TextureParameterDictionary, - _spectrum_type: SpectrumType, - _loc: FileLoc, + render_from_texture: Transform, + parameters: TextureParameterDictionary, + spectrum_type: SpectrumType, + loc: FileLoc, _arena: &Arena, ) -> Result { - todo!() + let map = TextureMapping3D::create(¶meters, &render_from_texture, &loc)?; + let tex = MarbleTexture::new( + map, + parameters.get_one_int("octaves", 8)?, + parameters.get_one_float("roughness", 0.5)?, + parameters.get_one_float("scale", 1.)?, + parameters.get_one_float("variation", 0.2)?, + get_colorspace_device().srgb, + ); + Ok(SpectrumTexture::Marble(tex)) } } diff --git a/src/textures/mix.rs b/src/textures/mix.rs index 41f747c..97ce551 100644 --- a/src/textures/mix.rs +++ b/src/textures/mix.rs @@ -4,8 +4,9 @@ use crate::utils::{FileLoc, TextureParameterDictionary}; use anyhow::Result; use shared::Float; use shared::core::geometry::{Vector3f, VectorLike}; +use shared::core::spectrum::Spectrum; use shared::core::texture::{SpectrumType, TextureEvalContext}; -use shared::spectra::{SampledSpectrum, SampledWavelengths}; +use shared::spectra::{ConstantSpectrum, SampledSpectrum, SampledWavelengths}; use shared::utils::Transform; use std::sync::Arc; @@ -90,11 +91,11 @@ impl CreateSpectrumTexture for SpectrumMixTexture { .expect("default supplied") }; - let tex = SpectrumMixTexture::new( - tex("tex1", zero), - tex("tex2", one), - parameters.get_float_texture("amount", 0.5)?, - ); + let tex = SpectrumMixTexture { + tex1: tex("tex1", zero), + tex2: tex("tex2", one), + amount: parameters.get_float_texture("amount", 0.5)?, + }; Ok(SpectrumTexture::Mix(tex)) } } @@ -108,12 +109,27 @@ pub struct SpectrumDirectionMixTexture { impl CreateSpectrumTexture for SpectrumDirectionMixTexture { fn create( - _render_from_texture: Transform, - _parameters: TextureParameterDictionary, - _spectrum_type: SpectrumType, - _loc: FileLoc, + render_from_texture: Transform, + parameters: TextureParameterDictionary, + spectrum_type: SpectrumType, + loc: FileLoc, _arena: &Arena, ) -> Result { - todo!() + let dir_raw = parameters.get_one_vector3f("dir", Vector3f::new(0., 1., 0.))?; + let dir = render_from_texture.apply_to_vector(dir_raw).normalize(); + let tex = |name: &str, def: Spectrum| { + parameters + .get_spectrum_texture(name, Some(def), spectrum_type) + .expect("default supplied") + }; + + let zero = Spectrum::Constant(ConstantSpectrum::new(0.)); + let one = Spectrum::Constant(ConstantSpectrum::new(1.)); + let tex = SpectrumDirectionMixTexture { + tex1: tex("tex1", zero), + tex2: tex("tex2", one), + dir, + }; + Ok(SpectrumTexture::DirectionMix(tex)) } }