use crate::Float; use crate::core::color::RGB; use crate::core::spectrum::{SpectrumTrait, StandardSpectra}; use crate::core::texture::{SpectrumType, TextureEvalContext}; use crate::spectra::{ RGBAlbedoSpectrum, RGBColorSpace, RGBIlluminantSpectrum, RGBUnboundedSpectrum, SampledSpectrum, SampledWavelengths, StandardColorSpaces, }; use crate::utils::ptr::{Ptr, Slice}; #[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: Slice, pub n_faces: u32, pub spectrum_type: SpectrumType, pub colorspaces: StandardColorSpaces, } impl GPUSpectrumPtexTexture { pub fn evaluate( &self, ctx: &TextureEvalContext, lambda: &SampledWavelengths, ) -> SampledSpectrum { let index = ctx.face_index.clamp(0, self.n_faces.saturating_sub(1)); let rgb = self.face_values[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), } } }