pbrt/shared/src/textures/mix.rs

133 lines
3.4 KiB
Rust

use crate::Float;
use crate::core::geometry::{Vector3f, VectorLike};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext};
use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr;
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct GPUFloatMixTexture {
pub tex1: Ptr<GPUFloatTexture>,
pub tex2: Ptr<GPUFloatTexture>,
pub amount: Ptr<GPUFloatTexture>,
}
impl GPUFloatMixTexture {
pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
let amt = self.amount.get().map(|t| t.evaluate(&ctx)).unwrap_or(0.0);
let t1 = if amt != 1.0 {
self.tex1.get().map(|t| t.evaluate(&ctx)).unwrap_or(0.0)
} else {
0.0
};
let t2 = if amt != 0.0 {
self.tex2.get().map(|t| t.evaluate(&ctx)).unwrap_or(0.0)
} else {
0.0
};
(1.0 - amt) * t1 + amt * t2
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct GPUFloatDirectionMixTexture {
pub tex1: Ptr<GPUFloatTexture>,
pub tex2: Ptr<GPUFloatTexture>,
pub dir: Vector3f,
}
impl GPUFloatDirectionMixTexture {
pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
let amt = self.dir.abs_dot(ctx.n.into());
let t1 = if amt != 1.0 {
self.tex1.get().map(|t| t.evaluate(&ctx)).unwrap_or(0.0)
} else {
0.0
};
let t2 = if amt != 0.0 {
self.tex2.get().map(|t| t.evaluate(&ctx)).unwrap_or(0.0)
} else {
0.0
};
(1.0 - amt) * t1 + amt * t2
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct GPUSpectrumMixTexture {
pub tex1: Ptr<GPUSpectrumTexture>,
pub tex2: Ptr<GPUSpectrumTexture>,
pub amount: Ptr<GPUFloatTexture>,
}
impl GPUSpectrumMixTexture {
pub fn evaluate(
&self,
ctx: &TextureEvalContext,
lambda: &SampledWavelengths,
) -> SampledSpectrum {
let amt = self.amount.get().map(|t| t.evaluate(&ctx)).unwrap_or(0.0);
let t1 = if amt != 1.0 {
self.tex1
.get()
.map(|t| t.evaluate(&ctx, &lambda))
.unwrap_or(SampledSpectrum::new(0.))
} else {
SampledSpectrum::new(0.)
};
let t2 = if amt != 0.0 {
self.tex2
.get()
.map(|t| t.evaluate(&ctx, &lambda))
.unwrap_or(SampledSpectrum::new(0.))
} else {
SampledSpectrum::new(0.)
};
(1.0 - amt) * t1 + amt * t2
}
}
#[repr(C)]
#[derive(Copy, Clone, Debug)]
pub struct GPUSpectrumDirectionMixTexture {
pub tex1: Ptr<GPUSpectrumTexture>,
pub tex2: Ptr<GPUSpectrumTexture>,
pub dir: Vector3f,
}
impl GPUSpectrumDirectionMixTexture {
pub fn evaluate(
&self,
ctx: &TextureEvalContext,
lambda: &SampledWavelengths,
) -> SampledSpectrum {
let amt = self.dir.abs_dot(ctx.n.into());
let t1 = if amt != 1.0 {
self.tex1
.get()
.map(|t| t.evaluate(&ctx, &lambda))
.unwrap_or(SampledSpectrum::new(0.))
} else {
SampledSpectrum::new(0.)
};
let t2 = if amt != 0.0 {
self.tex2
.get()
.map(|t| t.evaluate(&ctx, &lambda))
.unwrap_or(SampledSpectrum::new(0.))
} else {
SampledSpectrum::new(0.)
};
(1.0 - amt) * t1 + amt * t2
}
}