Major overhaul to Texture handling

This commit is contained in:
Wito Wiala 2026-06-06 18:34:29 +01:00
parent 853e980e83
commit 4e1b3619f4
23 changed files with 407 additions and 355 deletions

View file

@ -1,8 +1,8 @@
use crate::core::color::{ColorEncoding, ColorEncodingTrait, LINEAR}; use crate::core::color::{ColorEncoding, ColorEncodingTrait, LINEAR};
use crate::core::geometry::{Bounds2f, Point2f, Point2fi, Point2i}; use crate::core::geometry::{Bounds2f, Point2f, Point2fi, Point2i};
use crate::utils::math::{f16_to_f32_software, lerp, square}; use crate::utils::math::{f16_to_f32_software, lerp, square};
use crate::{gvec_with_capacity, Float, GVec}; use crate::{gvec_with_capacity, Float, GVec, Ptr};
use anyhow::{Result, bail}; use anyhow::{bail, Result};
use core::hash; use core::hash;
use core::ops::{Deref, DerefMut}; use core::ops::{Deref, DerefMut};
use num_traits::Float as NumFloat; use num_traits::Float as NumFloat;
@ -23,7 +23,7 @@ impl WrapMode {
"black" => Ok(WrapMode::Black), "black" => Ok(WrapMode::Black),
"repeat" => Ok(WrapMode::Repeat), "repeat" => Ok(WrapMode::Repeat),
"octahedralsphere" => Ok(WrapMode::OctahedralSphere), "octahedralsphere" => Ok(WrapMode::OctahedralSphere),
_ => bail!("{:?}: wrap mode unknown", name) _ => bail!("{:?}: wrap mode unknown", name),
} }
} }
} }
@ -236,6 +236,17 @@ pub struct Image {
pub pixels: Pixels, pub pixels: Pixels,
} }
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct ImageView {
pub pixels: *const u8,
pub byte_len: usize,
pub resolution: Point2i,
pub n_channels: i32,
pub format: PixelFormat,
pub encoding: ColorEncoding,
}
impl Image { impl Image {
pub fn new( pub fn new(
format: PixelFormat, format: PixelFormat,
@ -472,3 +483,34 @@ impl Image {
false false
} }
} }
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum FilterFunction {
Point,
Bilinear,
Trilinear,
Ewa,
}
impl FilterFunction {
pub fn parse(name: &str) -> Result<FilterFunction> {
match name {
"ewa" | "EWA" => Ok(FilterFunction::Ewa),
"trilinear" => Ok(FilterFunction::Trilinear),
"bilinear" => Ok(FilterFunction::Bilinear),
"point" => Ok(FilterFunction::Point),
_ => bail!("Filter function unknown"),
}
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug)]
pub struct ImagePyramid {
pub levels: *const Ptr<Image>,
pub level_count: u32,
pub wrap_mode: WrapMode,
pub filter: FilterFunction,
pub max_aniso: f32,
}

View file

@ -15,7 +15,7 @@ use crate::core::material::{
use crate::core::medium::{Medium, MediumInterface, PhaseFunction}; use crate::core::medium::{Medium, MediumInterface, PhaseFunction};
use crate::core::sampler::{Sampler, SamplerTrait}; use crate::core::sampler::{Sampler, SamplerTrait};
use crate::core::shape::Shape; use crate::core::shape::Shape;
use crate::core::texture::{GPUFloatTexture, UniversalTextureEvaluator}; use crate::core::texture::{FloatTexture, UniversalTextureEvaluator};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::Ptr;
use crate::utils::math::{clamp, difference_of_products, square}; use crate::utils::math::{clamp, difference_of_products, square};
@ -347,7 +347,7 @@ impl SurfaceInteraction {
pub fn compute_bump_geom( pub fn compute_bump_geom(
&mut self, &mut self,
tex_eval: &UniversalTextureEvaluator, tex_eval: &UniversalTextureEvaluator,
displacement: Ptr<GPUFloatTexture>, displacement: Ptr<FloatTexture>,
normal_image: Ptr<Image>, normal_image: Ptr<Image>,
) { ) {
let ctx = NormalBumpEvalContext::from(&*self); let ctx = NormalBumpEvalContext::from(&*self);

View file

@ -14,7 +14,7 @@ use crate::core::interaction::{Interaction, InteractionTrait, ShadingGeom, Surfa
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::core::texture::{ use crate::core::texture::{
GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext, TextureEvaluator, FloatTexture, SpectrumTexture, TextureEvalContext, TextureEvaluator,
}; };
use crate::materials::*; use crate::materials::*;
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
@ -122,7 +122,7 @@ pub fn normal_map(normal_map: &Image, ctx: &NormalBumpEvalContext) -> (Vector3f,
pub fn bump_map<T: TextureEvaluator>( pub fn bump_map<T: TextureEvaluator>(
tex_eval: &T, tex_eval: &T,
displacement: &GPUFloatTexture, displacement: &FloatTexture,
ctx: &NormalBumpEvalContext, ctx: &NormalBumpEvalContext,
) -> (Vector3f, Vector3f) { ) -> (Vector3f, Vector3f) {
debug_assert!(tex_eval.can_evaluate(&[Ptr::from(displacement)], &[])); debug_assert!(tex_eval.can_evaluate(&[Ptr::from(displacement)], &[]));
@ -174,7 +174,7 @@ pub trait MaterialTrait {
fn can_evaluate_textures(&self, tex_eval: &dyn TextureEvaluator) -> bool; fn can_evaluate_textures(&self, tex_eval: &dyn TextureEvaluator) -> bool;
fn get_normal_map(&self) -> Option<&Image>; fn get_normal_map(&self) -> Option<&Image>;
fn get_displacement(&self) -> Ptr<GPUFloatTexture>; fn get_displacement(&self) -> Ptr<FloatTexture>;
fn has_subsurface_scattering(&self) -> bool; fn has_subsurface_scattering(&self) -> bool;
} }

View file

@ -4,7 +4,7 @@ use num_traits::{Float as NumFloat, Num, NumCast, PrimInt};
use crate::core::light::LightTrait; use crate::core::light::LightTrait;
use crate::core::shape::Shape; use crate::core::shape::Shape;
use crate::core::texture::GPUFloatTexture; use crate::core::texture::FloatTexture;
use crate::lights::*; use crate::lights::*;
use crate::spectra::{DenselySampledSpectrum, RGBColorSpace}; use crate::spectra::{DenselySampledSpectrum, RGBColorSpace};
use crate::utils::Ptr; use crate::utils::Ptr;

View file

@ -6,7 +6,7 @@ use crate::core::material::Material;
use crate::core::medium::{Medium, MediumInterface}; use crate::core::medium::{Medium, MediumInterface};
use crate::core::pbrt::Float; use crate::core::pbrt::Float;
use crate::core::shape::{Shape, ShapeIntersection, ShapeTrait}; use crate::core::shape::{Shape, ShapeIntersection, ShapeTrait};
use crate::core::texture::{GPUFloatTexture, TextureEvalContext}; use crate::core::texture::{FloatTexture, TextureEvalContext};
use crate::utils::hash::hash_float; use crate::utils::hash::hash_float;
use crate::utils::transform::{AnimatedTransform, Transform}; use crate::utils::transform::{AnimatedTransform, Transform};
use crate::utils::Ptr; use crate::utils::Ptr;
@ -29,7 +29,7 @@ pub struct GeometricPrimitive {
pub material: Ptr<Material>, pub material: Ptr<Material>,
pub area_light: Ptr<Light>, pub area_light: Ptr<Light>,
pub medium_interface: MediumInterface, pub medium_interface: MediumInterface,
pub alpha: Ptr<GPUFloatTexture>, pub alpha: Ptr<FloatTexture>,
} }
unsafe impl Send for GeometricPrimitive {} unsafe impl Send for GeometricPrimitive {}

View file

@ -341,34 +341,34 @@ impl From<&Interaction> for TextureEvalContext {
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub enum GPUFloatTexture { pub enum FloatTexture {
Constant(FloatConstantTexture), Constant(FloatConstantTexture),
DirectionMix(GPUFloatDirectionMixTexture), DirectionMix(FloatDirectionMixTexture),
Scaled(GPUFloatScaledTexture), Scaled(FloatScaledTexture),
Bilerp(FloatBilerpTexture), Bilerp(FloatBilerpTexture),
Checkerboard(FloatCheckerboardTexture), Checkerboard(FloatCheckerboardTexture),
Dots(FloatDotsTexture), Dots(FloatDotsTexture),
FBm(FBmTexture), FBm(FBmTexture),
Windy(WindyTexture), Windy(WindyTexture),
Wrinkled(WrinkledTexture), Wrinkled(WrinkledTexture),
Image(GPUFloatImageTexture), Image(FloatImageTexture),
Mix(GPUFloatMixTexture), Mix(FloatMixTexture),
} }
impl GPUFloatTexture { impl FloatTexture {
pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float { pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
match self { match self {
GPUFloatTexture::Constant(t) => t.evaluate(ctx), FloatTexture::Constant(t) => t.evaluate(ctx),
GPUFloatTexture::DirectionMix(t) => t.evaluate(ctx), FloatTexture::DirectionMix(t) => t.evaluate(ctx),
GPUFloatTexture::Scaled(t) => t.evaluate(ctx), FloatTexture::Scaled(t) => t.evaluate(ctx),
GPUFloatTexture::Bilerp(t) => t.evaluate(ctx), FloatTexture::Bilerp(t) => t.evaluate(ctx),
GPUFloatTexture::Checkerboard(t) => t.evaluate(ctx), FloatTexture::Checkerboard(t) => t.evaluate(ctx),
GPUFloatTexture::Dots(t) => t.evaluate(ctx), FloatTexture::Dots(t) => t.evaluate(ctx),
GPUFloatTexture::FBm(t) => t.evaluate(ctx), FloatTexture::FBm(t) => t.evaluate(ctx),
GPUFloatTexture::Windy(t) => t.evaluate(ctx), FloatTexture::Windy(t) => t.evaluate(ctx),
GPUFloatTexture::Wrinkled(t) => t.evaluate(ctx), FloatTexture::Wrinkled(t) => t.evaluate(ctx),
GPUFloatTexture::Image(t) => t.evaluate(ctx), FloatTexture::Image(t) => t.evaluate(ctx),
GPUFloatTexture::Mix(t) => t.evaluate(ctx), FloatTexture::Mix(t) => t.evaluate(ctx),
} }
} }
} }
@ -384,51 +384,51 @@ pub enum SpectrumType {
#[repr(C)] #[repr(C)]
#[enum_dispatch] #[enum_dispatch]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub enum GPUSpectrumTexture { pub enum SpectrumTexture {
Constant(SpectrumConstantTexture), Constant(SpectrumConstantTexture),
Bilerp(SpectrumBilerpTexture), Bilerp(SpectrumBilerpTexture),
Checkerboard(SpectrumCheckerboardTexture), Checkerboard(SpectrumCheckerboardTexture),
Marble(MarbleTexture), Marble(MarbleTexture),
DirectionMix(GPUSpectrumDirectionMixTexture), DirectionMix(SpectrumDirectionMixTexture),
Dots(SpectrumDotsTexture), Dots(SpectrumDotsTexture),
Scaled(GPUSpectrumScaledTexture), Scaled(SpectrumScaledTexture),
Image(GPUSpectrumImageTexture), Image(SpectrumImageTexture),
Mix(GPUSpectrumMixTexture), Mix(SpectrumMixTexture),
} }
impl GPUSpectrumTexture { impl SpectrumTexture {
pub fn evaluate( pub fn evaluate(
&self, &self,
ctx: &TextureEvalContext, ctx: &TextureEvalContext,
lambda: &SampledWavelengths, lambda: &SampledWavelengths,
) -> SampledSpectrum { ) -> SampledSpectrum {
match self { match self {
GPUSpectrumTexture::Constant(t) => t.evaluate(ctx, lambda), SpectrumTexture::Constant(t) => t.evaluate(ctx, lambda),
GPUSpectrumTexture::Bilerp(t) => t.evaluate(ctx, lambda), SpectrumTexture::Bilerp(t) => t.evaluate(ctx, lambda),
GPUSpectrumTexture::Checkerboard(t) => t.evaluate(ctx, lambda), SpectrumTexture::Checkerboard(t) => t.evaluate(ctx, lambda),
GPUSpectrumTexture::Marble(t) => t.evaluate(ctx, lambda), SpectrumTexture::Marble(t) => t.evaluate(ctx, lambda),
GPUSpectrumTexture::DirectionMix(t) => t.evaluate(ctx, lambda), SpectrumTexture::DirectionMix(t) => t.evaluate(ctx, lambda),
GPUSpectrumTexture::Dots(t) => t.evaluate(ctx, lambda), SpectrumTexture::Dots(t) => t.evaluate(ctx, lambda),
GPUSpectrumTexture::Scaled(t) => t.evaluate(ctx, lambda), SpectrumTexture::Scaled(t) => t.evaluate(ctx, lambda),
GPUSpectrumTexture::Image(t) => t.evaluate(ctx, lambda), SpectrumTexture::Image(t) => t.evaluate(ctx, lambda),
GPUSpectrumTexture::Mix(t) => t.evaluate(ctx, lambda), SpectrumTexture::Mix(t) => t.evaluate(ctx, lambda),
} }
} }
} }
pub trait TextureEvaluator: Send + Sync { pub trait TextureEvaluator: Send + Sync {
fn evaluate_float(&self, tex: &GPUFloatTexture, ctx: &TextureEvalContext) -> Float; fn evaluate_float(&self, tex: &FloatTexture, ctx: &TextureEvalContext) -> Float;
fn evaluate_spectrum( fn evaluate_spectrum(
&self, &self,
tex: &GPUSpectrumTexture, tex: &SpectrumTexture,
ctx: &TextureEvalContext, ctx: &TextureEvalContext,
lambda: &SampledWavelengths, lambda: &SampledWavelengths,
) -> SampledSpectrum; ) -> SampledSpectrum;
fn can_evaluate( fn can_evaluate(
&self, &self,
_ftex: &[Ptr<GPUFloatTexture>], _ftex: &[Ptr<FloatTexture>],
_stex: &[Ptr<GPUSpectrumTexture>], _stex: &[Ptr<SpectrumTexture>],
) -> bool; ) -> bool;
} }
@ -437,13 +437,13 @@ pub trait TextureEvaluator: Send + Sync {
pub struct UniversalTextureEvaluator; pub struct UniversalTextureEvaluator;
impl TextureEvaluator for UniversalTextureEvaluator { impl TextureEvaluator for UniversalTextureEvaluator {
fn evaluate_float(&self, tex: &GPUFloatTexture, ctx: &TextureEvalContext) -> Float { fn evaluate_float(&self, tex: &FloatTexture, ctx: &TextureEvalContext) -> Float {
tex.evaluate(ctx) tex.evaluate(ctx)
} }
fn evaluate_spectrum( fn evaluate_spectrum(
&self, &self,
tex: &GPUSpectrumTexture, tex: &SpectrumTexture,
ctx: &TextureEvalContext, ctx: &TextureEvalContext,
lambda: &SampledWavelengths, lambda: &SampledWavelengths,
) -> SampledSpectrum { ) -> SampledSpectrum {
@ -452,8 +452,8 @@ impl TextureEvaluator for UniversalTextureEvaluator {
fn can_evaluate( fn can_evaluate(
&self, &self,
_float_textures: &[Ptr<GPUFloatTexture>], _float_textures: &[Ptr<FloatTexture>],
_spectrum_textures: &[Ptr<GPUSpectrumTexture>], _spectrum_textures: &[Ptr<SpectrumTexture>],
) -> bool { ) -> bool {
true true
} }
@ -464,39 +464,39 @@ impl TextureEvaluator for UniversalTextureEvaluator {
pub struct BasicTextureEvaluator; pub struct BasicTextureEvaluator;
impl TextureEvaluator for BasicTextureEvaluator { impl TextureEvaluator for BasicTextureEvaluator {
fn evaluate_float(&self, tex: &GPUFloatTexture, ctx: &TextureEvalContext) -> Float { fn evaluate_float(&self, tex: &FloatTexture, ctx: &TextureEvalContext) -> Float {
match tex { match tex {
GPUFloatTexture::Constant(t) => t.evaluate(ctx), FloatTexture::Constant(t) => t.evaluate(ctx),
GPUFloatTexture::Image(t) => t.evaluate(ctx), FloatTexture::Image(t) => t.evaluate(ctx),
_ => 0.0, _ => 0.0,
} }
} }
fn evaluate_spectrum( fn evaluate_spectrum(
&self, &self,
tex: &GPUSpectrumTexture, tex: &SpectrumTexture,
ctx: &TextureEvalContext, ctx: &TextureEvalContext,
lambda: &SampledWavelengths, lambda: &SampledWavelengths,
) -> SampledSpectrum { ) -> SampledSpectrum {
match tex { match tex {
GPUSpectrumTexture::Constant(t) => t.evaluate(ctx, lambda), SpectrumTexture::Constant(t) => t.evaluate(ctx, lambda),
GPUSpectrumTexture::Image(t) => t.evaluate(ctx, lambda), SpectrumTexture::Image(t) => t.evaluate(ctx, lambda),
_ => SampledSpectrum::new(0.0), _ => SampledSpectrum::new(0.0),
} }
} }
fn can_evaluate( fn can_evaluate(
&self, &self,
ftex: &[Ptr<GPUFloatTexture>], ftex: &[Ptr<FloatTexture>],
stex: &[Ptr<GPUSpectrumTexture>], stex: &[Ptr<SpectrumTexture>],
) -> bool { ) -> bool {
for t in ftex { for t in ftex {
if t.is_null() { if t.is_null() {
continue; continue;
} }
match t.get().unwrap() { match t.get().unwrap() {
GPUFloatTexture::Constant(_) FloatTexture::Constant(_)
| GPUFloatTexture::Image(_) => {} | FloatTexture::Image(_) => {}
_ => return false, _ => return false,
} }
} }
@ -505,8 +505,8 @@ impl TextureEvaluator for BasicTextureEvaluator {
continue; continue;
} }
match t.get().unwrap() { match t.get().unwrap() {
GPUSpectrumTexture::Constant(_) SpectrumTexture::Constant(_)
| GPUSpectrumTexture::Image(_) => {} | SpectrumTexture::Image(_) => {}
_ => return false, _ => return false,
} }
} }

View file

@ -11,7 +11,7 @@ use crate::core::medium::MediumInterface;
use crate::core::shape::{Shape, ShapeSampleContext, ShapeTrait}; use crate::core::shape::{Shape, ShapeSampleContext, ShapeTrait};
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::core::texture::{ use crate::core::texture::{
GPUFloatTexture, TextureEvalContext, TextureEvaluator, UniversalTextureEvaluator, FloatTexture, TextureEvalContext, TextureEvaluator, UniversalTextureEvaluator,
}; };
use crate::spectra::*; use crate::spectra::*;
use crate::utils::hash::hash_float; use crate::utils::hash::hash_float;
@ -24,7 +24,7 @@ use num_traits::Float as NumFloat;
pub struct DiffuseAreaLight { pub struct DiffuseAreaLight {
pub base: LightBase, pub base: LightBase,
pub shape: Ptr<Shape>, pub shape: Ptr<Shape>,
pub alpha: Ptr<GPUFloatTexture>, pub alpha: Ptr<FloatTexture>,
pub colorspace: Ptr<RGBColorSpace>, pub colorspace: Ptr<RGBColorSpace>,
pub lemit: Ptr<DenselySampledSpectrum>, pub lemit: Ptr<DenselySampledSpectrum>,
pub image: Ptr<Image>, pub image: Ptr<Image>,

View file

@ -8,7 +8,7 @@ use crate::core::image::Image;
use crate::core::material::{Material, MaterialEvalContext, MaterialTrait}; use crate::core::material::{Material, MaterialEvalContext, MaterialTrait};
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::core::texture::{FloatTexture, SpectrumTexture, TextureEvaluator};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::Ptr;
use crate::utils::math::clamp; use crate::utils::math::clamp;
@ -17,13 +17,13 @@ use crate::utils::math::clamp;
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct CoatedDiffuseMaterial { pub struct CoatedDiffuseMaterial {
pub normal_map: Ptr<Image>, pub normal_map: Ptr<Image>,
pub displacement: Ptr<GPUFloatTexture>, pub displacement: Ptr<FloatTexture>,
pub reflectance: Ptr<GPUSpectrumTexture>, pub reflectance: Ptr<SpectrumTexture>,
pub albedo: Ptr<GPUSpectrumTexture>, pub albedo: Ptr<SpectrumTexture>,
pub u_roughness: Ptr<GPUFloatTexture>, pub u_roughness: Ptr<FloatTexture>,
pub v_roughness: Ptr<GPUFloatTexture>, pub v_roughness: Ptr<FloatTexture>,
pub thickness: Ptr<GPUFloatTexture>, pub thickness: Ptr<FloatTexture>,
pub g: Ptr<GPUFloatTexture>, pub g: Ptr<FloatTexture>,
pub eta: Ptr<Spectrum>, pub eta: Ptr<Spectrum>,
pub max_depth: u32, pub max_depth: u32,
pub n_samples: u32, pub n_samples: u32,
@ -34,13 +34,13 @@ pub struct CoatedDiffuseMaterial {
impl CoatedDiffuseMaterial { impl CoatedDiffuseMaterial {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
reflectance: Ptr<GPUSpectrumTexture>, reflectance: Ptr<SpectrumTexture>,
u_roughness: Ptr<GPUFloatTexture>, u_roughness: Ptr<FloatTexture>,
v_roughness: Ptr<GPUFloatTexture>, v_roughness: Ptr<FloatTexture>,
thickness: Ptr<GPUFloatTexture>, thickness: Ptr<FloatTexture>,
albedo: Ptr<GPUSpectrumTexture>, albedo: Ptr<SpectrumTexture>,
g: Ptr<GPUFloatTexture>, g: Ptr<FloatTexture>,
displacement: Ptr<GPUFloatTexture>, displacement: Ptr<FloatTexture>,
eta: Ptr<Spectrum>, eta: Ptr<Spectrum>,
normal_map: Ptr<Image>, normal_map: Ptr<Image>,
remap_roughness: bool, remap_roughness: bool,
@ -141,7 +141,7 @@ impl MaterialTrait for CoatedDiffuseMaterial {
Some(&*self.normal_map) Some(&*self.normal_map)
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> Ptr<FloatTexture> {
self.displacement self.displacement
} }
@ -153,18 +153,18 @@ impl MaterialTrait for CoatedDiffuseMaterial {
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct CoatedConductorMaterial { pub struct CoatedConductorMaterial {
displacement: Ptr<GPUFloatTexture>, displacement: Ptr<FloatTexture>,
interface_uroughness: Ptr<GPUFloatTexture>, interface_uroughness: Ptr<FloatTexture>,
interface_vroughness: Ptr<GPUFloatTexture>, interface_vroughness: Ptr<FloatTexture>,
thickness: Ptr<GPUFloatTexture>, thickness: Ptr<FloatTexture>,
interface_eta: Ptr<Spectrum>, interface_eta: Ptr<Spectrum>,
g: Ptr<GPUFloatTexture>, g: Ptr<FloatTexture>,
albedo: Ptr<GPUSpectrumTexture>, albedo: Ptr<SpectrumTexture>,
conductor_uroughness: Ptr<GPUFloatTexture>, conductor_uroughness: Ptr<FloatTexture>,
conductor_vroughness: Ptr<GPUFloatTexture>, conductor_vroughness: Ptr<FloatTexture>,
conductor_eta: Ptr<GPUSpectrumTexture>, conductor_eta: Ptr<SpectrumTexture>,
k: Ptr<GPUSpectrumTexture>, k: Ptr<SpectrumTexture>,
reflectance: Ptr<GPUSpectrumTexture>, reflectance: Ptr<SpectrumTexture>,
normal_map: Ptr<Image>, normal_map: Ptr<Image>,
max_depth: u32, max_depth: u32,
n_samples: u32, n_samples: u32,
@ -175,17 +175,17 @@ pub struct CoatedConductorMaterial {
impl CoatedConductorMaterial { impl CoatedConductorMaterial {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
displacement: Ptr<GPUFloatTexture>, displacement: Ptr<FloatTexture>,
interface_uroughness: Ptr<GPUFloatTexture>, interface_uroughness: Ptr<FloatTexture>,
interface_vroughness: Ptr<GPUFloatTexture>, interface_vroughness: Ptr<FloatTexture>,
thickness: Ptr<GPUFloatTexture>, thickness: Ptr<FloatTexture>,
g: Ptr<GPUFloatTexture>, g: Ptr<FloatTexture>,
albedo: Ptr<GPUSpectrumTexture>, albedo: Ptr<SpectrumTexture>,
conductor_uroughness: Ptr<GPUFloatTexture>, conductor_uroughness: Ptr<FloatTexture>,
conductor_vroughness: Ptr<GPUFloatTexture>, conductor_vroughness: Ptr<FloatTexture>,
conductor_eta: Ptr<GPUSpectrumTexture>, conductor_eta: Ptr<SpectrumTexture>,
k: Ptr<GPUSpectrumTexture>, k: Ptr<SpectrumTexture>,
reflectance: Ptr<GPUSpectrumTexture>, reflectance: Ptr<SpectrumTexture>,
normal_map: Ptr<Image>, normal_map: Ptr<Image>,
interface_eta: Ptr<Spectrum>, interface_eta: Ptr<Spectrum>,
max_depth: u32, max_depth: u32,
@ -337,7 +337,7 @@ impl MaterialTrait for CoatedConductorMaterial {
self.normal_map.get() self.normal_map.get()
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> Ptr<FloatTexture> {
self.displacement self.displacement
} }

View file

@ -10,37 +10,37 @@ use crate::core::image::Image;
use crate::core::material::{Material, MaterialEvalContext, MaterialTrait}; use crate::core::material::{Material, MaterialEvalContext, MaterialTrait};
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::core::texture::{FloatTexture, SpectrumTexture, TextureEvaluator};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::textures::GPUSpectrumMixTexture; use crate::textures::SpectrumMixTexture;
use crate::utils::Ptr; use crate::utils::Ptr;
use crate::utils::math::clamp; use crate::utils::math::clamp;
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct HairMaterial { pub struct HairMaterial {
pub sigma_a: Ptr<GPUSpectrumTexture>, pub sigma_a: Ptr<SpectrumTexture>,
pub color: Ptr<GPUSpectrumTexture>, pub color: Ptr<SpectrumTexture>,
pub eumelanin: Ptr<GPUFloatTexture>, pub eumelanin: Ptr<FloatTexture>,
pub pheomelanin: Ptr<GPUFloatTexture>, pub pheomelanin: Ptr<FloatTexture>,
pub eta: Ptr<GPUFloatTexture>, pub eta: Ptr<FloatTexture>,
pub beta_m: Ptr<GPUFloatTexture>, pub beta_m: Ptr<FloatTexture>,
pub beta_n: Ptr<GPUFloatTexture>, pub beta_n: Ptr<FloatTexture>,
pub alpha: Ptr<GPUFloatTexture>, pub alpha: Ptr<FloatTexture>,
} }
impl HairMaterial { impl HairMaterial {
#[cfg(not(target_os = "cuda"))] #[cfg(not(target_os = "cuda"))]
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn new( pub fn new(
sigma_a: Ptr<GPUSpectrumTexture>, sigma_a: Ptr<SpectrumTexture>,
color: Ptr<GPUSpectrumTexture>, color: Ptr<SpectrumTexture>,
eumelanin: Ptr<GPUFloatTexture>, eumelanin: Ptr<FloatTexture>,
pheomelanin: Ptr<GPUFloatTexture>, pheomelanin: Ptr<FloatTexture>,
eta: Ptr<GPUFloatTexture>, eta: Ptr<FloatTexture>,
beta_m: Ptr<GPUFloatTexture>, beta_m: Ptr<FloatTexture>,
beta_n: Ptr<GPUFloatTexture>, beta_n: Ptr<FloatTexture>,
alpha: Ptr<GPUFloatTexture>, alpha: Ptr<FloatTexture>,
) -> Self { ) -> Self {
Self { Self {
sigma_a, sigma_a,
@ -81,7 +81,7 @@ impl MaterialTrait for HairMaterial {
todo!() todo!()
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> Ptr<FloatTexture> {
Ptr::null() Ptr::null()
} }
@ -93,7 +93,7 @@ impl MaterialTrait for HairMaterial {
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct MeasuredMaterial { pub struct MeasuredMaterial {
pub displacement: Ptr<GPUFloatTexture>, pub displacement: Ptr<FloatTexture>,
pub normal_map: Ptr<Image>, pub normal_map: Ptr<Image>,
pub brdf: Ptr<MeasuredBxDFData>, pub brdf: Ptr<MeasuredBxDFData>,
} }
@ -126,7 +126,7 @@ impl MaterialTrait for MeasuredMaterial {
Some(&*self.normal_map) Some(&*self.normal_map)
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> Ptr<FloatTexture> {
self.displacement self.displacement
} }
@ -139,15 +139,15 @@ impl MaterialTrait for MeasuredMaterial {
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct SubsurfaceMaterial { pub struct SubsurfaceMaterial {
pub normal_map: Ptr<Image>, pub normal_map: Ptr<Image>,
pub displacement: Ptr<GPUFloatTexture>, pub displacement: Ptr<FloatTexture>,
pub sigma_a: Ptr<GPUSpectrumTexture>, pub sigma_a: Ptr<SpectrumTexture>,
pub sigma_s: Ptr<GPUSpectrumMixTexture>, pub sigma_s: Ptr<SpectrumMixTexture>,
pub reflectance: Ptr<GPUSpectrumMixTexture>, pub reflectance: Ptr<SpectrumMixTexture>,
pub mfp: Ptr<GPUSpectrumMixTexture>, pub mfp: Ptr<SpectrumMixTexture>,
pub eta: Float, pub eta: Float,
pub scale: Float, pub scale: Float,
pub u_roughness: Ptr<GPUFloatTexture>, pub u_roughness: Ptr<FloatTexture>,
pub v_roughness: Ptr<GPUFloatTexture>, pub v_roughness: Ptr<FloatTexture>,
pub remap_roughness: bool, pub remap_roughness: bool,
pub table: Ptr<BSSRDFTable>, pub table: Ptr<BSSRDFTable>,
} }
@ -178,7 +178,7 @@ impl MaterialTrait for SubsurfaceMaterial {
todo!() todo!()
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> Ptr<FloatTexture> {
todo!() todo!()
} }

View file

@ -8,7 +8,7 @@ use crate::core::image::Image;
use crate::core::material::{Material, MaterialEvalContext, MaterialTrait}; use crate::core::material::{Material, MaterialEvalContext, MaterialTrait};
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::core::texture::{FloatTexture, SpectrumTexture, TextureEvaluator};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::math::clamp; use crate::utils::math::clamp;
use crate::utils::Ptr; use crate::utils::Ptr;
@ -17,24 +17,24 @@ use crate::utils::Ptr;
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct ConductorMaterial { pub struct ConductorMaterial {
pub normal_map: Ptr<Image>, pub normal_map: Ptr<Image>,
pub reflectance: Ptr<GPUSpectrumTexture>, pub reflectance: Ptr<SpectrumTexture>,
pub eta: Ptr<GPUSpectrumTexture>, pub eta: Ptr<SpectrumTexture>,
pub k: Ptr<GPUSpectrumTexture>, pub k: Ptr<SpectrumTexture>,
pub u_roughness: Ptr<GPUFloatTexture>, pub u_roughness: Ptr<FloatTexture>,
pub v_roughness: Ptr<GPUFloatTexture>, pub v_roughness: Ptr<FloatTexture>,
pub displacement: Ptr<GPUFloatTexture>, pub displacement: Ptr<FloatTexture>,
pub remap_roughness: bool, pub remap_roughness: bool,
} }
impl ConductorMaterial { impl ConductorMaterial {
pub fn new( pub fn new(
normal_map: Ptr<Image>, normal_map: Ptr<Image>,
reflectance: Ptr<GPUSpectrumTexture>, reflectance: Ptr<SpectrumTexture>,
eta: Ptr<GPUSpectrumTexture>, eta: Ptr<SpectrumTexture>,
k: Ptr<GPUSpectrumTexture>, k: Ptr<SpectrumTexture>,
u_roughness: Ptr<GPUFloatTexture>, u_roughness: Ptr<FloatTexture>,
v_roughness: Ptr<GPUFloatTexture>, v_roughness: Ptr<FloatTexture>,
displacement: Ptr<GPUFloatTexture>, displacement: Ptr<FloatTexture>,
remap_roughness: bool, remap_roughness: bool,
) -> Self { ) -> Self {
Self { Self {
@ -105,7 +105,7 @@ impl MaterialTrait for ConductorMaterial {
self.normal_map.get() self.normal_map.get()
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> Ptr<FloatTexture> {
self.displacement self.displacement
} }

View file

@ -8,7 +8,7 @@ use crate::core::image::Image;
use crate::core::material::{Material, MaterialEvalContext, MaterialTrait}; use crate::core::material::{Material, MaterialEvalContext, MaterialTrait};
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::core::texture::{FloatTexture, SpectrumTexture, TextureEvaluator};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::math::clamp; use crate::utils::math::clamp;
use crate::Ptr; use crate::Ptr;
@ -17,9 +17,9 @@ use crate::Ptr;
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct DielectricMaterial { pub struct DielectricMaterial {
pub normal_map: Ptr<Image>, pub normal_map: Ptr<Image>,
pub displacement: Ptr<GPUFloatTexture>, pub displacement: Ptr<FloatTexture>,
pub u_roughness: Ptr<GPUFloatTexture>, pub u_roughness: Ptr<FloatTexture>,
pub v_roughness: Ptr<GPUFloatTexture>, pub v_roughness: Ptr<FloatTexture>,
pub eta: Ptr<Spectrum>, pub eta: Ptr<Spectrum>,
pub remap_roughness: bool, pub remap_roughness: bool,
} }
@ -71,7 +71,7 @@ impl MaterialTrait for DielectricMaterial {
Some(&*self.normal_map) Some(&*self.normal_map)
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> Ptr<FloatTexture> {
self.displacement self.displacement
} }
@ -83,7 +83,7 @@ impl MaterialTrait for DielectricMaterial {
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct ThinDielectricMaterial { pub struct ThinDielectricMaterial {
pub displacement: Ptr<GPUFloatTexture>, pub displacement: Ptr<FloatTexture>,
pub normal_map: Ptr<Image>, pub normal_map: Ptr<Image>,
pub eta: Ptr<Spectrum>, pub eta: Ptr<Spectrum>,
} }
@ -114,7 +114,7 @@ impl MaterialTrait for ThinDielectricMaterial {
Some(&*self.normal_map) Some(&*self.normal_map)
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> Ptr<FloatTexture> {
self.displacement self.displacement
} }

View file

@ -9,7 +9,7 @@ use crate::core::image::Image;
use crate::core::material::{Material, MaterialEvalContext, MaterialTrait}; use crate::core::material::{Material, MaterialEvalContext, MaterialTrait};
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::core::texture::{FloatTexture, SpectrumTexture, TextureEvaluator};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::Ptr; use crate::Ptr;
use crate::utils::math::clamp; use crate::utils::math::clamp;
@ -18,8 +18,8 @@ use crate::utils::math::clamp;
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct DiffuseMaterial { pub struct DiffuseMaterial {
pub normal_map: Ptr<Image>, pub normal_map: Ptr<Image>,
pub displacement: Ptr<GPUFloatTexture>, pub displacement: Ptr<FloatTexture>,
pub reflectance: Ptr<GPUSpectrumTexture>, pub reflectance: Ptr<SpectrumTexture>,
} }
impl MaterialTrait for DiffuseMaterial { impl MaterialTrait for DiffuseMaterial {
@ -51,7 +51,7 @@ impl MaterialTrait for DiffuseMaterial {
self.normal_map.get() self.normal_map.get()
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> Ptr<FloatTexture> {
self.displacement self.displacement
} }
@ -64,9 +64,9 @@ impl MaterialTrait for DiffuseMaterial {
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct DiffuseTransmissionMaterial { pub struct DiffuseTransmissionMaterial {
pub image: Ptr<Image>, pub image: Ptr<Image>,
pub displacement: Ptr<GPUFloatTexture>, pub displacement: Ptr<FloatTexture>,
pub reflectance: Ptr<GPUFloatTexture>, pub reflectance: Ptr<FloatTexture>,
pub transmittance: Ptr<GPUFloatTexture>, pub transmittance: Ptr<FloatTexture>,
pub scale: Float, pub scale: Float,
} }
@ -96,7 +96,7 @@ impl MaterialTrait for DiffuseTransmissionMaterial {
self.image.get() self.image.get()
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> Ptr<FloatTexture> {
self.displacement self.displacement
} }

View file

@ -8,7 +8,7 @@ use crate::core::image::Image;
use crate::core::material::{Material, MaterialEvalContext, MaterialTrait}; use crate::core::material::{Material, MaterialEvalContext, MaterialTrait};
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::core::texture::{FloatTexture, SpectrumTexture, TextureEvaluator};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::Ptr;
use crate::utils::hash::hash_float; use crate::utils::hash::hash_float;
@ -17,7 +17,7 @@ use crate::utils::math::clamp;
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct MixMaterial { pub struct MixMaterial {
pub amount: Ptr<GPUFloatTexture>, pub amount: Ptr<FloatTexture>,
pub materials: [Ptr<Material>; 2], pub materials: [Ptr<Material>; 2],
} }
@ -73,7 +73,7 @@ impl MaterialTrait for MixMaterial {
None None
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> Ptr<FloatTexture> {
panic!( panic!(
"MixMaterial::get_displacement() shouldn't be called. \ "MixMaterial::get_displacement() shouldn't be called. \
Displacement is not supported on Mix materials directly." Displacement is not supported on Mix materials directly."

View file

@ -1,6 +1,6 @@
use crate::Float; use crate::Float;
use crate::core::texture::{ use crate::core::texture::{
GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext, TextureMapping2D, TextureMapping3D, FloatTexture, SpectrumTexture, TextureEvalContext, TextureMapping2D, TextureMapping3D,
TextureMapping3DTrait, TextureMapping3DTrait,
}; };
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
@ -46,7 +46,7 @@ fn checkerboard(
pub struct FloatCheckerboardTexture { pub struct FloatCheckerboardTexture {
pub map2d: Ptr<TextureMapping2D>, pub map2d: Ptr<TextureMapping2D>,
pub map3d: Ptr<TextureMapping3D>, pub map3d: Ptr<TextureMapping3D>,
pub tex: [Ptr<GPUFloatTexture>; 2], pub tex: [Ptr<FloatTexture>; 2],
} }
impl FloatCheckerboardTexture { impl FloatCheckerboardTexture {
@ -77,7 +77,7 @@ impl FloatCheckerboardTexture {
pub struct SpectrumCheckerboardTexture { pub struct SpectrumCheckerboardTexture {
pub map2d: Ptr<TextureMapping2D>, pub map2d: Ptr<TextureMapping2D>,
pub map3d: Ptr<TextureMapping3D>, pub map3d: Ptr<TextureMapping3D>,
pub tex: [Ptr<GPUSpectrumTexture>; 2], pub tex: [Ptr<SpectrumTexture>; 2],
} }
impl SpectrumCheckerboardTexture { impl SpectrumCheckerboardTexture {

View file

@ -1,7 +1,7 @@
use crate::Float; use crate::Float;
use crate::core::geometry::{Point2f, VectorLike}; use crate::core::geometry::{Point2f, VectorLike};
use crate::core::texture::{ use crate::core::texture::{
GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext, TextureMapping2D, FloatTexture, SpectrumTexture, TextureEvalContext, TextureMapping2D,
}; };
use crate::spectra::sampled::{SampledSpectrum, SampledWavelengths}; use crate::spectra::sampled::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::Ptr;
@ -29,8 +29,8 @@ fn inside_polka_dot(st: Point2f) -> bool {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct FloatDotsTexture { pub struct FloatDotsTexture {
pub mapping: TextureMapping2D, pub mapping: TextureMapping2D,
pub outside_dot: Ptr<GPUFloatTexture>, pub outside_dot: Ptr<FloatTexture>,
pub inside_dot: Ptr<GPUFloatTexture>, pub inside_dot: Ptr<FloatTexture>,
} }
impl FloatDotsTexture { impl FloatDotsTexture {
@ -54,8 +54,8 @@ impl FloatDotsTexture {
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct SpectrumDotsTexture { pub struct SpectrumDotsTexture {
pub mapping: TextureMapping2D, pub mapping: TextureMapping2D,
pub outside_dot: Ptr<GPUSpectrumTexture>, pub outside_dot: Ptr<SpectrumTexture>,
pub inside_dot: Ptr<GPUSpectrumTexture>, pub inside_dot: Ptr<SpectrumTexture>,
} }
impl SpectrumDotsTexture { impl SpectrumDotsTexture {

View file

@ -1,5 +1,5 @@
use crate::core::color::{RGB, XYZ}; use crate::core::color::{RGB, XYZ};
use crate::core::image::Image; use crate::core::image::{Image, WrapMode, WrapMode2D};
use crate::core::spectrum::SpectrumTrait; use crate::core::spectrum::SpectrumTrait;
use crate::core::texture::{SpectrumType, TextureEvalContext, TextureMapping2D}; use crate::core::texture::{SpectrumType, TextureEvalContext, TextureMapping2D};
use crate::spectra::{ use crate::spectra::{
@ -13,104 +13,118 @@ use crate::Float;
* Leaving it here isolated, for careful handling */ * Leaving it here isolated, for careful handling */
#[repr(C)] #[repr(C)]
#[derive(Clone, Debug, Copy)] #[derive(Clone, Debug, Copy)]
pub struct GPUSpectrumImageTexture { pub struct SpectrumImageTexture {
pub mapping: TextureMapping2D, pub wrap_mode: WrapMode,
pub tex_obj: u64, pub tex_obj: u64,
pub image: Ptr<Image>,
pub scale: Float, pub scale: Float,
pub invert: bool,
pub is_single_channel: bool,
pub color_space: Ptr<RGBColorSpace>,
pub spectrum_type: SpectrumType, pub spectrum_type: SpectrumType,
pub image: Ptr<Image>,
pub color_space: Ptr<RGBColorSpace>,
pub mapping: TextureMapping2D,
pub is_single_channel: bool,
pub invert: bool,
} }
impl GPUSpectrumImageTexture { impl SpectrumImageTexture {
#[allow(unused)]
pub fn evaluate( pub fn evaluate(
&self, &self,
ctx: &TextureEvalContext, ctx: &TextureEvalContext,
lambda: &SampledWavelengths, lambda: &SampledWavelengths,
) -> SampledSpectrum { ) -> SampledSpectrum {
#[cfg(not(feature = "cuda"))] #[cfg(feature = "cuda")]
{ if self.tex_obj != 0 {
return SampledSpectrum::zero(); // FUTURE: hardware sampling path.
// let c = self.mapping.map(ctx);
// let rgb = tex2d_grad(self.tex_obj, c.st, [c.dsdx,c.dtdx], [c.dsdy,c.dtdy]);
// return spectrum_from_rgb(rgb * self.scale, self.invert, self.spectrum_type, ...);
// Until then, fall through to software path below.
} }
#[cfg(feature = "cuda")] let Some(image) = self.image.get() else {
{ return SampledSpectrum::zero();
use cuda_std::intrinsics; };
let c = self.mapping.map(ctx); let mut c = self.mapping.map(ctx);
let u = c.st.x(); c.st[1] = 1.0 - c.st[1]; // flip V to match pbrt convention
let v = 1.0 - c.st.y();
let d_p_dx = [c.dsdx, c.dtdx]; let wrap = WrapMode2D {
let d_p_dy = [c.dsdy, c.dtdy]; uv: [self.wrap_mode; 2],
};
let tex_color = if self.is_single_channel { let rgb = if image.n_channels == 1 {
let val = 0.; let v = image.bilerp_channel_with_wrap(c.st, 0, wrap);
// let val: Float = RGB::new(v, v, v)
// unsafe { intrinsics::tex2d_grad(self.tex_obj, u, v, d_p_dx, d_p_dy) }; } else {
RGB::new(val, val, val) RGB::new(
} else { image.bilerp_channel_with_wrap(c.st, 0, wrap),
let val = [0., 0., 0., 0.]; image.bilerp_channel_with_wrap(c.st, 1, wrap),
// let val: [Float; 4] = image.bilerp_channel_with_wrap(c.st, 2, wrap),
// 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 = rgb * self.scale;
if self.invert {
let mut rgb = tex_color * self.scale; rgb = (RGB::new(1.0, 1.0, 1.0) - rgb).clamp_zero();
if self.invert { }
rgb = (RGB::new(1.0, 1.0, 1.0) - rgb).clamp_zero(); let cs = self
} .color_space
.get()
match self.spectrum_type { .expect("color_space must not be null");
SpectrumType::Unbounded => { match self.spectrum_type {
RGBUnboundedSpectrum::new(&self.color_space, rgb).sample(lambda) SpectrumType::Unbounded => RGBUnboundedSpectrum::new(cs, rgb).sample(lambda),
} SpectrumType::Albedo => RGBAlbedoSpectrum::new(cs, rgb.clamp(0.0, 1.0)).sample(lambda),
SpectrumType::Albedo => { _ => RGBIlluminantSpectrum::new(cs, rgb).sample(lambda),
RGBAlbedoSpectrum::new(&self.color_space, rgb.clamp(0.0, 1.0)).sample(lambda)
}
_ => RGBIlluminantSpectrum::new(&self.color_space, rgb).sample(lambda),
}
} }
} }
} }
#[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct GPUFloatImageTexture { pub struct FloatImageTexture {
pub image: Ptr<Image>,
pub mapping: TextureMapping2D, pub mapping: TextureMapping2D,
pub wrap_mode: WrapMode,
pub tex_obj: u64, pub tex_obj: u64,
pub scale: Float, pub scale: Float,
pub invert: bool, pub invert: bool,
} }
impl GPUFloatImageTexture { impl FloatImageTexture {
#[allow(unused_variables)] #[allow(unused_variables)]
pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float { pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
#[cfg(not(feature = "cuda"))] #[cfg(not(feature = "cuda"))]
{ {
return 0.; let wrap = WrapMode2D {
uv: [self.wrap_mode; 2],
};
let mut c = self.mapping.map(ctx);
c.st[1] = 1.0 - c.st[1];
let Some(image) = self.image.get() else { return 0. };
let v = image.bilerp_channel_with_wrap(c.st, 0, wrap);
let v = if self.invert { (1.0 - v).max(0.0) } else { v };
return v * self.scale;
} }
#[cfg(feature = "cuda")] #[cfg(feature = "cuda")]
#[allow(unused)]
{ {
use cuda_std::intrinsics; if self.tex_obj != 0 {
let c = self.mapping.map(ctx); use cuda_std::intrinsics;
let u = c.st.x(); let c = self.mapping.map(ctx);
let v = 1.0 - c.st.y(); let u = c.st.x();
let d_p_dx = [c.dsdx, c.dtdx]; let v = 1.0 - c.st.y();
let d_p_dy = [c.dsdy, c.dtdy]; let d_p_dx = [c.dsdx, c.dtdx];
// let val: Float = unsafe { intrinsics::tex2d_grad(self.tex_obj, u, v, d_p_dx, d_p_dy) }; let d_p_dy = [c.dsdy, c.dtdy];
let val: Float = 0.; // let val: Float = unsafe { intrinsics::tex2d_grad(self.tex_obj, u, v, d_p_dx, d_p_dy) };
let _ = (u, v, d_p_dx, d_p_dy);
let result = if self.invert { let val: Float = 0.;
// Invert the pixel intensity let result = if self.invert { (1.0 - val).max(0.0) } else { val };
(1.0 - val).max(0.0) return result * self.scale;
} else { }
val // software path (no hardware texture object)
}; let wrap = WrapMode2D { uv: [self.wrap_mode; 2] };
let mut c = self.mapping.map(ctx);
return result * self.scale; c.st[1] = 1.0 - c.st[1];
let Some(image) = self.image.get() else { return 0. };
let v = image.bilerp_channel_with_wrap(c.st, 0, wrap);
let v = if self.invert { (1.0 - v).max(0.0) } else { v };
return v * self.scale;
} }
} }
} }

View file

@ -1,18 +1,18 @@
use crate::Float; use crate::Float;
use crate::core::geometry::{Vector3f, VectorLike}; use crate::core::geometry::{Vector3f, VectorLike};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext}; use crate::core::texture::{FloatTexture, SpectrumTexture, TextureEvalContext};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::Ptr;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct GPUFloatMixTexture { pub struct FloatMixTexture {
pub tex1: Ptr<GPUFloatTexture>, pub tex1: Ptr<FloatTexture>,
pub tex2: Ptr<GPUFloatTexture>, pub tex2: Ptr<FloatTexture>,
pub amount: Ptr<GPUFloatTexture>, pub amount: Ptr<FloatTexture>,
} }
impl GPUFloatMixTexture { impl FloatMixTexture {
pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float { pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
let amt = self.amount.get().map(|t| t.evaluate(ctx)).unwrap_or(0.0); let amt = self.amount.get().map(|t| t.evaluate(ctx)).unwrap_or(0.0);
let t1 = if amt != 1.0 { let t1 = if amt != 1.0 {
@ -33,13 +33,13 @@ impl GPUFloatMixTexture {
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct GPUFloatDirectionMixTexture { pub struct FloatDirectionMixTexture {
pub tex1: Ptr<GPUFloatTexture>, pub tex1: Ptr<FloatTexture>,
pub tex2: Ptr<GPUFloatTexture>, pub tex2: Ptr<FloatTexture>,
pub dir: Vector3f, pub dir: Vector3f,
} }
impl GPUFloatDirectionMixTexture { impl FloatDirectionMixTexture {
pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float { pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
let amt = self.dir.abs_dot(ctx.n.into()); let amt = self.dir.abs_dot(ctx.n.into());
let t1 = if amt != 1.0 { let t1 = if amt != 1.0 {
@ -60,13 +60,13 @@ impl GPUFloatDirectionMixTexture {
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct GPUSpectrumMixTexture { pub struct SpectrumMixTexture {
pub tex1: Ptr<GPUSpectrumTexture>, pub tex1: Ptr<SpectrumTexture>,
pub tex2: Ptr<GPUSpectrumTexture>, pub tex2: Ptr<SpectrumTexture>,
pub amount: Ptr<GPUFloatTexture>, pub amount: Ptr<FloatTexture>,
} }
impl GPUSpectrumMixTexture { impl SpectrumMixTexture {
pub fn evaluate( pub fn evaluate(
&self, &self,
ctx: &TextureEvalContext, ctx: &TextureEvalContext,
@ -97,13 +97,13 @@ impl GPUSpectrumMixTexture {
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct GPUSpectrumDirectionMixTexture { pub struct SpectrumDirectionMixTexture {
pub tex1: Ptr<GPUSpectrumTexture>, pub tex1: Ptr<SpectrumTexture>,
pub tex2: Ptr<GPUSpectrumTexture>, pub tex2: Ptr<SpectrumTexture>,
pub dir: Vector3f, pub dir: Vector3f,
} }
impl GPUSpectrumDirectionMixTexture { impl SpectrumDirectionMixTexture {
pub fn evaluate( pub fn evaluate(
&self, &self,
ctx: &TextureEvalContext, ctx: &TextureEvalContext,

View file

@ -1,16 +1,16 @@
use crate::Float; use crate::Float;
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext}; use crate::core::texture::{FloatTexture, SpectrumTexture, TextureEvalContext};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::Ptr;
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct GPUFloatScaledTexture { pub struct FloatScaledTexture {
pub tex: Ptr<GPUFloatTexture>, pub tex: Ptr<FloatTexture>,
pub scale: Ptr<GPUFloatTexture>, pub scale: Ptr<FloatTexture>,
} }
impl GPUFloatScaledTexture { impl FloatScaledTexture {
pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float { pub fn evaluate(&self, ctx: &TextureEvalContext) -> Float {
let sc = self.scale.get().map(|t| t.evaluate(ctx)).unwrap(); let sc = self.scale.get().map(|t| t.evaluate(ctx)).unwrap();
if sc == 0. { if sc == 0. {
@ -22,12 +22,12 @@ impl GPUFloatScaledTexture {
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct GPUSpectrumScaledTexture { pub struct SpectrumScaledTexture {
pub tex: Ptr<GPUSpectrumTexture>, pub tex: Ptr<SpectrumTexture>,
pub scale: Ptr<GPUFloatTexture>, pub scale: Ptr<FloatTexture>,
} }
impl GPUSpectrumScaledTexture { impl SpectrumScaledTexture {
pub fn evaluate( pub fn evaluate(
&self, &self,
ctx: &TextureEvalContext, ctx: &TextureEvalContext,

View file

@ -88,14 +88,14 @@ impl MaterialFactory for Material {
} }
pub fn default_diffuse_material(arena: &Arena) -> Material { pub fn default_diffuse_material(arena: &Arena) -> Material {
use shared::core::texture::GPUSpectrumTexture; use shared::core::texture::SpectrumTexture;
use shared::core::texture::SpectrumConstantTexture; use shared::core::texture::SpectrumConstantTexture;
use shared::core::spectrum::{ConstantSpectrum, Spectrum}; use shared::core::spectrum::{ConstantSpectrum, Spectrum};
use shared::materials::DiffuseMaterial; use shared::materials::DiffuseMaterial;
use shared::utils::Ptr; use shared::utils::Ptr;
let grey = Spectrum::Constant(ConstantSpectrum { c: 0.5 }); let grey = Spectrum::Constant(ConstantSpectrum { c: 0.5 });
let tex = GPUSpectrumTexture::Constant(SpectrumConstantTexture::new(grey)); let tex = SpectrumTexture::Constant(SpectrumConstantTexture::new(grey));
let tex_ptr = arena.alloc(tex); let tex_ptr = arena.alloc(tex);
Material::Diffuse(DiffuseMaterial { Material::Diffuse(DiffuseMaterial {

View file

@ -4,7 +4,7 @@ use shared::core::{
medium::MediumInterface, medium::MediumInterface,
primitive::{GeometricPrimitive, SimplePrimitive}, primitive::{GeometricPrimitive, SimplePrimitive},
shape::Shape, shape::Shape,
texture::GPUFloatTexture, texture::FloatTexture,
}; };
use shared::utils::Ptr; use shared::utils::Ptr;
@ -23,7 +23,7 @@ pub trait CreateGeometricPrimitive {
material: Ptr<Material>, material: Ptr<Material>,
area_light: Ptr<Light>, area_light: Ptr<Light>,
medium_interface: MediumInterface, medium_interface: MediumInterface,
alpha: Ptr<GPUFloatTexture>, alpha: Ptr<FloatTexture>,
) -> GeometricPrimitive { ) -> GeometricPrimitive {
GeometricPrimitive { GeometricPrimitive {
shape, shape,

View file

@ -12,7 +12,11 @@ use shared::core::texture::{
UVMapping, UVMapping,
}; };
use shared::spectra::{SampledSpectrum, SampledWavelengths}; use shared::spectra::{SampledSpectrum, SampledWavelengths};
use shared::textures::*; use shared::textures::{
FBmTexture, FloatBilerpTexture, FloatCheckerboardTexture, FloatConstantTexture,
FloatDotsTexture, MarbleTexture, SpectrumBilerpTexture, SpectrumCheckerboardTexture,
SpectrumConstantTexture, SpectrumDotsTexture, WindyTexture, WrinkledTexture,
};
use shared::utils::Transform; use shared::utils::Transform;
use shared::Float; use shared::Float;
use std::collections::HashMap; use std::collections::HashMap;
@ -45,16 +49,6 @@ pub enum FloatTexture {
Bilerp(FloatBilerpTexture), Bilerp(FloatBilerpTexture),
} }
impl FloatTexture {
fn upload_image(inner: &FloatImageTexture, _arena: &Arena) -> GPUFloatImageTexture {
GPUFloatImageTexture {
mapping: inner.base.mapping,
tex_obj: inner.base.mipmap.texture_object(),
scale: inner.base.scale,
invert: inner.base.invert,
}
}
}
impl Default for FloatTexture { impl Default for FloatTexture {
fn default() -> Self { fn default() -> Self {

View file

@ -1,7 +1,6 @@
use crate::core::image::{HostImage, ImageIO}; use crate::core::image::{HostImage, ImageIO};
use crate::core::light::lookup_spectrum; use crate::core::light::lookup_spectrum;
use crate::core::spectrum::spectrum_to_photometric; use crate::core::spectrum::spectrum_to_photometric;
use crate::core::texture::FloatTexture;
use crate::utils::resolve_filename; use crate::utils::resolve_filename;
use crate::utils::upload::ArenaUpload; use crate::utils::upload::ArenaUpload;
use crate::{Arena, FileLoc, ParameterDictionary}; use crate::{Arena, FileLoc, ParameterDictionary};
@ -11,7 +10,8 @@ use shared::core::light::{Light, LightBase, LightType};
use shared::core::medium::{Medium, MediumInterface}; use shared::core::medium::{Medium, MediumInterface};
use shared::core::shape::{Shape, ShapeTrait}; use shared::core::shape::{Shape, ShapeTrait};
use shared::core::spectrum::Spectrum; use shared::core::spectrum::Spectrum;
use shared::core::texture::{GPUFloatTexture, SpectrumType, TextureEvalContext}; use crate::core::texture::FloatTexture as HostFloatTexture;
use shared::core::texture::{FloatTexture, SpectrumType, TextureEvalContext};
use shared::lights::DiffuseAreaLight; use shared::lights::DiffuseAreaLight;
use shared::spectra::RGBColorSpace; use shared::spectra::RGBColorSpace;
use shared::utils::Transform; use shared::utils::Transform;
@ -24,7 +24,7 @@ pub fn create(
params: &ParameterDictionary, params: &ParameterDictionary,
loc: &FileLoc, loc: &FileLoc,
shape: &Shape, shape: &Shape,
alpha: &FloatTexture, alpha: &HostFloatTexture,
colorspace: Option<&RGBColorSpace>, colorspace: Option<&RGBColorSpace>,
arena: &Arena, arena: &Arena,
) -> Result<Light> { ) -> Result<Light> {
@ -102,7 +102,7 @@ pub fn create(
// Upload alpha texture to GPU and check for null texture // Upload alpha texture to GPU and check for null texture
let alpha_ptr = arena.upload(alpha); let alpha_ptr = arena.upload(alpha);
let light_type = match alpha_ptr.get().unwrap() { let light_type = match alpha_ptr.get().unwrap() {
GPUFloatTexture::Constant(t) if t.evaluate(&TextureEvalContext::default()) == 0.0 => { FloatTexture::Constant(t) if t.evaluate(&TextureEvalContext::default()) == 0.0 => {
LightType::DeltaPosition LightType::DeltaPosition
} }
_ => LightType::Area, _ => LightType::Area,

View file

@ -1,8 +1,9 @@
use crate::core::texture::{FloatTexture, SpectrumTexture};
use crate::core::image::HostImage; use crate::core::image::HostImage;
use shared::core::image::Image; use crate::core::texture::{FloatTexture as HostFloatTexture, SpectrumTexture as HostSpectrumTexture};
use crate::spectra::default_colorspace;
use crate::Arena; use crate::Arena;
use shared::core::texture::{GPUFloatTexture, GPUSpectrumTexture}; use shared::core::image::Image;
use shared::core::texture::{FloatTexture, SpectrumTexture};
use shared::textures::*; use shared::textures::*;
use shared::Ptr; use shared::Ptr;
use std::sync::Arc; use std::sync::Arc;
@ -12,43 +13,46 @@ pub trait Upload {
fn upload(self, arena: &Arena) -> Self::Target; fn upload(self, arena: &Arena) -> Self::Target;
} }
fn convert_float(tex: &FloatTexture, arena: &Arena) -> GPUFloatTexture { fn convert_float(tex: &HostFloatTexture, arena: &Arena) -> FloatTexture {
match tex { match tex {
FloatTexture::Constant(t) => GPUFloatTexture::Constant(*t), HostFloatTexture::Constant(t) => FloatTexture::Constant(*t),
FloatTexture::Bilerp(t) => GPUFloatTexture::Bilerp(*t), HostFloatTexture::Bilerp(t) => FloatTexture::Bilerp(*t),
FloatTexture::Checkerboard(t) => GPUFloatTexture::Checkerboard(*t), HostFloatTexture::Checkerboard(t) => FloatTexture::Checkerboard(*t),
FloatTexture::Dots(t) => GPUFloatTexture::Dots(*t), HostFloatTexture::Dots(t) => FloatTexture::Dots(*t),
FloatTexture::FBm(t) => GPUFloatTexture::FBm(*t), HostFloatTexture::FBm(t) => FloatTexture::FBm(*t),
FloatTexture::Windy(t) => GPUFloatTexture::Windy(*t), HostFloatTexture::Windy(t) => FloatTexture::Windy(*t),
FloatTexture::Wrinkled(t) => GPUFloatTexture::Wrinkled(*t), HostFloatTexture::Wrinkled(t) => FloatTexture::Wrinkled(*t),
FloatTexture::Scaled(t) => { HostFloatTexture::Scaled(t) => {
let tex = arena.alloc(convert_float(&t.tex, arena)); let tex = arena.alloc(convert_float(t.tex.as_ref(), arena));
let scale = arena.alloc(convert_float(&t.scale, arena)); let scale = arena.alloc(convert_float(t.scale.as_ref(), arena));
GPUFloatTexture::Scaled(GPUFloatScaledTexture { tex, scale }) FloatTexture::Scaled(FloatScaledTexture { tex, scale })
} }
FloatTexture::Mix(t) => { HostFloatTexture::Mix(t) => {
let tex1 = arena.alloc(convert_float(&t.tex1, arena)); let tex1 = arena.alloc(convert_float(t.tex1.as_ref(), arena));
let tex2 = arena.alloc(convert_float(&t.tex2, arena)); let tex2 = arena.alloc(convert_float(t.tex2.as_ref(), arena));
let amount = arena.alloc(convert_float(&t.amount, arena)); let amount = arena.alloc(convert_float(t.amount.as_ref(), arena));
GPUFloatTexture::Mix(GPUFloatMixTexture { tex1, tex2, amount }) FloatTexture::Mix(FloatMixTexture { tex1, tex2, amount })
} }
FloatTexture::DirectionMix(t) => { HostFloatTexture::DirectionMix(t) => {
let tex1 = arena.alloc(convert_float(&t.tex1, arena)); let tex1 = arena.alloc(convert_float(t.tex1.as_ref(), arena));
let tex2 = arena.alloc(convert_float(&t.tex2, arena)); let tex2 = arena.alloc(convert_float(t.tex2.as_ref(), arena));
GPUFloatTexture::DirectionMix(GPUFloatDirectionMixTexture { FloatTexture::DirectionMix(FloatDirectionMixTexture {
tex1, tex1,
tex2, tex2,
dir: t.dir, dir: t.dir,
}) })
} }
FloatTexture::Image(t) => { HostFloatTexture::Image(t) => {
let image = arena.alloc(t.base.mipmap.base_image().inner.clone());
let tex_obj = arena.get_texture_object(&t.base.mipmap); let tex_obj = arena.get_texture_object(&t.base.mipmap);
GPUFloatTexture::Image(GPUFloatImageTexture { FloatTexture::Image(FloatImageTexture {
image,
mapping: t.base.mapping, mapping: t.base.mapping,
wrap_mode: t.base.mipmap.wrap_mode,
tex_obj, tex_obj,
scale: t.base.scale, scale: t.base.scale,
invert: t.base.invert, invert: t.base.invert,
@ -57,94 +61,92 @@ fn convert_float(tex: &FloatTexture, arena: &Arena) -> GPUFloatTexture {
} }
} }
fn convert_spectrum(tex: &SpectrumTexture, arena: &Arena) -> GPUSpectrumTexture { fn convert_spectrum(tex: &HostSpectrumTexture, arena: &Arena) -> SpectrumTexture {
match tex { match tex {
SpectrumTexture::Constant(t) => GPUSpectrumTexture::Constant(*t), HostSpectrumTexture::Constant(t) => SpectrumTexture::Constant(*t),
SpectrumTexture::Bilerp(t) => GPUSpectrumTexture::Bilerp(*t), HostSpectrumTexture::Bilerp(t) => SpectrumTexture::Bilerp(*t),
SpectrumTexture::Checkerboard(t) => GPUSpectrumTexture::Checkerboard(*t), HostSpectrumTexture::Checkerboard(t) => SpectrumTexture::Checkerboard(*t),
SpectrumTexture::Dots(t) => GPUSpectrumTexture::Dots(*t), HostSpectrumTexture::Dots(t) => SpectrumTexture::Dots(*t),
SpectrumTexture::Marble(t) => GPUSpectrumTexture::Marble(*t), HostSpectrumTexture::Marble(t) => SpectrumTexture::Marble(*t),
SpectrumTexture::Scaled(t) => { HostSpectrumTexture::Scaled(t) => {
let tex = arena.alloc(convert_spectrum(&t.tex, arena)); let tex = arena.alloc(convert_spectrum(t.tex.as_ref(), arena));
let scale = arena.alloc(convert_float(&t.scale, arena)); let scale = arena.alloc(convert_float(t.scale.as_ref(), arena));
GPUSpectrumTexture::Scaled(GPUSpectrumScaledTexture { tex, scale }) SpectrumTexture::Scaled(SpectrumScaledTexture { tex, scale })
} }
SpectrumTexture::Mix(t) => { HostSpectrumTexture::Mix(t) => {
let tex1 = arena.alloc(convert_spectrum(&t.tex1, arena)); let tex1 = arena.alloc(convert_spectrum(t.tex1.as_ref(), arena));
let tex2 = arena.alloc(convert_spectrum(&t.tex2, arena)); let tex2 = arena.alloc(convert_spectrum(t.tex2.as_ref(), arena));
let amount = arena.alloc(convert_float(&t.amount, arena)); let amount = arena.alloc(convert_float(t.amount.as_ref(), arena));
GPUSpectrumTexture::Mix(GPUSpectrumMixTexture { tex1, tex2, amount }) SpectrumTexture::Mix(SpectrumMixTexture { tex1, tex2, amount })
} }
SpectrumTexture::DirectionMix(t) => { HostSpectrumTexture::DirectionMix(t) => {
let tex1 = arena.alloc(convert_spectrum(&t.tex1, arena)); let tex1 = arena.alloc(convert_spectrum(t.tex1.as_ref(), arena));
let tex2 = arena.alloc(convert_spectrum(&t.tex2, arena)); let tex2 = arena.alloc(convert_spectrum(t.tex2.as_ref(), arena));
GPUSpectrumTexture::DirectionMix(GPUSpectrumDirectionMixTexture { SpectrumTexture::DirectionMix(SpectrumDirectionMixTexture {
tex1, tex1,
tex2, tex2,
dir: t.dir, dir: t.dir,
}) })
} }
SpectrumTexture::Image(t) => { HostSpectrumTexture::Image(t) => {
let image = arena.alloc(t.base.mipmap.base_image().inner.clone());
let tex_obj = arena.get_texture_object(&t.base.mipmap); let tex_obj = arena.get_texture_object(&t.base.mipmap);
GPUSpectrumTexture::Image(GPUSpectrumImageTexture { SpectrumTexture::Image(SpectrumImageTexture {
mapping: t.base.mapping, image,
tex_obj, tex_obj,
wrap_mode: t.base.mipmap.wrap_mode,
color_space: arena
.alloc(t.base.mipmap.color_space.unwrap_or_else(default_colorspace)),
mapping: t.base.mapping,
scale: t.base.scale, scale: t.base.scale,
invert: t.base.invert, invert: t.base.invert,
is_single_channel: t.base.mipmap.is_single_channel(), is_single_channel: t.base.mipmap.is_single_channel(),
spectrum_type: t.spectrum_type, spectrum_type: t.spectrum_type,
color_space: arena.alloc(
t.base
.mipmap
.color_space
.unwrap_or_else(crate::spectra::default_colorspace),
),
}) })
} }
} }
} }
impl Upload for Arc<FloatTexture> { impl Upload for Arc<HostFloatTexture> {
type Target = Ptr<GPUFloatTexture>; type Target = Ptr<FloatTexture>;
fn upload(self, arena: &Arena) -> Self::Target { fn upload(self, arena: &Arena) -> Self::Target {
arena.alloc(convert_float(&self, arena)) arena.alloc(convert_float(&self, arena))
} }
} }
impl Upload for Arc<SpectrumTexture> { impl Upload for Arc<HostSpectrumTexture> {
type Target = Ptr<GPUSpectrumTexture>; type Target = Ptr<SpectrumTexture>;
fn upload(self, arena: &Arena) -> Self::Target { fn upload(self, arena: &Arena) -> Self::Target {
arena.alloc(convert_spectrum(&self, arena)) arena.alloc(convert_spectrum(&self, arena))
} }
} }
impl Upload for &FloatTexture { impl Upload for &HostFloatTexture {
type Target = Ptr<GPUFloatTexture>; type Target = Ptr<FloatTexture>;
fn upload(self, arena: &Arena) -> Self::Target { fn upload(self, arena: &Arena) -> Self::Target {
arena.alloc(convert_float(self, arena)) arena.alloc(convert_float(self, arena))
} }
} }
impl Upload for &SpectrumTexture { impl Upload for &HostSpectrumTexture {
type Target = Ptr<GPUSpectrumTexture>; type Target = Ptr<SpectrumTexture>;
fn upload(self, arena: &Arena) -> Self::Target { fn upload(self, arena: &Arena) -> Self::Target {
arena.alloc(convert_spectrum(self, arena)) arena.alloc(convert_spectrum(self, arena))
} }
} }
impl Upload for Option<Arc<FloatTexture>> { impl Upload for Option<Arc<HostFloatTexture>> {
type Target = Ptr<GPUFloatTexture>; type Target = Ptr<FloatTexture>;
fn upload(self, arena: &Arena) -> Self::Target { fn upload(self, arena: &Arena) -> Self::Target {
arena.alloc_opt(self.map(|v| convert_float(&v, arena))) arena.alloc_opt(self.map(|v| convert_float(&v, arena)))
} }
} }
impl Upload for Option<Arc<SpectrumTexture>> { impl Upload for Option<Arc<HostSpectrumTexture>> {
type Target = Ptr<GPUSpectrumTexture>; type Target = Ptr<SpectrumTexture>;
fn upload(self, arena: &Arena) -> Self::Target { fn upload(self, arena: &Arena) -> Self::Target {
arena.alloc_opt(self.map(|v| convert_spectrum(&v, arena))) arena.alloc_opt(self.map(|v| convert_spectrum(&v, arena)))
} }