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, 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), } } }