pbrt/src/textures/scaled.rs

111 lines
3.5 KiB
Rust

use crate::core::texture::{CreateSpectrumTexture, FloatTexture, SpectrumTexture};
use crate::core::texture::{FloatTextureTrait, SpectrumTextureTrait};
use crate::utils::{FileLoc, TextureParameterDictionary};
use crate::Arena;
use anyhow::Result;
use shared::core::spectrum::Spectrum;
use shared::core::texture::{SpectrumType, TextureEvalContext};
use shared::spectra::{SampledSpectrum, SampledWavelengths, ConstantSpectrum};
use shared::utils::Transform;
use shared::Float;
use std::sync::Arc;
#[derive(Clone, Debug)]
pub struct FloatScaledTexture {
pub tex: Arc<FloatTexture>,
pub scale: Arc<FloatTexture>,
}
impl FloatScaledTexture {
pub fn new(tex: Arc<FloatTexture>, scale: Arc<FloatTexture>) -> Self {
Self { tex, scale }
}
pub fn create(
_render_from_texture: &Transform,
params: &TextureParameterDictionary,
_loc: &FileLoc,
_arena: &Arena,
) -> Result<FloatTexture> {
let mut tex = params.get_float_texture("tex", 1.)?;
let mut scale = params.get_float_texture("scale", 1.)?;
for _ in 0..2 {
if let FloatTexture::Constant(c_tex) = &*scale {
let cs = c_tex.value;
if cs == 1.0 {
return Ok((*tex).clone());
} else if let FloatTexture::Image(img_tex) = &*tex {
let mut image_copy = img_tex.clone();
image_copy.base.multiply_scale(cs);
return Ok(FloatTexture::Image(image_copy));
}
}
std::mem::swap(&mut tex, &mut scale);
}
std::mem::swap(&mut tex, &mut scale);
Ok(FloatTexture::Scaled(FloatScaledTexture::new(
tex.clone(),
scale.clone(),
)))
}
}
impl FloatTextureTrait for FloatScaledTexture {
fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
let sc = self.scale.evaluate(ctx);
if sc == 0. {
return 0.;
}
self.tex.evaluate(ctx)
}
}
#[derive(Clone, Debug)]
pub struct SpectrumScaledTexture {
pub tex: Arc<SpectrumTexture>,
pub scale: Arc<FloatTexture>,
}
impl CreateSpectrumTexture for SpectrumScaledTexture {
fn create(
_render_from_texture: Transform,
parameters: TextureParameterDictionary,
spectrum_type: SpectrumType,
_loc: FileLoc,
) -> Result<SpectrumTexture> {
let one = Spectrum::Constant(ConstantSpectrum::new(1.0));
let tex = parameters
.get_spectrum_texture("tex", Some(one), spectrum_type)
.ok_or_else(|| anyhow::anyhow!("{}: missing \"tex\" parameter", _loc))?;
let scale = parameters.get_float_texture("scale", 1.0)?;
if let FloatTexture::Constant(ref cscale) = *scale {
let cs = cscale.value;
if cs == 1.0 {
return Ok((*tex).clone());
}
if let SpectrumTexture::Image(ref image) = *tex {
let mut image_copy = image.clone();
image_copy.base.multiply_scale(cs);
return Ok(SpectrumTexture::Image(image_copy));
}
}
Ok(SpectrumTexture::Scaled(SpectrumScaledTexture {
tex,
scale,
}))
}
}
impl SpectrumTextureTrait for SpectrumScaledTexture {
fn evaluate(&self, ctx: &TextureEvalContext, lambda: &SampledWavelengths) -> SampledSpectrum {
let sc = self.scale.evaluate(ctx);
if sc == 0. {
return SampledSpectrum::new(0.);
}
self.tex.evaluate(ctx, lambda) * sc
}
}