pbrt/shared/src/textures/ptex.rs
2026-01-22 14:18:57 +00:00

51 lines
1.6 KiB
Rust

use crate::Float;
use crate::core::color::{ColorEncoding, RGB};
use crate::core::spectrum::{SpectrumTrait, StandardSpectra};
use crate::core::texture::{SpectrumType, TextureEvalContext};
use crate::spectra::{
DeviceStandardColorSpaces, RGBAlbedoSpectrum, RGBColorSpace, RGBIlluminantSpectrum,
RGBUnboundedSpectrum, SampledSpectrum, SampledWavelengths,
};
use crate::utils::Ptr;
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct GPUFloatPtexTexture {
pub face_values: *const Float,
}
impl GPUFloatPtexTexture {
pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
unsafe { *self.face_values.add(ctx.face_index as usize) }
}
}
#[repr(C)]
#[derive(Clone, Debug, Copy)]
pub struct GPUSpectrumPtexTexture {
pub face_values: Ptr<RGB>,
pub n_faces: u32,
pub spectrum_type: SpectrumType,
pub colorspaces: DeviceStandardColorSpaces,
}
impl GPUSpectrumPtexTexture {
pub fn evaluate(
&self,
ctx: &TextureEvalContext,
lambda: &SampledWavelengths,
) -> SampledSpectrum {
let index = (ctx.face_index as u32).clamp(0, self.n_faces.saturating_sub(1));
let rgb = unsafe { &*self.face_values.add(index as usize) };
let s_rgb = self.colorspaces.srgb;
match self.spectrum_type {
SpectrumType::Unbounded => RGBUnboundedSpectrum::new(&s_rgb, *rgb).sample(lambda),
SpectrumType::Albedo => {
let clamped_rgb = rgb.clamp(0.0, 1.0);
RGBAlbedoSpectrum::new(&s_rgb, clamped_rgb).sample(lambda)
}
SpectrumType::Illuminant => RGBIlluminantSpectrum::new(&s_rgb, *rgb).sample(lambda),
}
}
}