105 lines
3.1 KiB
Rust
105 lines
3.1 KiB
Rust
use crate::Float;
|
|
use crate::core::color::{RGB, XYZ};
|
|
use crate::core::spectrum::SpectrumTrait;
|
|
use crate::core::texture::{SpectrumType, TextureEvalContext, TextureMapping2D};
|
|
use crate::spectra::{
|
|
RGBAlbedoSpectrum, RGBColorSpace, RGBIlluminantSpectrum, RGBUnboundedSpectrum, SampledSpectrum,
|
|
SampledWavelengths,
|
|
};
|
|
|
|
/* GPU heavy code, dont know if this will ever work the way Im doing things.
|
|
* Leaving it here isolated, for careful handling */
|
|
|
|
#[repr(C)]
|
|
#[derive(Clone, Debug, Copy)]
|
|
pub struct GPUSpectrumImageTexture {
|
|
pub mapping: TextureMapping2D,
|
|
pub tex_obj: u64,
|
|
pub scale: Float,
|
|
pub invert: bool,
|
|
pub is_single_channel: bool,
|
|
pub color_space: RGBColorSpace,
|
|
pub spectrum_type: SpectrumType,
|
|
}
|
|
|
|
impl GPUSpectrumImageTexture {
|
|
pub fn evaluate(
|
|
&self,
|
|
ctx: &TextureEvalContext,
|
|
lambda: &SampledWavelengths,
|
|
) -> SampledSpectrum {
|
|
#[cfg(not(feature = "cuda"))]
|
|
{
|
|
return SampledSpectrum::zero();
|
|
}
|
|
|
|
#[cfg(feature = "cuda")]
|
|
{
|
|
use cuda_std::intrinsics;
|
|
let c = self.mapping.map(ctx);
|
|
let u = c.st.x();
|
|
let v = 1.0 - c.st.y();
|
|
|
|
let d_p_dx = [c.dsdx, c.dtdx];
|
|
let d_p_dy = [c.dsdy, c.dtdy];
|
|
|
|
let tex_color = if self.is_single_channel {
|
|
let val: Float =
|
|
unsafe { intrinsics::tex2d_grad(self.tex_obj, u, v, d_p_dx, d_p_dy) };
|
|
RGB::new(val, val, val)
|
|
} else {
|
|
let val: [Float; 4] =
|
|
unsafe { intrinsics::tex2d_grad(self.tex_obj, u, v, d_p_dx, d_p_dy) };
|
|
RGB::new(val[0], val[1], val[2])
|
|
};
|
|
|
|
let mut rgb = tex_color * self.scale;
|
|
if self.invert {
|
|
rgb = (RGB::new(1.0, 1.0, 1.0) - rgb).clamp_zero();
|
|
}
|
|
|
|
match self.spectrum_type {
|
|
SpectrumType::Unbounded => {
|
|
RGBUnboundedSpectrum::new(&self.color_space, rgb).sample(lambda)
|
|
}
|
|
SpectrumType::Albedo => {
|
|
RGBAlbedoSpectrum::new(&self.color_space, rgb.clamp(0.0, 1.0)).sample(lambda)
|
|
}
|
|
_ => RGBIlluminantSpectrum::new(&self.color_space, rgb).sample(lambda),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Copy, Clone)]
|
|
pub struct GPUFloatImageTexture {
|
|
pub mapping: TextureMapping2D,
|
|
pub tex_obj: u64,
|
|
pub scale: Float,
|
|
pub invert: bool,
|
|
}
|
|
|
|
impl GPUFloatImageTexture {
|
|
pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
|
|
#[cfg(not(feature = "cuda"))]
|
|
{
|
|
return 0.;
|
|
}
|
|
#[cfg(feature = "cuda")]
|
|
{
|
|
use cuda_std::intrinsics;
|
|
let c = self.mapping.map(ctx);
|
|
let u = c.st.x();
|
|
let v = 1.0 - c.st.y();
|
|
let d_p_dx = [c.dsdx, c.dtdx];
|
|
let d_p_dy = [c.dsdy, c.dtdy];
|
|
let val: Float = unsafe { intrinsics::tex2d_grad(self.tex_obj, u, v, d_p_dx, d_p_dy) };
|
|
|
|
if self.invert {
|
|
return (1. - v).max(0.);
|
|
} else {
|
|
return v;
|
|
}
|
|
}
|
|
}
|
|
}
|