diff --git a/shared/src/bxdfs/layered.rs b/shared/src/bxdfs/layered.rs index 4e7b588..d975b2e 100644 --- a/shared/src/bxdfs/layered.rs +++ b/shared/src/bxdfs/layered.rs @@ -19,7 +19,7 @@ use crate::spectra::{ N_SPECTRUM_SAMPLES, RGBColorSpace, RGBUnboundedSpectrum, SampledSpectrum, SampledWavelengths, StandardColorSpaces, }; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use crate::utils::hash::hash_buffer; use crate::utils::math::{ clamp, fast_exp, i0, lerp, log_i0, radians, safe_acos, safe_asin, safe_sqrt, sample_discrete, diff --git a/shared/src/bxdfs/measured.rs b/shared/src/bxdfs/measured.rs index 810e018..8b733f9 100644 --- a/shared/src/bxdfs/measured.rs +++ b/shared/src/bxdfs/measured.rs @@ -8,7 +8,7 @@ use crate::core::geometry::{ use crate::core::scattering::reflect; use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::utils::math::square; -use crate::utils::ptr::{Ptr, Slice}; +use crate::utils::ptr::{DevicePtr, Slice}; use crate::utils::sampling::{PiecewiseLinear2D, cosine_hemisphere_pdf, sample_cosine_hemisphere}; use crate::{Float, INV_PI, PI, PI_OVER_2}; use core::any::Any; @@ -28,7 +28,7 @@ pub struct MeasuredBxDFData { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct MeasuredBxDF { - pub brdf: Ptr, + pub brdf: DevicePtr, pub lambda: SampledWavelengths, } @@ -38,7 +38,7 @@ unsafe impl Sync for MeasuredBxDF {} impl MeasuredBxDF { pub fn new(brdf: &MeasuredBxDFData, lambda: &SampledWavelengths) -> Self { Self { - brdf: Ptr::from(brdf), + brdf: DevicePtr::from(brdf), lambda: *lambda, } } diff --git a/shared/src/cameras/realistic.rs b/shared/src/cameras/realistic.rs index b4ba93e..9d41912 100644 --- a/shared/src/cameras/realistic.rs +++ b/shared/src/cameras/realistic.rs @@ -5,7 +5,7 @@ use crate::core::film::Film; use crate::core::geometry::{ Bounds2f, Normal3f, Point2f, Point2i, Point3f, Ray, Vector2f, Vector2i, Vector3f, VectorLike, }; -use crate::core::image::{Image, PixelFormat}; +use crate::core::image::{DeviceImage, PixelFormat}; use crate::core::medium::Medium; use crate::core::pbrt::Float; use crate::core::sampler::CameraSample; @@ -37,7 +37,7 @@ pub struct RealisticCamera { base: CameraBase, focus_distance: Float, set_aperture_diameter: Float, - aperture_image: *const Image, + aperture_image: *const DeviceImage, element_interfaces: *const LensElementInterface, n_elements: usize, physical_extent: Bounds2f, @@ -51,7 +51,7 @@ impl RealisticCamera { lens_params: &[Float], focus_distance: Float, set_aperture_diameter: Float, - aperture_image: Option, + aperture_image: Option, ) -> Self { let film_ptr = base.film; if film_ptr.is_null() { diff --git a/shared/src/core/bsdf.rs b/shared/src/core/bsdf.rs index a40f9e9..470c0d8 100644 --- a/shared/src/core/bsdf.rs +++ b/shared/src/core/bsdf.rs @@ -2,17 +2,17 @@ use crate::Float; use crate::core::bxdf::{BSDFSample, BxDF, BxDFFlags, BxDFTrait, FArgs, TransportMode}; use crate::core::geometry::{Frame, Normal3f, Point2f, Vector3f, VectorLike}; use crate::spectra::SampledSpectrum; -use crate::utils::Ptr; +use crate::utils::DevicePtr; #[repr(C)] #[derive(Copy, Debug, Default)] pub struct BSDF { - bxdf: Ptr, + bxdf: DevicePtr, shading_frame: Frame, } impl BSDF { - pub fn new(ns: Normal3f, dpdus: Vector3f, bxdf: Ptr) -> Self { + pub fn new(ns: Normal3f, dpdus: Vector3f, bxdf: DevicePtr) -> Self { Self { bxdf, shading_frame: Frame::new(dpdus.normalize(), Vector3f::from(ns)), diff --git a/shared/src/core/bssrdf.rs b/shared/src/core/bssrdf.rs index dece5c7..25c249b 100644 --- a/shared/src/core/bssrdf.rs +++ b/shared/src/core/bssrdf.rs @@ -3,10 +3,10 @@ use crate::core::geometry::{Frame, Normal3f, Point2f, Point3f, Point3fi, Vector3 use crate::core::interaction::{InteractionBase, ShadingGeom, SurfaceInteraction}; use crate::core::shape::Shape; use crate::spectra::{N_SPECTRUM_SAMPLES, SampledSpectrum}; -use crate::utils::ArenaPtr; +use crate::utils::Ptr; use crate::utils::math::{catmull_rom_weights, square}; use crate::utils::sampling::sample_catmull_rom_2d; -use crate::utils::{Ptr, ptr::Slice}; +use crate::utils::{DevicePtr, ptr::Slice}; use crate::{Float, PI}; use enum_dispatch::enum_dispatch; use std::sync::Arc; @@ -78,15 +78,15 @@ impl From<&SubsurfaceInteraction> for SurfaceInteraction { dndv: Normal3f::zero(), }, face_index: 0, - area_light: Ptr::null(), - material: Ptr::null(), + area_light: DevicePtr::null(), + material: DevicePtr::null(), dpdx: Vector3f::zero(), dpdy: Vector3f::zero(), dudx: 0., dvdx: 0., dudy: 0., dvdy: 0., - shape: Ptr::from(&Shape::default()), + shape: DevicePtr::from(&Shape::default()), } } } @@ -96,11 +96,11 @@ impl From<&SubsurfaceInteraction> for SurfaceInteraction { pub struct BSSRDFTable { pub n_rho_samples: u32, pub n_radius_samples: u32, - pub rho_samples: Ptr, - pub radius_samples: Ptr, - pub profile: Ptr, - pub rho_eff: Ptr, - pub profile_cdf: Ptr, + pub rho_samples: DevicePtr, + pub radius_samples: DevicePtr, + pub profile: DevicePtr, + pub rho_eff: DevicePtr, + pub profile_cdf: DevicePtr, } impl BSSRDFTable { @@ -165,7 +165,7 @@ pub struct TabulatedBSSRDF { eta: Float, sigma_t: SampledSpectrum, rho: SampledSpectrum, - table: Ptr, + table: DevicePtr, } impl TabulatedBSSRDF { @@ -187,7 +187,7 @@ impl TabulatedBSSRDF { eta, sigma_t, rho, - table: Ptr::from(table), + table: DevicePtr::from(table), } } diff --git a/shared/src/core/camera.rs b/shared/src/core/camera.rs index 1d38548..4c1b019 100644 --- a/shared/src/core/camera.rs +++ b/shared/src/core/camera.rs @@ -10,7 +10,7 @@ use crate::core::pbrt::Float; use crate::core::sampler::CameraSample; use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::utils::math::lerp; -use crate::utils::ptr::Ptr; +use crate::utils::ptr::DevicePtr; use crate::utils::transform::{AnimatedTransform, Transform}; use enum_dispatch::enum_dispatch; @@ -113,8 +113,8 @@ pub struct CameraBase { pub min_pos_differential_y: Vector3f, pub min_dir_differential_x: Vector3f, pub min_dir_differential_y: Vector3f, - pub film: Ptr, - pub medium: Ptr, + pub film: DevicePtr, + pub medium: DevicePtr, } #[enum_dispatch(CameraTrait)] @@ -232,13 +232,13 @@ pub trait CameraTrait { Point3f::new(0., 0., 0.) + self.base().min_pos_differential_x, Vector3f::new(0., 0., 1.) + self.base().min_dir_differential_x, None, - &Ptr::default(), + &DevicePtr::default(), ); let y_ray = Ray::new( Point3f::new(0., 0., 0.) + self.base().min_pos_differential_y, Vector3f::new(0., 0., 1.) + self.base().min_dir_differential_y, None, - &Ptr::default(), + &DevicePtr::default(), ); let n_down = Vector3f::from(n_down_z); let tx = -(n_down.dot(y_ray.o.into())) / n_down.dot(x_ray.d); diff --git a/shared/src/core/film.rs b/shared/src/core/film.rs index 555809d..790647b 100644 --- a/shared/src/core/film.rs +++ b/shared/src/core/film.rs @@ -5,7 +5,7 @@ use crate::core::geometry::{ Bounds2f, Bounds2fi, Bounds2i, Normal3f, Point2f, Point2i, Point3f, Tuple, Vector2f, Vector2fi, Vector2i, Vector3f, }; -use crate::core::image::{Image, PixelFormat}; +use crate::core::image::{DeviceImage, PixelFormat}; use crate::core::interaction::SurfaceInteraction; use crate::core::pbrt::Float; use crate::core::spectrum::{Spectrum, SpectrumTrait, StandardSpectra}; @@ -17,7 +17,7 @@ use crate::utils::AtomicFloat; use crate::utils::containers::Array2D; use crate::utils::math::linear_least_squares; use crate::utils::math::{SquareMatrix, wrap_equal_area_square}; -use crate::utils::ptr::Ptr; +use crate::utils::ptr::DevicePtr; use crate::utils::sampling::VarianceEstimator; use crate::utils::transform::AnimatedTransform; @@ -472,7 +472,7 @@ impl PixelSensor { pub fn new_with_white_balance( output_colorspace: &RGBColorSpace, - sensor_illum: Ptr, + sensor_illum: DevicePtr, imaging_ratio: Float, spectra: *const StandardSpectra, ) -> Self { diff --git a/shared/src/core/filter.rs b/shared/src/core/filter.rs index 46125d9..4d97c14 100644 --- a/shared/src/core/filter.rs +++ b/shared/src/core/filter.rs @@ -3,7 +3,7 @@ use crate::core::pbrt::Float; use crate::filters::*; use crate::utils::containers::Array2D; use crate::utils::math::{gaussian, gaussian_integral, lerp, sample_tent, windowed_sinc}; -use crate::utils::sampling::PiecewiseConstant2D; +use crate::utils::sampling::DevicePiecewiseConstant2D; use enum_dispatch::enum_dispatch; pub struct FilterSample { @@ -15,7 +15,7 @@ pub struct FilterSample { #[derive(Clone, Debug, Copy)] pub struct FilterSampler { pub domain: Bounds2f, - pub distrib: PiecewiseConstant2D, + pub distrib: DevicePiecewiseConstant2D, pub f: Array2D, } @@ -43,7 +43,7 @@ impl FilterSampler { f[(x as i32, y as i32)] = func(p); } } - let distrib = PiecewiseConstant2D::new_with_bounds(&f, domain); + let distrib = DevicePiecewiseConstant2D::new_with_bounds(&f, domain); Self { domain, f, distrib } } diff --git a/shared/src/core/geometry/ray.rs b/shared/src/core/geometry/ray.rs index 1daf9c0..d51b97e 100644 --- a/shared/src/core/geometry/ray.rs +++ b/shared/src/core/geometry/ray.rs @@ -2,7 +2,7 @@ use super::{Normal3f, Point3f, Point3fi, Vector3f, VectorLike}; use crate::core::medium::Medium; use crate::core::pbrt::Float; use crate::utils::math::{next_float_down, next_float_up}; -use crate::utils::ptr::Ptr; +use crate::utils::ptr::DevicePtr; #[repr(C)] #[derive(Clone, Copy, Debug)] @@ -10,7 +10,7 @@ pub struct Ray { pub o: Point3f, pub d: Vector3f, pub time: Float, - pub medium: Ptr, + pub medium: DevicePtr, // We do this instead of creating a trait for Rayable or some gnarly thing like that pub has_differentials: bool, pub differential: RayDifferential, @@ -21,7 +21,7 @@ impl Default for Ray { Self { o: Point3f::new(0.0, 0.0, 0.0), d: Vector3f::new(0.0, 0.0, 0.0), - medium: Ptr::null(), + medium: DevicePtr::null(), time: 0.0, has_differentials: false, differential: RayDifferential::default(), @@ -35,7 +35,7 @@ impl Ray { o, d, time: time.unwrap_or_else(|| Self::default().time), - medium: Ptr::from(medium), + medium: DevicePtr::from(medium), ..Self::default() } } @@ -71,7 +71,7 @@ impl Ray { o: origin, d, time, - medium: Ptr::null(), + medium: DevicePtr::null(), has_differentials: false, differential: RayDifferential::default(), } @@ -99,7 +99,7 @@ impl Ray { o: pf, d, time, - medium: Ptr::null(), + medium: DevicePtr::null(), has_differentials: false, differential: RayDifferential::default(), } diff --git a/shared/src/core/image.rs b/shared/src/core/image.rs index cb15801..8185ad7 100644 --- a/shared/src/core/image.rs +++ b/shared/src/core/image.rs @@ -66,87 +66,75 @@ pub enum Pixels { } #[repr(C)] -#[derive(Debug, Clone, Copy)] -pub struct Image { +#[derive(Clone, Copy, Debug)] +pub struct ImageBase { pub format: PixelFormat, - pub pixels: Pixels, pub encoding: ColorEncoding, pub resolution: Point2i, pub n_channels: i32, } -impl Image { - pub fn resolution(&self) -> Point2i { - self.resolution - } - - pub fn is_valid(&self) -> bool { - self.resolution.x() > 0. && self.resolution.y() > 0. - } - - pub fn format(&self) -> PixelFormat { - self.format - } - - pub fn n_channels(&self) -> i32 { - self.n_channels - } - - pub fn pixel_offset(&self, p: Point2i) -> u32 { - let width = self.resolution.x() as u32; - let idx = p.y() as u32 * width + p.x() as u32; - idx * (self.n_channels as u32) - } - - pub fn get_channel_with_wrap(&self, p: Point2i, c: i32, wrap_mode: WrapMode2D) -> Float { - if !self.remap_pixel_coords(&mut p, wrap_mode) { - return 0.; - } - - let offset = self.pixel_offset(p) + c; - unsafe { - match self.pixels { - Pixels::U8(ptr) => { - let raw_u8 = *ptr.add(offset); - self.encoding.to_linear_scalar(raw_u8) - } - Pixels::F16(ptr) => { - let half_bits = *ptr.add(offset); - f16_to_f32(f16::from_bits(half_bits)) - } - Pixels::F32(ptr) => *ptr.add(offset), - } - } - } - - pub fn get_channel(&self, p: Point2i, c: i32) -> Float { - self.get_channel_with_wrap(p, c, WrapMode::Clamp.into()) - } - +impl ImageBase { pub fn remap_pixel_coords(&self, p: &mut Point2i, wrap_mode: WrapMode2D) -> bool { + let resolution = self.resolution; for i in 0..2 { - if p[i] >= 0 && p[i] < self.resolution[i] { + if p[i] >= 0 && p[i] < resolution[i] { continue; } match wrap_mode.uv[i] { WrapMode::Black => return false, - WrapMode::Clamp => p[i] = p[i].clamp(0, self.resolution[i] - 1), - WrapMode::Repeat => p[i] = p[i].rem_euclid(self.resolution[i]), + WrapMode::Clamp => p[i] = p[i].clamp(0, resolution[i] - 1), + WrapMode::Repeat => p[i] = p[i].rem_euclid(resolution[i]), WrapMode::OctahedralSphere => { - p[i] = p[i].clamp(0, self.resolution[i] - 1); + p[i] = p[i].clamp(0, resolution[i] - 1); } } } true } +} + +#[repr(C)] +#[derive(Debug, Clone, Copy)] +pub struct DeviceImage { + pub base: ImageBase, + pub pixels: Pixels, +} + +impl DeviceImage { + pub fn base(&self) -> ImageBase { + self.base + } + + pub fn resolution(&self) -> Point2i { + self.base.resolution + } + + pub fn is_valid(&self) -> bool { + self.resolution().x() > 0 && self.resolution().y() > 0 + } + + pub fn format(&self) -> PixelFormat { + self.base().format + } + + pub fn n_channels(&self) -> i32 { + self.base().n_channels + } + + pub fn pixel_offset(&self, p: Point2i) -> u32 { + let width = self.resolution().x() as u32; + let idx = p.y() as u32 * width + p.x() as u32; + idx * (self.n_channels() as u32) + } pub fn bilerp_channel(&self, p: Point2f, c: i32) -> Float { self.bilerp_channel_with_wrap(p, c, WrapMode::Clamp.into()) } pub fn bilerp_channel_with_wrap(&self, p: Point2f, c: i32, wrap_mode: WrapMode2D) -> Float { - let x = p.x() * self.resolution.x() as Float - 0.5; - let y = p.y() * self.resolution.y() as Float - 0.5; + let x = p.x() * self.resolution().x() as Float - 0.5; + let y = p.y() * self.resolution().y() as Float - 0.5; let xi = x.floor() as i32; let yi = y.floor() as i32; let dx = x - xi as Float; @@ -157,22 +145,51 @@ impl Image { let v11 = self.get_channel_with_wrap(Point2i::new(xi + 1, yi + 1), c, wrap_mode); lerp(dy, lerp(dx, v00, v10), lerp(dx, v01, v11)) } +} - pub fn lookup_nearest_channel_with_wrap( - &self, - p: Point2f, - c: i32, - wrap_mode: WrapMode2D, - ) -> Float { +pub trait ImageAccess { + fn get_channel_with_wrap(&self, p: Point2i, c: i32, wrap_mode: WrapMode2D) -> Float; + fn get_channel(&self, p: Point2i, c: i32) -> Float; + fn lookup_nearest_channel_with_wrap(&self, p: Point2f, c: i32, wrap_mode: WrapMode2D) -> Float; + fn lookup_nearest_channel(&self, p: Point2f, c: i32) -> Float; +} + +impl ImageAccess for DeviceImage { + fn get_channel_with_wrap(&self, mut p: Point2i, c: i32, wrap_mode: WrapMode2D) -> Float { + if !self.base.remap_pixel_coords(&mut p, wrap_mode) { + return 0.; + } + + let offset = self.pixel_offset(p) + c as u32; + unsafe { + match self.pixels { + Pixels::U8(ptr) => { + let raw_u8 = *ptr.add(offset as usize); + self.base().encoding.to_linear_scalar(raw_u8) + } + Pixels::F16(ptr) => { + let half_bits: u16 = *ptr.add(offset as usize) as u16; + f16_to_f32(half_bits) + } + Pixels::F32(ptr) => *ptr.add(offset as usize), + } + } + } + + fn get_channel(&self, p: Point2i, c: i32) -> Float { + self.get_channel_with_wrap(p, c, WrapMode::Clamp.into()) + } + + fn lookup_nearest_channel_with_wrap(&self, p: Point2f, c: i32, wrap_mode: WrapMode2D) -> Float { let pi = Point2i::new( - p.x() as i32 * self.resolution.x(), - p.y() as i32 * self.resolution.y(), + p.x() as i32 * self.resolution().x(), + p.y() as i32 * self.resolution().y(), ); self.get_channel_with_wrap(pi, c, wrap_mode) } - pub fn lookup_nearest_channel(&self, p: Point2f, c: i32) -> Float { + fn lookup_nearest_channel(&self, p: Point2f, c: i32) -> Float { self.lookup_nearest_channel_with_wrap(p, c, WrapMode::Clamp.into()) } } diff --git a/shared/src/core/interaction.rs b/shared/src/core/interaction.rs index 830cc7c..eb438c9 100644 --- a/shared/src/core/interaction.rs +++ b/shared/src/core/interaction.rs @@ -5,7 +5,7 @@ use crate::core::camera::{Camera, CameraTrait}; use crate::core::geometry::{ Normal3f, Point2f, Point3f, Point3fi, Ray, RayDifferential, Vector3f, VectorLike, }; -use crate::core::image::Image; +use crate::core::image::DeviceImage; use crate::core::light::{Light, LightTrait}; use crate::core::material::{ Material, MaterialEvalContext, MaterialTrait, NormalBumpEvalContext, bump_map, normal_map, @@ -16,7 +16,7 @@ use crate::core::sampler::{Sampler, SamplerTrait}; use crate::core::shape::Shape; use crate::core::texture::{GPUFloatTexture, UniversalTextureEvaluator}; use crate::spectra::{SampledSpectrum, SampledWavelengths}; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use crate::utils::math::{clamp, difference_of_products, square}; use enum_dispatch::enum_dispatch; use std::any::Any; @@ -31,7 +31,7 @@ pub struct InteractionBase { pub wo: Vector3f, pub uv: Point2f, pub medium_interface: MediumInterface, - pub medium: Ptr, + pub medium: DevicePtr, } impl InteractionBase { @@ -49,11 +49,11 @@ impl InteractionBase { wo: wo.normalize(), time, medium_interface: MediumInterface::default(), - medium: Ptr::null(), + medium: DevicePtr::null(), } } - pub fn new_medium(p: Point3f, wo: Vector3f, time: Float, medium: Ptr) -> Self { + pub fn new_medium(p: Point3f, wo: Vector3f, time: Float, medium: DevicePtr) -> Self { Self { pi: Point3fi::new_from_point(p), n: Normal3f::zero(), @@ -114,7 +114,7 @@ pub trait InteractionTrait { false } - fn get_medium(&self, w: Vector3f) -> Ptr { + fn get_medium(&self, w: Vector3f) -> DevicePtr { let data = self.get_common(); if !data.medium_interface.inside.is_null() || !data.medium_interface.outside.is_null() { if w.dot(data.n.into()) > 0.0 { @@ -225,9 +225,9 @@ pub struct SurfaceInteraction { pub dndv: Normal3f, pub shading: ShadingGeom, pub face_index: u32, - pub area_light: Ptr, - pub material: Ptr, - pub shape: Ptr, + pub area_light: DevicePtr, + pub material: DevicePtr, + pub shape: DevicePtr, pub dpdx: Vector3f, pub dpdy: Vector3f, pub dudx: Float, @@ -412,8 +412,8 @@ impl SurfaceInteraction { fn compute_bump_geom( &mut self, tex_eval: &UniversalTextureEvaluator, - displacement: Ptr, - normal_image: Ptr, + displacement: DevicePtr, + normal_image: DevicePtr, ) { let ctx = NormalBumpEvalContext::from(&*self); let (dpdu, dpdv) = if !displacement.is_null() { @@ -536,7 +536,7 @@ impl InteractionTrait for SurfaceInteraction { &mut self.common } - fn get_medium(&self, w: Vector3f) -> Ptr { + fn get_medium(&self, w: Vector3f) -> DevicePtr { let interface = self.common.medium_interface; if self.n().dot(w.into()) > 0.0 { interface.outside @@ -583,16 +583,16 @@ impl SurfaceInteraction { dndu, dndv, }, - material: Ptr::null(), + material: DevicePtr::null(), face_index: 0, - area_light: Ptr::null(), + area_light: DevicePtr::null(), dpdx: Vector3f::zero(), dpdy: Vector3f::zero(), dudx: 0.0, dudy: 0.0, dvdx: 0.0, dvdy: 0.0, - shape: Ptr::null(), + shape: DevicePtr::null(), } } @@ -658,13 +658,13 @@ impl SurfaceInteraction { ray_medium: &Medium, prim_medium_interface: MediumInterface, ) { - self.material = Ptr::from(mtl); - self.area_light = Ptr::from(area); + self.material = DevicePtr::from(mtl); + self.area_light = DevicePtr::from(area); if prim_medium_interface.is_medium_transition() { self.common.medium_interface = prim_medium_interface; } else { - self.common.medium = Ptr::from(ray_medium); + self.common.medium = DevicePtr::from(ray_medium); } } } @@ -681,7 +681,7 @@ impl MediumInteraction { p: Point3f, wo: Vector3f, time: Float, - medium: Ptr, + medium: DevicePtr, phase: PhaseFunction, ) -> Self { Self { diff --git a/shared/src/core/light.rs b/shared/src/core/light.rs index d7124a5..32089b0 100644 --- a/shared/src/core/light.rs +++ b/shared/src/core/light.rs @@ -3,7 +3,7 @@ use crate::core::geometry::{ Bounds2f, Bounds3f, DirectionCone, Normal3f, Point2f, Point2i, Point3f, Point3fi, Ray, Vector3f, VectorLike, cos_theta, }; -use crate::core::image::Image; +use crate::core::image::DeviceImage; use crate::core::interaction::{ Interaction, InteractionBase, InteractionTrait, MediumInteraction, SimpleInteraction, SurfaceInteraction, @@ -17,8 +17,8 @@ use crate::spectra::{ }; use crate::utils::Transform; use crate::utils::math::{equal_area_sphere_to_square, radians, safe_sqrt, smooth_step, square}; -use crate::utils::ptr::Ptr; -use crate::utils::sampling::PiecewiseConstant2D; +use crate::utils::ptr::{DevicePtr, Ptr}; +use crate::utils::sampling::DevicePiecewiseConstant2D; use crate::{Float, PI}; use bitflags::bitflags; diff --git a/shared/src/core/material.rs b/shared/src/core/material.rs index 97038ee..93756e5 100644 --- a/shared/src/core/material.rs +++ b/shared/src/core/material.rs @@ -10,7 +10,7 @@ use crate::core::bsdf::BSDF; use crate::core::bssrdf::BSSRDF; use crate::core::bxdf::BxDF; use crate::core::geometry::{Frame, Normal3f, Point2f, Point3f, Vector2f, Vector3f, VectorLike}; -use crate::core::image::{Image, WrapMode, WrapMode2D}; +use crate::core::image::{DeviceImage, WrapMode, WrapMode2D}; use crate::core::interaction::{Interaction, InteractionTrait, ShadingGeom, SurfaceInteraction}; use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::spectrum::{Spectrum, SpectrumTrait}; @@ -19,7 +19,7 @@ use crate::core::texture::{ }; use crate::materials::*; use crate::spectra::{SampledSpectrum, SampledWavelengths}; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use crate::utils::hash::hash_float; use crate::utils::math::clamp; @@ -103,7 +103,7 @@ impl From<&NormalBumpEvalContext> for TextureEvalContext { } } -pub fn normal_map(normal_map: &Image, ctx: &NormalBumpEvalContext) -> (Vector3f, Vector3f) { +pub fn normal_map(normal_map: &DeviceImage, ctx: &NormalBumpEvalContext) -> (Vector3f, Vector3f) { let wrap = WrapMode2D::from(WrapMode::Repeat); let uv = Point2f::new(ctx.uv[0], 1. - ctx.uv[1]); let r = normal_map.bilerp_channel_with_wrap(uv, 0, wrap); @@ -125,7 +125,7 @@ pub fn bump_map( displacement: &GPUFloatTexture, ctx: &NormalBumpEvalContext, ) -> (Vector3f, Vector3f) { - debug_assert!(tex_eval.can_evaluate(&[Ptr::from(displacement)], &[])); + debug_assert!(tex_eval.can_evaluate(&[DevicePtr::from(displacement)], &[])); let mut du = 0.5 * (ctx.dudx.abs() + ctx.dudy.abs()); if du == 0.0 { du = 0.0005; @@ -173,8 +173,8 @@ pub trait MaterialTrait { ) -> Option; fn can_evaluate_textures(&self, tex_eval: &dyn TextureEvaluator) -> bool; - fn get_normal_map(&self) -> Option<&Image>; - fn get_displacement(&self) -> Ptr; + fn get_normal_map(&self) -> Option<&DeviceImage>; + fn get_displacement(&self) -> DevicePtr; fn has_subsurface_scattering(&self) -> bool; } diff --git a/shared/src/core/medium.rs b/shared/src/core/medium.rs index ae65585..f318a46 100644 --- a/shared/src/core/medium.rs +++ b/shared/src/core/medium.rs @@ -12,7 +12,7 @@ use crate::spectra::{ }; use crate::utils::containers::SampledGrid; use crate::utils::math::{clamp, square}; -use crate::utils::ptr::Ptr; +use crate::utils::ptr::DevicePtr; use crate::utils::rng::Rng; use crate::utils::transform::Transform; @@ -829,8 +829,8 @@ impl MediumTrait for NanoVDBMedium { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct MediumInterface { - pub inside: Ptr, - pub outside: Ptr, + pub inside: DevicePtr, + pub outside: DevicePtr, } unsafe impl Send for MediumInterface {} @@ -839,17 +839,32 @@ unsafe impl Sync for MediumInterface {} impl Default for MediumInterface { fn default() -> Self { Self { - inside: Ptr::null(), - outside: Ptr::null(), + inside: DevicePtr::null(), + outside: DevicePtr::null(), } } } +impl From for MediumInterface { + fn from(medium: Medium) -> Self { + Self { + inside: DevicePtr::from(&medium), + outside: DevicePtr::from(&medium), + } + } +} + +impl From<&Medium> for MediumInterface { + fn from(medium: &Medium) -> Self { + Self::from(medium.clone()) + } +} + impl MediumInterface { pub fn new(inside: &Medium, outside: &Medium) -> Self { Self { - inside: Ptr::from(inside), - outside: Ptr::from(outside), + inside: DevicePtr::from(inside), + outside: DevicePtr::from(outside), } } diff --git a/shared/src/core/primitive.rs b/shared/src/core/primitive.rs index d5da5bd..bfd1928 100644 --- a/shared/src/core/primitive.rs +++ b/shared/src/core/primitive.rs @@ -7,7 +7,7 @@ use crate::core::medium::{Medium, MediumInterface}; use crate::core::pbrt::Float; use crate::core::shape::{Shape, ShapeIntersection, ShapeTrait}; use crate::core::texture::{GPUFloatTexture, TextureEvalContext}; -use crate::utils::ArenaPtr; +use crate::utils::Ptr; use crate::utils::hash::hash_float; use crate::utils::transform::{AnimatedTransform, Transform}; @@ -88,13 +88,13 @@ impl PrimitiveTrait for GeometricPrimitive { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct SimplePrimitive { - shape: ArenaPtr, - material: ArenaPtr, + shape: Ptr, + material: Ptr, } #[derive(Debug, Clone)] pub struct TransformedPrimitive { - pub primitive: ArenaPtr, + pub primitive: Ptr, pub render_from_primitive: Transform, } @@ -129,7 +129,7 @@ impl PrimitiveTrait for TransformedPrimitive { #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct AnimatedPrimitive { - primitive: ArenaPtr, + primitive: Ptr, render_from_primitive: AnimatedTransform, } @@ -164,7 +164,7 @@ impl PrimitiveTrait for AnimatedPrimitive { #[derive(Debug, Clone, Copy)] pub struct BVHAggregatePrimitive { max_prims_in_node: u32, - primitives: *const ArenaPtr, + primitives: *const Ptr, nodes: *const LinearBVHNode, } diff --git a/shared/src/core/sampler.rs b/shared/src/core/sampler.rs index a2858b6..441fdb5 100644 --- a/shared/src/core/sampler.rs +++ b/shared/src/core/sampler.rs @@ -2,7 +2,7 @@ use crate::core::filter::FilterTrait; use crate::core::geometry::{Bounds2f, Point2f, Point2i, Vector2f}; use crate::core::options::{PBRTOptions, get_options}; use crate::core::pbrt::{Float, ONE_MINUS_EPSILON, PI, PI_OVER_2, PI_OVER_4, find_interval}; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use crate::utils::containers::Array2D; use crate::utils::math::{ BinaryPermuteScrambler, DigitPermutation, FastOwenScrambler, NoRandomizer, OwenScrambler, @@ -103,7 +103,7 @@ pub struct HaltonSampler { mult_inverse: [u64; 2], halton_index: u64, dim: u32, - digit_permutations: Ptr, + digit_permutations: DevicePtr, } impl HaltonSampler { diff --git a/shared/src/core/shape.rs b/shared/src/core/shape.rs index 8b173e5..ad60399 100644 --- a/shared/src/core/shape.rs +++ b/shared/src/core/shape.rs @@ -10,7 +10,7 @@ use crate::core::material::Material; use crate::core::medium::{Medium, MediumInterface}; use crate::shapes::*; use crate::utils::math::{next_float_down, next_float_up}; -use crate::utils::{Ptr, Transform}; +use crate::utils::{DevicePtr, Transform}; use crate::{Float, PI}; use enum_dispatch::enum_dispatch; @@ -118,7 +118,12 @@ impl ShapeSampleContext { } pub fn spawn_ray(&self, w: Vector3f) -> Ray { - Ray::new(self.offset_ray_origin(w), w, Some(self.time), &Ptr::null()) + Ray::new( + self.offset_ray_origin(w), + w, + Some(self.time), + &DevicePtr::null(), + ) } } diff --git a/shared/src/core/texture.rs b/shared/src/core/texture.rs index a0798dd..11e9076 100644 --- a/shared/src/core/texture.rs +++ b/shared/src/core/texture.rs @@ -9,7 +9,7 @@ use crate::spectra::{ SampledWavelengths, }; use crate::textures::*; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use crate::utils::Transform; use crate::utils::math::square; use crate::{Float, INV_2_PI, INV_PI, PI}; @@ -428,8 +428,8 @@ pub trait TextureEvaluator: Send + Sync { fn can_evaluate( &self, - _ftex: &[Ptr], - _stex: &[Ptr], + _ftex: &[DevicePtr], + _stex: &[DevicePtr], ) -> bool; } @@ -453,8 +453,8 @@ impl TextureEvaluator for UniversalTextureEvaluator { fn can_evaluate( &self, - _float_textures: &[Ptr], - _spectrum_textures: &[Ptr], + _float_textures: &[DevicePtr], + _spectrum_textures: &[DevicePtr], ) -> bool { true } diff --git a/shared/src/lights/diffuse.rs b/shared/src/lights/diffuse.rs index ee1c75b..8dfcc1f 100644 --- a/shared/src/lights/diffuse.rs +++ b/shared/src/lights/diffuse.rs @@ -1,7 +1,7 @@ use crate::PI; use crate::core::color::{RGB, XYZ}; use crate::core::geometry::*; -use crate::core::image::Image; +use crate::core::image::{DeviceImage, ImageAccess}; use crate::core::interaction::{ Interaction, InteractionTrait, MediumInteraction, SurfaceInteraction, }; @@ -17,17 +17,17 @@ use crate::core::texture::{ }; use crate::spectra::*; use crate::utils::hash::hash_float; -use crate::utils::{Ptr, Transform}; +use crate::utils::{DevicePtr, Transform}; #[repr(C)] #[derive(Clone, Debug, Copy)] pub struct DiffuseAreaLight { pub base: LightBase, - pub shape: Ptr, - pub alpha: Ptr, - pub image_color_space: Ptr, - pub lemit: Ptr, - pub image: Ptr, + pub shape: DevicePtr, + pub alpha: DevicePtr, + pub image_color_space: DevicePtr, + pub lemit: DevicePtr, + pub image: DevicePtr, pub area: Float, pub two_sided: bool, pub scale: Float, @@ -175,8 +175,8 @@ impl LightTrait for DiffuseAreaLight { fn bounds(&self) -> Option { let mut phi = 0.; if !self.image.is_null() { - for y in 0..self.image.resolution.y() { - for x in 0..self.image.resolution.x() { + for y in 0..self.image.base.resolution.y() { + for x in 0..self.image.base.resolution.x() { for c in 0..3 { phi += self.image.get_channel(Point2i::new(x, y), c); } diff --git a/shared/src/lights/distant.rs b/shared/src/lights/distant.rs index 9756409..2d1def4 100644 --- a/shared/src/lights/distant.rs +++ b/shared/src/lights/distant.rs @@ -5,14 +5,14 @@ use crate::core::interaction::{Interaction, InteractionBase, SimpleInteraction}; use crate::core::light::{LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait}; use crate::core::spectrum::SpectrumTrait; use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths}; -use crate::utils::{ArenaPtr, Ptr}; +use crate::utils::{DevicePtr, Ptr}; use crate::{Float, PI}; #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct DistantLight { pub base: LightBase, - pub lemit: Ptr, + pub lemit: DevicePtr, pub scale: Float, pub scene_center: Point3f, pub scene_radius: Float, diff --git a/shared/src/lights/goniometric.rs b/shared/src/lights/goniometric.rs index 991c9c4..323cc6d 100644 --- a/shared/src/lights/goniometric.rs +++ b/shared/src/lights/goniometric.rs @@ -1,5 +1,5 @@ use crate::core::geometry::{Bounds3f, Normal3f, Point2f, Point2i, Point3f, Ray, Vector3f}; -use crate::core::image::Image; +use crate::core::image::{DeviceImage, ImageAccess}; use crate::core::light::{ LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait, LightType, }; @@ -7,17 +7,17 @@ use crate::core::medium::MediumInterface; use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths}; use crate::utils::math::equal_area_sphere_to_square; -use crate::utils::sampling::PiecewiseConstant2D; -use crate::utils::{Ptr, Transform}; +use crate::utils::sampling::DevicePiecewiseConstant2D; +use crate::utils::{DevicePtr, Transform}; use crate::{Float, PI}; -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] pub struct GoniometricLight { pub base: LightBase, - iemit: DenselySampledSpectrum, - scale: Float, - image: Ptr, - distrib: Ptr, + pub iemit: DenselySampledSpectrum, + pub scale: Float, + pub image: DevicePtr, + pub distrib: DevicePtr, } impl GoniometricLight { @@ -77,13 +77,14 @@ impl LightTrait for GoniometricLight { #[cfg(not(target_os = "cuda"))] fn phi(&self, lambda: SampledWavelengths) -> SampledSpectrum { + let resolution = self.image.resolution(); let mut sum_y = 0.; - for y in 0..self.image.resolution.y() { - for x in 0..self.image.resolution.x() { + for y in 0..resolution.y() { + for x in 0..resolution.x() { sum_y += self.image.get_channel(Point2i::new(x, y), 0); } } self.scale * self.iemit.sample(&lambda) * 4. * PI * sum_y - / (self.image.resolution.x() * self.image.resolution.y()) as Float + / (resolution.x() * resolution.y()) as Float } } diff --git a/shared/src/lights/infinite.rs b/shared/src/lights/infinite.rs index a145b60..4a9ea76 100644 --- a/shared/src/lights/infinite.rs +++ b/shared/src/lights/infinite.rs @@ -1,23 +1,10 @@ -use crate::{ - core::{ - geometry::{Frame, VectorLike}, - interaction::InteractionBase, - }, - spectra::{RGBColorSpace, RGBIlluminantSpectrum}, - utils::{ - math::{clamp, equal_area_sphere_to_square, equal_area_square_to_sphere, square}, - sampling::{ - AliasTable, PiecewiseConstant2D, WindowedPiecewiseConstant2D, sample_uniform_sphere, - uniform_sphere_pdf, - }, - }, -}; - use crate::core::color::RGB; use crate::core::geometry::{ Bounds2f, Bounds3f, Normal3f, Point2f, Point2i, Point3f, Ray, Vector2f, Vector3f, }; -use crate::core::image::{Image, PixelFormat, WrapMode}; +use crate::core::geometry::{Frame, VectorLike}; +use crate::core::image::{DeviceImage, ImageAccess, PixelFormat, WrapMode}; +use crate::core::interaction::InteractionBase; use crate::core::interaction::{Interaction, SimpleInteraction}; use crate::core::light::{ LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait, LightType, @@ -25,8 +12,14 @@ use crate::core::light::{ use crate::core::medium::{Medium, MediumInterface}; use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths}; +use crate::spectra::{RGBColorSpace, RGBIlluminantSpectrum}; use crate::utils::Transform; -use crate::utils::ptr::Ptr; +use crate::utils::math::{clamp, equal_area_sphere_to_square, equal_area_square_to_sphere, square}; +use crate::utils::ptr::DevicePtr; +use crate::utils::sampling::{ + AliasTable, DevicePiecewiseConstant2D, WindowedPiecewiseConstant2D, sample_uniform_sphere, + uniform_sphere_pdf, +}; use crate::{Float, PI}; use std::sync::Arc; @@ -34,7 +27,7 @@ use std::sync::Arc; #[derive(Debug, Copy, Clone)] pub struct InfiniteUniformLight { pub base: LightBase, - pub lemit: Ptr, + pub lemit: DevicePtr, pub scale: Float, pub scene_center: Point3f, pub scene_radius: Float, @@ -122,10 +115,10 @@ impl LightTrait for InfiniteUniformLight { #[derive(Clone, Copy, Debug)] pub struct InfiniteImageLight { pub base: LightBase, - pub image: Ptr, - pub image_color_space: Ptr, - pub distrib: Ptr, - pub compensated_distrib: Ptr, + pub image: DevicePtr, + pub image_color_space: DevicePtr, + pub distrib: DevicePtr, + pub compensated_distrib: DevicePtr, pub scale: Float, pub scene_radius: Float, pub scene_center: Point3f, @@ -258,8 +251,8 @@ impl LightTrait for InfiniteImageLight { #[derive(Debug, Copy, Clone)] pub struct InfinitePortalLight { pub base: LightBase, - pub image: Ptr, - pub image_color_space: Ptr, + pub image: DevicePtr, + pub image_color_space: DevicePtr, pub scale: Float, pub portal: [Point3f; 4], pub portal_frame: Frame, diff --git a/shared/src/lights/point.rs b/shared/src/lights/point.rs index 700cbe3..18c7f19 100644 --- a/shared/src/lights/point.rs +++ b/shared/src/lights/point.rs @@ -7,7 +7,7 @@ use crate::core::light::{ }; use crate::core::spectrum::SpectrumTrait; use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths}; -use crate::utils::ptr::Ptr; +use crate::utils::ptr::DevicePtr; use crate::{Float, PI}; #[repr(C)] @@ -15,7 +15,7 @@ use crate::{Float, PI}; pub struct PointLight { pub base: LightBase, pub scale: Float, - pub i: Ptr, + pub i: DevicePtr, } impl LightTrait for PointLight { diff --git a/shared/src/lights/projection.rs b/shared/src/lights/projection.rs index 30ff666..2542c77 100644 --- a/shared/src/lights/projection.rs +++ b/shared/src/lights/projection.rs @@ -3,7 +3,7 @@ use crate::core::color::RGB; use crate::core::geometry::{ Bounds2f, Bounds3f, Normal3f, Point2f, Point2i, Point3f, Ray, Vector3f, VectorLike, cos_theta, }; -use crate::core::image::Image; +use crate::core::image::DeviceImage; use crate::core::light::{ LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait, LightType, }; @@ -11,10 +11,10 @@ use crate::core::medium::MediumInterface; use crate::core::spectrum::SpectrumTrait; use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::utils::math::{radians, square}; -use crate::utils::ptr::Ptr; +use crate::utils::ptr::DevicePtr; use crate::{ spectra::{RGBColorSpace, RGBIlluminantSpectrum}, - utils::{Transform, sampling::PiecewiseConstant2D}, + utils::{Transform, sampling::DevicePiecewiseConstant2D}, }; #[repr(C)] @@ -27,9 +27,9 @@ pub struct ProjectionLight { pub screen_from_light: Transform, pub light_from_screen: Transform, pub a: Float, - pub image: Ptr, - pub distrib: Ptr, - pub image_color_space: Ptr, + pub image: DevicePtr, + pub distrib: DevicePtr, + pub image_color_space: DevicePtr, } impl ProjectionLight { diff --git a/shared/src/lights/sampler.rs b/shared/src/lights/sampler.rs index 24f0791..deeceaa 100644 --- a/shared/src/lights/sampler.rs +++ b/shared/src/lights/sampler.rs @@ -6,7 +6,7 @@ use crate::core::light::{LightBounds, LightSampleContext}; use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::utils::math::{clamp, lerp, sample_discrete}; use crate::utils::math::{safe_sqrt, square}; -use crate::utils::ptr::{Ptr, Slice}; +use crate::utils::ptr::{DevicePtr, Slice}; use crate::utils::sampling::AliasTable; use crate::{Float, ONE_MINUS_EPSILON, PI}; use enum_dispatch::enum_dispatch; @@ -154,14 +154,14 @@ impl CompactLightBounds { #[derive(Debug, Clone)] pub struct SampledLight { - pub light: Ptr, + pub light: DevicePtr, pub p: Float, } impl SampledLight { pub fn new(light: Light, p: Float) -> Self { Self { - light: Ptr::from(&light), + light: DevicePtr::from(&light), p, } } @@ -214,7 +214,7 @@ impl LightSamplerTrait for UniformLightSampler { let light_index = (u as u32 * self.lights_len).min(self.lights_len - 1) as usize; Some(SampledLight { - light: Ptr::from(&self.light(light_index)), + light: DevicePtr::from(&self.light(light_index)), p: 1. / self.lights_len as Float, }) } @@ -262,7 +262,7 @@ impl LightSamplerTrait for PowerLightSampler { let light_ref = &self.lights[light_index as usize]; Some(SampledLight { - light: Ptr::from(light_ref), + light: DevicePtr::from(light_ref), p: pmf, }) } diff --git a/shared/src/lights/spot.rs b/shared/src/lights/spot.rs index f5ee84f..fbd8c92 100644 --- a/shared/src/lights/spot.rs +++ b/shared/src/lights/spot.rs @@ -5,14 +5,14 @@ use crate::core::interaction::{Interaction, InteractionBase, InteractionTrait, S use crate::core::light::{LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait}; use crate::core::spectrum::SpectrumTrait; use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths}; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use crate::{Float, PI}; #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct SpotLight { pub base: LightBase, - pub iemit: Ptr, + pub iemit: DevicePtr, pub scale: Float, pub cos_falloff_start: Float, pub cos_falloff_end: Float, diff --git a/shared/src/materials/coated.rs b/shared/src/materials/coated.rs index 8ecc1b4..2433276 100644 --- a/shared/src/materials/coated.rs +++ b/shared/src/materials/coated.rs @@ -4,27 +4,27 @@ use crate::bxdfs::{ use crate::core::bsdf::BSDF; use crate::core::bssrdf::BSSRDF; use crate::core::bxdf::BxDF; -use crate::core::image::Image; +use crate::core::image::DeviceImage; use crate::core::material::{Material, MaterialEvalContext, MaterialTrait}; use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::spectra::{SampledSpectrum, SampledWavelengths}; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use crate::utils::math::clamp; #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct CoatedDiffuseMaterial { - pub normal_map: Ptr, - pub displacement: Ptr, - pub reflectance: Ptr, - pub albedo: Ptr, - pub u_roughness: Ptr, - pub v_roughness: Ptr, - pub thickness: Ptr, - pub g: Ptr, - pub eta: Ptr, + pub normal_map: DevicePtr, + pub displacement: DevicePtr, + pub reflectance: DevicePtr, + pub albedo: DevicePtr, + pub u_roughness: DevicePtr, + pub v_roughness: DevicePtr, + pub thickness: DevicePtr, + pub g: DevicePtr, + pub eta: DevicePtr, pub remap_roughness: bool, pub max_depth: usize, pub n_samples: usize, @@ -42,21 +42,21 @@ impl CoatedDiffuseMaterial { g: &GPUFloatTexture, eta: &Spectrum, displacement: &GPUFloatTexture, - normal_map: &Image, + normal_map: &DeviceImage, remap_roughness: bool, max_depth: usize, n_samples: usize, ) -> Self { Self { - displacement: Ptr::from(displacement), - normal_map: Ptr::from(normal_map), - reflectance: Ptr::from(reflectance), - albedo: Ptr::from(albedo), - u_roughness: Ptr::from(u_roughness), - v_roughness: Ptr::from(v_roughness), - thickness: Ptr::from(thickness), - g: Ptr::from(g), - eta: Ptr::from(eta), + displacement: DevicePtr::from(displacement), + normal_map: DevicePtr::from(normal_map), + reflectance: DevicePtr::from(reflectance), + albedo: DevicePtr::from(albedo), + u_roughness: DevicePtr::from(u_roughness), + v_roughness: DevicePtr::from(v_roughness), + thickness: DevicePtr::from(thickness), + g: DevicePtr::from(g), + eta: DevicePtr::from(eta), remap_roughness, max_depth, n_samples, @@ -115,7 +115,7 @@ impl MaterialTrait for CoatedDiffuseMaterial { self.n_samples, )); - BSDF::new(ctx.ns, ctx.dpdus, Ptr::from(&bxdf)) + BSDF::new(ctx.ns, ctx.dpdus, DevicePtr::from(&bxdf)) } fn get_bssrdf( @@ -134,11 +134,11 @@ impl MaterialTrait for CoatedDiffuseMaterial { ) } - fn get_normal_map(&self) -> Option<&Image> { + fn get_normal_map(&self) -> Option<&DeviceImage> { Some(&*self.normal_map) } - fn get_displacement(&self) -> Ptr { + fn get_displacement(&self) -> DevicePtr { self.displacement } @@ -150,19 +150,19 @@ impl MaterialTrait for CoatedDiffuseMaterial { #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct CoatedConductorMaterial { - normal_map: Ptr, - displacement: Ptr, - interface_uroughness: Ptr, - interface_vroughness: Ptr, - thickness: Ptr, - interface_eta: Ptr, - g: Ptr, - albedo: Ptr, - conductor_uroughness: Ptr, - conductor_vroughness: Ptr, - conductor_eta: Ptr, - k: Ptr, - reflectance: Ptr, + normal_map: DevicePtr, + displacement: DevicePtr, + interface_uroughness: DevicePtr, + interface_vroughness: DevicePtr, + thickness: DevicePtr, + interface_eta: DevicePtr, + g: DevicePtr, + albedo: DevicePtr, + conductor_uroughness: DevicePtr, + conductor_vroughness: DevicePtr, + conductor_eta: DevicePtr, + k: DevicePtr, + reflectance: DevicePtr, remap_roughness: bool, max_depth: u32, n_samples: u32, @@ -172,7 +172,7 @@ impl CoatedConductorMaterial { #[allow(clippy::too_many_arguments)] #[cfg(not(target_os = "cuda"))] pub fn new( - normal_map: &Image, + normal_map: &DeviceImage, displacement: &GPUFloatTexture, interface_uroughness: &GPUFloatTexture, interface_vroughness: &GPUFloatTexture, @@ -190,19 +190,19 @@ impl CoatedConductorMaterial { n_samples: u32, ) -> Self { Self { - displacement: Ptr::from(displacement), - normal_map: Ptr::from(normal_map), - interface_uroughness: Ptr::from(interface_uroughness), - interface_vroughness: Ptr::from(interface_vroughness), - thickness: Ptr::from(thickness), - interface_eta: Ptr::from(interface_eta), - g: Ptr::from(g), - albedo: Ptr::from(albedo), - conductor_uroughness: Ptr::from(conductor_uroughness), - conductor_vroughness: Ptr::from(conductor_vroughness), - conductor_eta: Ptr::from(conductor_eta), - k: Ptr::from(k), - reflectance: Ptr::from(reflectance), + displacement: DevicePtr::from(displacement), + normal_map: DevicePtr::from(normal_map), + interface_uroughness: DevicePtr::from(interface_uroughness), + interface_vroughness: DevicePtr::from(interface_vroughness), + thickness: DevicePtr::from(thickness), + interface_eta: DevicePtr::from(interface_eta), + g: DevicePtr::from(g), + albedo: DevicePtr::from(albedo), + conductor_uroughness: DevicePtr::from(conductor_uroughness), + conductor_vroughness: DevicePtr::from(conductor_vroughness), + conductor_eta: DevicePtr::from(conductor_eta), + k: DevicePtr::from(k), + reflectance: DevicePtr::from(reflectance), remap_roughness, max_depth, n_samples, @@ -285,7 +285,7 @@ impl MaterialTrait for CoatedConductorMaterial { self.max_depth as usize, self.n_samples as usize, )); - BSDF::new(ctx.ns, ctx.dpdus, Ptr::from(&bxdf)) + BSDF::new(ctx.ns, ctx.dpdus, DevicePtr::from(&bxdf)) } fn get_bssrdf( @@ -326,11 +326,11 @@ impl MaterialTrait for CoatedConductorMaterial { tex_eval.can_evaluate(&float_textures, &spectrum_textures) } - fn get_normal_map(&self) -> Option<&Image> { + fn get_normal_map(&self) -> Option<&DeviceImage> { Some(&*self.normal_map) } - fn get_displacement(&self) -> Ptr { + fn get_displacement(&self) -> DevicePtr { self.displacement } diff --git a/shared/src/materials/complex.rs b/shared/src/materials/complex.rs index 761111e..974eb5e 100644 --- a/shared/src/materials/complex.rs +++ b/shared/src/materials/complex.rs @@ -6,40 +6,40 @@ use crate::bxdfs::{ use crate::core::bsdf::BSDF; use crate::core::bssrdf::{BSSRDF, BSSRDFTable}; use crate::core::bxdf::BxDF; -use crate::core::image::Image; +use crate::core::image::DeviceImage; use crate::core::material::{Material, MaterialEvalContext, MaterialTrait}; use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::textures::GPUSpectrumMixTexture; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use crate::utils::math::clamp; #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct HairMaterial { - pub sigma_a: Ptr, - pub color: Ptr, - pub eumelanin: Ptr, - pub pheomelanin: Ptr, - pub eta: Ptr, - pub beta_m: Ptr, - pub beta_n: Ptr, - pub alpha: Ptr, + pub sigma_a: DevicePtr, + pub color: DevicePtr, + pub eumelanin: DevicePtr, + pub pheomelanin: DevicePtr, + pub eta: DevicePtr, + pub beta_m: DevicePtr, + pub beta_n: DevicePtr, + pub alpha: DevicePtr, } impl HairMaterial { #[cfg(not(target_os = "cuda"))] pub fn new( - sigma_a: Ptr, - color: Ptr, - eumelanin: Ptr, - pheomelanin: Ptr, - eta: Ptr, - beta_m: Ptr, - beta_n: Ptr, - alpha: Ptr, + sigma_a: DevicePtr, + color: DevicePtr, + eumelanin: DevicePtr, + pheomelanin: DevicePtr, + eta: DevicePtr, + beta_m: DevicePtr, + beta_n: DevicePtr, + alpha: DevicePtr, ) -> Self { Self { sigma_a, @@ -76,12 +76,12 @@ impl MaterialTrait for HairMaterial { todo!() } - fn get_normal_map(&self) -> Option<&Image> { + fn get_normal_map(&self) -> Option<&DeviceImage> { todo!() } - fn get_displacement(&self) -> Ptr { - Ptr::null() + fn get_displacement(&self) -> DevicePtr { + DevicePtr::null() } fn has_subsurface_scattering(&self) -> bool { @@ -92,9 +92,9 @@ impl MaterialTrait for HairMaterial { #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct MeasuredMaterial { - pub displacement: Ptr, - pub normal_map: Ptr, - pub brdf: Ptr, + pub displacement: DevicePtr, + pub normal_map: DevicePtr, + pub brdf: DevicePtr, } impl MaterialTrait for MeasuredMaterial { @@ -121,11 +121,11 @@ impl MaterialTrait for MeasuredMaterial { true } - fn get_normal_map(&self) -> Option<&Image> { + fn get_normal_map(&self) -> Option<&DeviceImage> { Some(&*self.normal_map) } - fn get_displacement(&self) -> Ptr { + fn get_displacement(&self) -> DevicePtr { self.displacement } @@ -137,16 +137,16 @@ impl MaterialTrait for MeasuredMaterial { #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct SubsurfaceMaterial { - pub normal_map: Ptr, - pub displacement: Ptr, - pub sigma_a: Ptr, - pub sigma_s: Ptr, - pub reflectance: Ptr, - pub mfp: Ptr, + pub normal_map: DevicePtr, + pub displacement: DevicePtr, + pub sigma_a: DevicePtr, + pub sigma_s: DevicePtr, + pub reflectance: DevicePtr, + pub mfp: DevicePtr, pub eta: Float, pub scale: Float, - pub u_roughness: Ptr, - pub v_roughness: Ptr, + pub u_roughness: DevicePtr, + pub v_roughness: DevicePtr, pub remap_roughness: bool, pub table: BSSRDFTable, } @@ -173,11 +173,11 @@ impl MaterialTrait for SubsurfaceMaterial { todo!() } - fn get_normal_map(&self) -> Option<&Image> { + fn get_normal_map(&self) -> Option<&DeviceImage> { todo!() } - fn get_displacement(&self) -> Ptr { + fn get_displacement(&self) -> DevicePtr { todo!() } diff --git a/shared/src/materials/conductor.rs b/shared/src/materials/conductor.rs index 26792e3..3454cb3 100644 --- a/shared/src/materials/conductor.rs +++ b/shared/src/materials/conductor.rs @@ -4,26 +4,26 @@ use crate::bxdfs::{ use crate::core::bsdf::BSDF; use crate::core::bssrdf::BSSRDF; use crate::core::bxdf::BxDF; -use crate::core::image::Image; +use crate::core::image::DeviceImage; use crate::core::material::{Material, MaterialEvalContext, MaterialTrait}; use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::spectra::{SampledSpectrum, SampledWavelengths}; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use crate::utils::math::clamp; #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct ConductorMaterial { - pub displacement: Ptr, - pub eta: Ptr, - pub k: Ptr, - pub reflectance: Ptr, - pub u_roughness: Ptr, - pub v_roughness: Ptr, + pub displacement: DevicePtr, + pub eta: DevicePtr, + pub k: DevicePtr, + pub reflectance: DevicePtr, + pub u_roughness: DevicePtr, + pub v_roughness: DevicePtr, pub remap_roughness: bool, - pub normal_map: Ptr, + pub normal_map: DevicePtr, } impl MaterialTrait for ConductorMaterial { @@ -50,11 +50,11 @@ impl MaterialTrait for ConductorMaterial { ) } - fn get_normal_map(&self) -> Option<&Image> { + fn get_normal_map(&self) -> Option<&DeviceImage> { todo!() } - fn get_displacement(&self) -> Ptr { + fn get_displacement(&self) -> DevicePtr { todo!() } diff --git a/shared/src/materials/dielectric.rs b/shared/src/materials/dielectric.rs index 58faa95..99f62ef 100644 --- a/shared/src/materials/dielectric.rs +++ b/shared/src/materials/dielectric.rs @@ -4,23 +4,23 @@ use crate::bxdfs::{ use crate::core::bsdf::BSDF; use crate::core::bssrdf::BSSRDF; use crate::core::bxdf::BxDF; -use crate::core::image::Image; +use crate::core::image::DeviceImage; use crate::core::material::{Material, MaterialEvalContext, MaterialTrait}; use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::spectra::{SampledSpectrum, SampledWavelengths}; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use crate::utils::math::clamp; #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct DielectricMaterial { - normal_map: Ptr, - displacement: Ptr, - u_roughness: Ptr, - v_roughness: Ptr, - eta: Ptr, + normal_map: DevicePtr, + displacement: DevicePtr, + u_roughness: DevicePtr, + v_roughness: DevicePtr, + eta: DevicePtr, remap_roughness: bool, } @@ -51,7 +51,7 @@ impl MaterialTrait for DielectricMaterial { let distrib = TrowbridgeReitzDistribution::new(u_rough, v_rough); let bxdf = BxDF::Dielectric(DielectricBxDF::new(sampled_eta, distrib)); - BSDF::new(ctx.ns, ctx.dpdus, Ptr::from(&bxdf)) + BSDF::new(ctx.ns, ctx.dpdus, DevicePtr::from(&bxdf)) } fn get_bssrdf( @@ -67,11 +67,11 @@ impl MaterialTrait for DielectricMaterial { tex_eval.can_evaluate(&[self.u_roughness, self.v_roughness], &[]) } - fn get_normal_map(&self) -> Option<&Image> { + fn get_normal_map(&self) -> Option<&DeviceImage> { Some(&*self.normal_map) } - fn get_displacement(&self) -> Ptr { + fn get_displacement(&self) -> DevicePtr { self.displacement } @@ -83,9 +83,9 @@ impl MaterialTrait for DielectricMaterial { #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct ThinDielectricMaterial { - pub displacement: Ptr, - pub normal_map: Ptr, - pub eta: Ptr, + pub displacement: DevicePtr, + pub normal_map: DevicePtr, + pub eta: DevicePtr, } impl MaterialTrait for ThinDielectricMaterial { fn get_bsdf( @@ -109,11 +109,11 @@ impl MaterialTrait for ThinDielectricMaterial { true } - fn get_normal_map(&self) -> Option<&Image> { + fn get_normal_map(&self) -> Option<&DeviceImage> { Some(&*self.normal_map) } - fn get_displacement(&self) -> Ptr { + fn get_displacement(&self) -> DevicePtr { self.displacement } diff --git a/shared/src/materials/diffuse.rs b/shared/src/materials/diffuse.rs index b1100a6..40ce86f 100644 --- a/shared/src/materials/diffuse.rs +++ b/shared/src/materials/diffuse.rs @@ -5,21 +5,21 @@ use crate::bxdfs::{ use crate::core::bsdf::BSDF; use crate::core::bssrdf::BSSRDF; use crate::core::bxdf::BxDF; -use crate::core::image::Image; +use crate::core::image::DeviceImage; use crate::core::material::{Material, MaterialEvalContext, MaterialTrait}; use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::spectra::{SampledSpectrum, SampledWavelengths}; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use crate::utils::math::clamp; #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct DiffuseMaterial { - pub normal_map: Ptr, - pub displacement: Ptr, - pub reflectance: Ptr, + pub normal_map: DevicePtr, + pub displacement: DevicePtr, + pub reflectance: DevicePtr, } impl MaterialTrait for DiffuseMaterial { @@ -31,7 +31,7 @@ impl MaterialTrait for DiffuseMaterial { ) -> BSDF { let r = tex_eval.evaluate_spectrum(&self.reflectance, ctx, lambda); let bxdf = BxDF::Diffuse(DiffuseBxDF::new(r)); - BSDF::new(ctx.ns, ctx.dpdus, Ptr::from(&bxdf)) + BSDF::new(ctx.ns, ctx.dpdus, DevicePtr::from(&bxdf)) } fn get_bssrdf( @@ -47,11 +47,11 @@ impl MaterialTrait for DiffuseMaterial { tex_eval.can_evaluate(&[], &[self.reflectance]) } - fn get_normal_map(&self) -> Option<&Image> { + fn get_normal_map(&self) -> Option<&DeviceImage> { Some(&*self.normal_map) } - fn get_displacement(&self) -> Ptr { + fn get_displacement(&self) -> DevicePtr { self.displacement } @@ -63,10 +63,10 @@ impl MaterialTrait for DiffuseMaterial { #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct DiffuseTransmissionMaterial { - pub image: Ptr, - pub displacement: Ptr, - pub reflectance: Ptr, - pub transmittance: Ptr, + pub image: DevicePtr, + pub displacement: DevicePtr, + pub reflectance: DevicePtr, + pub transmittance: DevicePtr, pub scale: Float, } @@ -92,11 +92,11 @@ impl MaterialTrait for DiffuseTransmissionMaterial { tex_eval.can_evaluate(&[self.reflectance, self.transmittance], &[]) } - fn get_normal_map(&self) -> Option<&Image> { + fn get_normal_map(&self) -> Option<&DeviceImage> { Some(&*self.image) } - fn get_displacement(&self) -> Ptr { + fn get_displacement(&self) -> DevicePtr { self.displacement } diff --git a/shared/src/materials/mix.rs b/shared/src/materials/mix.rs index 27b4260..135eb3c 100644 --- a/shared/src/materials/mix.rs +++ b/shared/src/materials/mix.rs @@ -4,7 +4,7 @@ use crate::bxdfs::{ use crate::core::bsdf::BSDF; use crate::core::bssrdf::BSSRDF; use crate::core::bxdf::BxDF; -use crate::core::image::Image; +use crate::core::image::DeviceImage; use crate::core::material::{Material, MaterialEvalContext, MaterialTrait}; use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::spectrum::{Spectrum, SpectrumTrait}; @@ -12,13 +12,13 @@ use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::utils::hash::hash_float; use crate::utils::math::clamp; -use crate::utils::{ArenaPtr, Ptr}; +use crate::utils::{DevicePtr, Ptr}; #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct MixMaterial { - pub amount: Ptr, - pub materials: [ArenaPtr; 2], + pub amount: DevicePtr, + pub materials: [Ptr; 2], } impl MixMaterial { @@ -69,11 +69,11 @@ impl MaterialTrait for MixMaterial { tex_eval.can_evaluate(&[self.amount], &[]) } - fn get_normal_map(&self) -> Option<&Image> { + fn get_normal_map(&self) -> Option<&DeviceImage> { None } - fn get_displacement(&self) -> Ptr { + fn get_displacement(&self) -> DevicePtr { panic!( "MixMaterial::get_displacement() shouldn't be called. \ Displacement is not supported on Mix materials directly." diff --git a/shared/src/spectra/colorspace.rs b/shared/src/spectra/colorspace.rs index bf858be..a79e8d0 100644 --- a/shared/src/spectra/colorspace.rs +++ b/shared/src/spectra/colorspace.rs @@ -3,17 +3,17 @@ use crate::core::geometry::Point2f; use crate::core::pbrt::Float; use crate::spectra::{DenselySampledSpectrum, SampledSpectrum}; use crate::utils::math::SquareMatrix3f; -use crate::utils::ptr::Ptr; +use crate::utils::ptr::DevicePtr; use std::cmp::{Eq, PartialEq}; #[repr(C)] #[derive(Copy, Debug, Clone)] pub struct StandardColorSpaces { - pub srgb: Ptr, - pub dci_p3: Ptr, - pub rec2020: Ptr, - pub aces2065_1: Ptr, + pub srgb: DevicePtr, + pub dci_p3: DevicePtr, + pub rec2020: DevicePtr, + pub aces2065_1: DevicePtr, } #[repr(C)] @@ -24,7 +24,7 @@ pub struct RGBColorSpace { pub b: Point2f, pub w: Point2f, pub illuminant: DenselySampledSpectrum, - pub rgb_to_spectrum_table: Ptr, + pub rgb_to_spectrum_table: DevicePtr, pub xyz_from_rgb: SquareMatrix3f, pub rgb_from_xyz: SquareMatrix3f, } @@ -52,6 +52,14 @@ impl RGBColorSpace { self.rgb_from_xyz * other.xyz_from_rgb } + + pub fn luminance_vector(&self) -> RGB { + RGB::new( + self.xyz_from_rgb[1][0], + self.xyz_from_rgb[1][1], + self.xyz_from_rgb[1][2], + ) + } } impl PartialEq for RGBColorSpace { diff --git a/shared/src/spectra/rgb.rs b/shared/src/spectra/rgb.rs index 1044b10..1f0d454 100644 --- a/shared/src/spectra/rgb.rs +++ b/shared/src/spectra/rgb.rs @@ -4,7 +4,7 @@ use super::{ }; use crate::core::color::{RGB, RGBSigmoidPolynomial, XYZ}; use crate::core::spectrum::SpectrumTrait; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use crate::Float; @@ -69,7 +69,7 @@ impl SpectrumTrait for UnboundedRGBSpectrum { pub struct RGBIlluminantSpectrum { pub scale: Float, pub rsp: RGBSigmoidPolynomial, - pub illuminant: Ptr, + pub illuminant: DevicePtr, } impl RGBIlluminantSpectrum { @@ -85,7 +85,7 @@ impl RGBIlluminantSpectrum { Self { scale, rsp, - illuminant: Ptr::from(&illuminant), + illuminant: DevicePtr::from(&illuminant), } } } diff --git a/shared/src/spectra/simple.rs b/shared/src/spectra/simple.rs index 97bb901..4d2fcd6 100644 --- a/shared/src/spectra/simple.rs +++ b/shared/src/spectra/simple.rs @@ -2,7 +2,7 @@ use super::cie::*; use super::sampled::{LAMBDA_MAX, LAMBDA_MIN}; use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::spectra::{N_SPECTRUM_SAMPLES, SampledSpectrum, SampledWavelengths}; -use crate::utils::ptr::Ptr; +use crate::utils::ptr::DevicePtr; use crate::{Float, find_interval}; use core::slice; use std::hash::{Hash, Hasher}; @@ -35,7 +35,7 @@ impl SpectrumTrait for ConstantSpectrum { pub struct DenselySampledSpectrum { pub lambda_min: i32, pub lambda_max: i32, - pub values: Ptr, + pub values: DevicePtr, } unsafe impl Send for DenselySampledSpectrum {} @@ -130,8 +130,8 @@ impl SpectrumTrait for DenselySampledSpectrum { #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct PiecewiseLinearSpectrum { - pub lambdas: Ptr, - pub values: Ptr, + pub lambdas: DevicePtr, + pub values: DevicePtr, pub count: u32, } diff --git a/shared/src/textures/bilerp.rs b/shared/src/textures/bilerp.rs index 57fd128..a521053 100644 --- a/shared/src/textures/bilerp.rs +++ b/shared/src/textures/bilerp.rs @@ -3,7 +3,7 @@ use crate::core::spectrum::Spectrum; use crate::core::spectrum::SpectrumTrait; use crate::core::texture::{TextureEvalContext, TextureMapping2D}; use crate::spectra::{SampledSpectrum, SampledWavelengths}; -use crate::utils::{Ptr, Transform}; +use crate::utils::{DevicePtr, Transform}; #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -48,19 +48,19 @@ impl FloatBilerpTexture { #[derive(Clone, Copy, Debug)] pub struct SpectrumBilerpTexture { pub mapping: TextureMapping2D, - pub v00: Ptr, - pub v01: Ptr, - pub v10: Ptr, - pub v11: Ptr, + pub v00: DevicePtr, + pub v01: DevicePtr, + pub v10: DevicePtr, + pub v11: DevicePtr, } impl SpectrumBilerpTexture { pub fn new( mapping: TextureMapping2D, - v00: Ptr, - v01: Ptr, - v10: Ptr, - v11: Ptr, + v00: DevicePtr, + v01: DevicePtr, + v10: DevicePtr, + v11: DevicePtr, ) -> Self { Self { mapping, diff --git a/shared/src/textures/checkerboard.rs b/shared/src/textures/checkerboard.rs index 1600cf5..629ccab 100644 --- a/shared/src/textures/checkerboard.rs +++ b/shared/src/textures/checkerboard.rs @@ -4,12 +4,12 @@ use crate::core::texture::{ TextureMapping3DTrait, }; use crate::spectra::{SampledSpectrum, SampledWavelengths}; -use crate::utils::{ArenaPtr, Ptr, math::square}; +use crate::utils::{DevicePtr, Ptr, math::square}; fn checkerboard( ctx: &TextureEvalContext, - map2d: Ptr, - map3d: Ptr, + map2d: DevicePtr, + map3d: DevicePtr, ) -> Float { let d = |x: Float| -> Float { let y = x / 2. - (x / 2.).floor() - 0.5; @@ -43,9 +43,9 @@ fn checkerboard( #[repr(C)] #[derive(Debug, Copy, Clone)] pub struct FloatCheckerboardTexture { - pub map2d: Ptr, - pub map3d: Ptr, - pub tex: [ArenaPtr; 2], + pub map2d: DevicePtr, + pub map3d: DevicePtr, + pub tex: [Ptr; 2], } impl FloatCheckerboardTexture { @@ -74,9 +74,9 @@ impl FloatCheckerboardTexture { #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct SpectrumCheckerboardTexture { - pub map2d: Ptr, - pub map3d: Ptr, - pub tex: [ArenaPtr; 2], + pub map2d: DevicePtr, + pub map3d: DevicePtr, + pub tex: [Ptr; 2], } impl SpectrumCheckerboardTexture { diff --git a/shared/src/textures/dots.rs b/shared/src/textures/dots.rs index 896466f..77158eb 100644 --- a/shared/src/textures/dots.rs +++ b/shared/src/textures/dots.rs @@ -4,7 +4,7 @@ use crate::core::texture::{ GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext, TextureMapping2D, }; use crate::spectra::sampled::{SampledSpectrum, SampledWavelengths}; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use crate::utils::math::square; use crate::utils::noise::noise_2d; @@ -28,8 +28,8 @@ fn inside_polka_dot(st: Point2f) -> bool { #[derive(Debug, Clone, Copy)] pub struct FloatDotsTexture { pub mapping: TextureMapping2D, - pub outside_dot: Ptr, - pub inside_dot: Ptr, + pub outside_dot: DevicePtr, + pub inside_dot: DevicePtr, } impl FloatDotsTexture { @@ -53,8 +53,8 @@ impl FloatDotsTexture { #[derive(Clone, Copy, Debug)] pub struct SpectrumDotsTexture { pub mapping: TextureMapping2D, - pub outside_dot: Ptr, - pub inside_dot: Ptr, + pub outside_dot: DevicePtr, + pub inside_dot: DevicePtr, } impl SpectrumDotsTexture { diff --git a/shared/src/textures/image.rs b/shared/src/textures/image.rs index e9c912d..901ef54 100644 --- a/shared/src/textures/image.rs +++ b/shared/src/textures/image.rs @@ -95,11 +95,13 @@ impl GPUFloatImageTexture { 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.); + let result = if self.invert { + (1.0 - val).max(0.0) // Invert the pixel intensity } else { - return v; - } + val + }; + + return result * self.scale; } } } diff --git a/shared/src/textures/marble.rs b/shared/src/textures/marble.rs index 47bd726..f6f2a47 100644 --- a/shared/src/textures/marble.rs +++ b/shared/src/textures/marble.rs @@ -6,7 +6,7 @@ use crate::core::texture::{TextureEvalContext, TextureMapping3D}; use crate::spectra::{RGBAlbedoSpectrum, RGBColorSpace, SampledSpectrum, SampledWavelengths}; use crate::utils::math::clamp; use crate::utils::noise::fbm; -use crate::utils::ptr::Ptr; +use crate::utils::ptr::DevicePtr; use crate::utils::splines::evaluate_cubic_bezier; #[repr(C)] @@ -18,7 +18,7 @@ pub struct MarbleTexture { pub scale: Float, pub variation: Float, // TODO: DO not forget to pass StandardColorSpace here!! - pub colorspace: Ptr, + pub colorspace: DevicePtr, } unsafe impl Send for MarbleTexture {} diff --git a/shared/src/textures/mix.rs b/shared/src/textures/mix.rs index 4be69ab..850284e 100644 --- a/shared/src/textures/mix.rs +++ b/shared/src/textures/mix.rs @@ -2,14 +2,14 @@ use crate::Float; use crate::core::geometry::{Vector3f, VectorLike}; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext}; use crate::spectra::{SampledSpectrum, SampledWavelengths}; -use crate::utils::ArenaPtr; +use crate::utils::Ptr; #[repr(C)] #[derive(Copy, Clone, Debug)] pub struct GPUFloatMixTexture { - pub tex1: ArenaPtr, - pub tex2: ArenaPtr, - pub amount: ArenaPtr, + pub tex1: Ptr, + pub tex2: Ptr, + pub amount: Ptr, } impl GPUFloatMixTexture { @@ -34,8 +34,8 @@ impl GPUFloatMixTexture { #[repr(C)] #[derive(Copy, Clone, Debug)] pub struct GPUFloatDirectionMixTexture { - pub tex1: ArenaPtr, - pub tex2: ArenaPtr, + pub tex1: Ptr, + pub tex2: Ptr, pub dir: Vector3f, } @@ -61,9 +61,9 @@ impl GPUFloatDirectionMixTexture { #[repr(C)] #[derive(Copy, Clone, Debug)] pub struct GPUSpectrumMixTexture { - pub tex1: ArenaPtr, - pub tex2: ArenaPtr, - pub amount: ArenaPtr, + pub tex1: Ptr, + pub tex2: Ptr, + pub amount: Ptr, } impl GPUSpectrumMixTexture { @@ -98,8 +98,8 @@ impl GPUSpectrumMixTexture { #[repr(C)] #[derive(Copy, Clone, Debug)] pub struct GPUSpectrumDirectionMixTexture { - pub tex1: ArenaPtr, - pub tex2: ArenaPtr, + pub tex1: Ptr, + pub tex2: Ptr, pub dir: Vector3f, } diff --git a/shared/src/textures/ptex.rs b/shared/src/textures/ptex.rs index 8a0589e..19abde2 100644 --- a/shared/src/textures/ptex.rs +++ b/shared/src/textures/ptex.rs @@ -6,7 +6,7 @@ use crate::spectra::{ RGBAlbedoSpectrum, RGBColorSpace, RGBIlluminantSpectrum, RGBUnboundedSpectrum, SampledSpectrum, SampledWavelengths, StandardColorSpaces, }; -use crate::utils::ptr::{Ptr, Slice}; +use crate::utils::ptr::{DevicePtr, Slice}; #[repr(C)] #[derive(Debug, Clone, Copy)] diff --git a/shared/src/textures/scaled.rs b/shared/src/textures/scaled.rs index 435c902..0d79b6f 100644 --- a/shared/src/textures/scaled.rs +++ b/shared/src/textures/scaled.rs @@ -1,13 +1,13 @@ use crate::Float; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext}; use crate::spectra::{SampledSpectrum, SampledWavelengths}; -use crate::utils::ArenaPtr; +use crate::utils::Ptr; #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct GPUFloatScaledTexture { - pub tex: ArenaPtr, - pub scale: ArenaPtr, + pub tex: Ptr, + pub scale: Ptr, } impl GPUFloatScaledTexture { @@ -23,8 +23,8 @@ impl GPUFloatScaledTexture { #[repr(C)] #[derive(Debug, Clone, Copy)] pub struct GPUSpectrumScaledTexture { - pub tex: ArenaPtr, - pub scale: ArenaPtr, + pub tex: Ptr, + pub scale: Ptr, } impl GPUSpectrumScaledTexture { diff --git a/shared/src/utils/math.rs b/shared/src/utils/math.rs index 1569be7..c9c9b12 100644 --- a/shared/src/utils/math.rs +++ b/shared/src/utils/math.rs @@ -5,7 +5,7 @@ use crate::core::pbrt::{Float, FloatBitOps, FloatBits, ONE_MINUS_EPSILON, PI, PI use crate::utils::hash::{hash_buffer, mix_bits}; use crate::utils::sobol::{SOBOL_MATRICES_32, VDC_SOBOL_MATRICES, VDC_SOBOL_MATRICES_INV}; -use crate::utils::Ptr; +use crate::utils::DevicePtr; use half::f16; use num_traits::{Float as NumFloat, Num, One, Signed, Zero}; use std::error::Error; @@ -753,7 +753,7 @@ pub fn inverse_radical_inverse(mut inverse: u64, base: u64, n_digits: u64) -> u6 pub struct DigitPermutation { pub base: u32, pub n_digits: u32, - pub permutations: Ptr, + pub permutations: DevicePtr, } impl DigitPermutation { diff --git a/shared/src/utils/mesh.rs b/shared/src/utils/mesh.rs index da87a1e..b9bd110 100644 --- a/shared/src/utils/mesh.rs +++ b/shared/src/utils/mesh.rs @@ -1,8 +1,8 @@ use crate::Float; use crate::core::geometry::{Normal3f, Point2f, Point3f, Vector3f}; +use crate::utils::Ptr; use crate::utils::Transform; -use crate::utils::ptr::Ptr; -use crate::utils::sampling::PiecewiseConstant2D; +use crate::utils::sampling::DevicePiecewiseConstant2D; #[repr(C)] #[derive(Debug, Copy, Clone)] @@ -30,5 +30,5 @@ pub struct BilinearPatchMesh { pub p: Ptr, pub n: Ptr, pub uv: Ptr, - pub image_distribution: Ptr, + pub image_distribution: Ptr, } diff --git a/shared/src/utils/mod.rs b/shared/src/utils/mod.rs index 9b0e4e4..0fdcf82 100644 --- a/shared/src/utils/mod.rs +++ b/shared/src/utils/mod.rs @@ -15,7 +15,7 @@ pub mod sobol; pub mod splines; pub mod transform; -pub use ptr::{ArenaPtr, Ptr}; +pub use ptr::{DevicePtr, Ptr}; pub use transform::{AnimatedTransform, Transform, TransformGeneric}; #[inline] diff --git a/shared/src/utils/ptr.rs b/shared/src/utils/ptr.rs index c9e0e7b..56359bc 100644 --- a/shared/src/utils/ptr.rs +++ b/shared/src/utils/ptr.rs @@ -3,84 +3,63 @@ use core::ops::Index; #[repr(C)] #[derive(Debug)] -pub struct ArenaPtr { - offset: i32, - _marker: PhantomData, +pub struct Ptr { + pub offset: u32, + pub _marker: PhantomData, } -impl Clone for ArenaPtr { +impl Clone for Ptr { fn clone(&self) -> Self { *self } } +impl Copy for Ptr {} -impl Copy for ArenaPtr {} - -impl ArenaPtr { +impl Ptr { + pub const NULL_OFFSET: u32 = 0xFFFFFFFF; pub fn null() -> Self { Self { - offset: 0xFFFFFFFF, + offset: Self::NULL_OFFSET, _marker: PhantomData, } } pub fn is_null(&self) -> bool { - self.offset == 0xFFFFFFFF + self.offset == Self::NULL_OFFSET } #[inline(always)] - pub unsafe fn as_ptr(&self, base: *const u8) -> *const T { + pub unsafe fn deref<'a>(&self, base: *const u8) -> &'a T { if self.is_null() { - core::ptr::null() - } else { - unsafe { base.add(self.offset as usize) as *const T } + panic!("Null pointer dereference"); } - } - - #[inline(always)] - pub unsafe fn as_ref<'a>(&self, base: *const u8) -> &'a T { - unsafe { &*self.as_ptr(base) } - } - - #[cfg(not(target_os = "cuda"))] - pub fn new(me: *const Self, target: *const T) -> Self { - if target.is_null() { - return Self::null(); - } - - let diff = unsafe { (target as *const u8).offset_from(me as *const u8) }; - - if diff > i32::MAX as isize || diff < i32::MIN as isize { - panic!("RelPtr offset out of i32 range! Are objects too far apart?"); - } - - Self { - offset: diff as i32, - _marker: PhantomData, + unsafe { + let ptr = base.add(self.offset as usize); + &*(ptr as *const T) } } } #[repr(transparent)] #[derive(Debug, Clone, Copy)] -pub struct Ptr(pub *const T); +pub struct DevicePtr(pub *const T); -impl Default for Ptr { +impl Default for DevicePtr { fn default() -> Self { Self(core::ptr::null()) } } -impl PartialEq for Ptr { +impl PartialEq for DevicePtr { #[inline(always)] fn eq(&self, other: &Self) -> bool { self.0 == other.0 } } -impl Eq for Ptr {} +impl Eq for DevicePtr {} -impl Ptr { +impl DevicePtr { pub fn null() -> Self { Self::default() } @@ -107,10 +86,10 @@ impl Ptr { } } -unsafe impl Send for Ptr {} -unsafe impl Sync for Ptr {} +unsafe impl Send for DevicePtr {} +unsafe impl Sync for DevicePtr {} -impl std::ops::Deref for Ptr { +impl std::ops::Deref for DevicePtr { type Target = T; #[inline(always)] @@ -119,19 +98,19 @@ impl std::ops::Deref for Ptr { } } -impl From<&T> for Ptr { +impl From<&T> for DevicePtr { fn from(r: &T) -> Self { Self(r as *const T) } } -impl From<&mut T> for Ptr { +impl From<&mut T> for DevicePtr { fn from(r: &mut T) -> Self { Self(r as *const T) } } -impl Index for Ptr { +impl Index for DevicePtr { type Output = T; #[inline(always)] @@ -142,7 +121,7 @@ impl Index for Ptr { } } -impl Index for Ptr { +impl Index for DevicePtr { type Output = T; #[inline(always)] @@ -154,7 +133,7 @@ impl Index for Ptr { #[repr(C)] #[derive(Clone, Copy, Debug)] pub struct Slice { - pub ptr: Ptr, + pub ptr: DevicePtr, pub len: u32, pub _marker: PhantomData, } @@ -163,7 +142,7 @@ unsafe impl Send for Slice {} unsafe impl Sync for Slice {} impl Slice { - pub fn new(ptr: Ptr, len: u32) -> Self { + pub fn new(ptr: DevicePtr, len: u32) -> Self { Self { ptr, len, diff --git a/shared/src/utils/sampling.rs b/shared/src/utils/sampling.rs index 50436c6..3389cf1 100644 --- a/shared/src/utils/sampling.rs +++ b/shared/src/utils/sampling.rs @@ -8,7 +8,7 @@ use crate::utils::math::{ catmull_rom_weights, clamp, difference_of_products, evaluate_polynomial, lerp, logistic, newton_bisection, safe_sqrt, square, sum_of_products, }; -use crate::utils::ptr::Ptr; +use crate::utils::ptr::DevicePtr; use crate::utils::rng::Rng; use crate::{ Float, INV_2_PI, INV_4_PI, INV_PI, ONE_MINUS_EPSILON, PI, PI_OVER_2, PI_OVER_4, find_interval, @@ -702,19 +702,19 @@ pub struct PLSample { #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct PiecewiseConstant1D { - pub func: Ptr, - pub cdf: Ptr, +pub struct DevicePiecewiseConstant1D { + pub func: DevicePtr, + pub cdf: DevicePtr, pub min: Float, pub max: Float, pub n: u32, pub func_integral: Float, } -unsafe impl Send for PiecewiseConstant1D {} -unsafe impl Sync for PiecewiseConstant1D {} +unsafe impl Send for DevicePiecewiseConstant1D {} +unsafe impl Sync for DevicePiecewiseConstant1D {} -impl PiecewiseConstant1D { +impl DevicePiecewiseConstant1D { pub fn integral(&self) -> Float { self.func_integral } @@ -742,14 +742,14 @@ impl PiecewiseConstant1D { #[repr(C)] #[derive(Debug, Copy, Clone)] -pub struct PiecewiseConstant2D { +pub struct DevicePiecewiseConstant2D { pub domain: Bounds2f, - pub p_marginal: PiecewiseConstant1D, + pub p_marginal: DevicePiecewiseConstant1D, pub n_conditionals: usize, - pub p_conditional_v: Ptr, + pub p_conditional_v: DevicePtr, } -impl PiecewiseConstant2D { +impl DevicePiecewiseConstant2D { pub fn resolution(&self) -> Point2i { Point2i::new( self.p_conditional_v[0u32].size() as i32, @@ -1056,10 +1056,10 @@ pub struct PiecewiseLinear2D { pub inv_patch_size: Vector2f, pub param_size: [u32; N], pub param_strides: [u32; N], - pub param_values: [Ptr; N], - pub data: Ptr, - pub marginal_cdf: Ptr, - pub conditional_cdf: Ptr, + pub param_values: [DevicePtr; N], + pub data: DevicePtr, + pub marginal_cdf: DevicePtr, + pub conditional_cdf: DevicePtr, } impl PiecewiseLinear2D { @@ -1311,7 +1311,7 @@ impl PiecewiseLinear2D { fn lookup( &self, - data: Ptr, + data: DevicePtr, i0: u32, size: u32, param_weight: &[(Float, Float); N], diff --git a/shared/src/utils/transform.rs b/shared/src/utils/transform.rs index cd29345..a13db3f 100644 --- a/shared/src/utils/transform.rs +++ b/shared/src/utils/transform.rs @@ -7,7 +7,7 @@ use super::math::{SquareMatrix, radians, safe_acos}; use super::quaternion::Quaternion; use crate::core::color::{RGB, XYZ}; use crate::core::geometry::{ - Bounds3f, Normal, Normal3f, Point, Point3f, Point3fi, Ray, Vector, Vector3f, Vector3fi, + Bounds3f, Frame, Normal, Normal3f, Point, Point3f, Point3fi, Ray, Vector, Vector3f, Vector3fi, VectorLike, }; use crate::core::interaction::{ @@ -714,6 +714,30 @@ where } } } + +impl From for TransformGeneric { + fn from(frame: Frame) -> Self { + let values: &[Float; 16] = &[ + frame.x.x(), + frame.x.y(), + frame.x.z(), + 0., + frame.y.x(), + frame.y.y(), + frame.y.z(), + 0., + frame.z.x(), + frame.z.y(), + frame.z.z(), + 0., + 0., + 0., + 0., + 1., + ]; + Self::from_flat(values).expect("Transform must be inversible") + } +} impl From for TransformGeneric { fn from(q: Quaternion) -> Self { let xx = q.v.x() * q.v.x(); diff --git a/src/core/image/io.rs b/src/core/image/io.rs index 30cde8b..ece3215 100644 --- a/src/core/image/io.rs +++ b/src/core/image/io.rs @@ -1,4 +1,4 @@ -use super::ImageBuffer; +use super::{Image, ImageAndMetadata}; use crate::utils::error::ImageError; use anyhow::{Context, Result, bail}; use exr::prelude::{read_first_rgba_layer_from_file, write_rgba_file}; @@ -6,7 +6,7 @@ use image_rs::ImageReader; use image_rs::{DynamicImage, ImageBuffer, Rgb, Rgba}; use shared::Float; use shared::core::color::{ColorEncoding, LINEAR, SRGB}; -use shared::core::image::Image; +use shared::core::image::DeviceImage; use std::fs::File; use std::io::{BufRead, BufReader, BufWriter, Read, Write}; use std::path::Path; @@ -21,7 +21,7 @@ pub trait ImageIO { fn to_u8_buffer(&self) -> Vec; } -impl ImageIO for ImageBuffer { +impl ImageIO for Image { fn read(path: &Path, encoding: Option) -> Result { let ext = path .extension() @@ -206,14 +206,14 @@ fn read_generic(path: &Path, encoding: Option) -> Result Image { + DynamicImage::ImageRgb32F(buf) => DeviceImage { format: PixelFormat::F32, resolution: res, channel_names: vec!["R".into(), "G".into(), "B".into()], encoding: LINEAR, pixels: PixelData::F32(buf.into_raw()), }, - DynamicImage::ImageRgba32F(buf) => Image { + DynamicImage::ImageRgba32F(buf) => DeviceImage { format: PixelFormat::F32, resolution: res, channel_names: vec!["R".into(), "G".into(), "B".into(), "A".into()], @@ -224,7 +224,7 @@ fn read_generic(path: &Path, encoding: Option) -> Result) -> Result Result { let w = image.layer_data.size.width() as i32; let h = image.layer_data.size.height() as i32; - let image = Image { + let image = DeviceImage { format: PixelFormat::F32, resolution: Point2i::new(w, h), channel_names: vec!["R".into(), "G".into(), "B".into(), "A".into()], @@ -355,7 +355,7 @@ fn read_pfm(path: &Path) -> Result { vec!["R".into(), "G".into(), "B".into()] }; - let image = Image { + let image = DeviceImage { format: PixelFormat::F32, resolution: Point2i::new(w, h), channel_names: names, diff --git a/src/core/image/mod.rs b/src/core/image/mod.rs index 72fbef3..7ae6c65 100644 --- a/src/core/image/mod.rs +++ b/src/core/image/mod.rs @@ -1,5 +1,5 @@ use shared::core::geometry::Point2i; -use shared::core::image::{Image, PixelFormat}; +use shared::core::image::{DeviceImage, ImageAccess, ImageBase, PixelFormat, WrapMode}; use shared::utils::math::f16_to_f32; use std::ops::Deref; @@ -8,6 +8,7 @@ pub mod metadata; pub mod ops; pub mod pixel; +pub use io::ImageIO; pub use metadata::*; impl std::fmt::Display for PixelFormat { @@ -75,39 +76,50 @@ pub enum PixelStorage { F32(Vec), } -pub struct ImageBuffer { - pub view: Image, +pub struct Image { + pub base: ImageBase, + pub pixels: PixelStorage, pub channel_names: Vec, - _storage: PixelStorage, } -impl Deref for ImageBuffer { - type Target = Image; - fn deref(&self) -> &Self::Target { - &self.view +impl ImageAccess for Image { + fn get_channel_with_wrap(&self, p: Point2i, c: i32, wrap_mode: WrapMode2D) -> Float { + todo!() + } + fn get_channel(&self, p: Point2i, c: i32) -> Float { + todo!() + } + fn lookup_nearest_channel_with_wrap(&self, p: Point2f, c: i32, wrap_mode: WrapMode2D) -> Float { + todo!() + } + fn lookup_nearest_channel(&self, p: Point2f, c: i32) -> Float { + todo!() } } #[derive(Debug, Clone)] pub struct ImageAndMetadata { - pub image: ImageBuffer, + pub image: Image, pub metadata: ImageMetadata, } -impl ImageBuffer { - fn resolution(&self) { - self.view.resolution() +impl Image { + pub fn resolution(&self) -> Point2i { + self.base.resolution + } + + fn n_channels(&self) -> i32 { + self.base.n_channels } pub fn new_empty() -> Self { Self { channel_names: Vec::new(), - _storage: PixelStorage::U8(Vec::new()), - view: Image { + pixels: PixelStorage::U8(Vec::new()), + base: ImageBase { format: PixelFormat::U256, resolution: Point2i::new(0, 0), n_channels: 0, - pixels: Pixels::U8(std::ptr::null()), encoding: ColorEncoding::default(), }, } @@ -120,23 +132,22 @@ impl ImageBuffer { encoding: ColorEncoding, ) -> Self { let n_channels = channel_names.len() as i32; - let (format, pixels_view) = match &storage { + let (format, pixels) = match &storage { PixelStorage::U8(vec) => (PixelFormat::U8, ImagePixels::U8(vec.as_ptr())), PixelStorage::F16(vec) => (PixelFormat::F16, ImagePixels::F16(vec.as_ptr())), PixelStorage::F32(vec) => (PixelFormat::F32, ImagePixels::F32(vec.as_ptr())), }; - let view = Image { + let base = ImageBase { format, resolution, n_channels, encoding, - pixels: pixels_view, }; Self { - view, - _storage: storage, + base, + pixels, channel_names, } } @@ -165,18 +176,17 @@ impl ImageBuffer { _ => unreachable!(), }; - let view = Image { + let base = ImageBase { format: PixelFormat::U256, resolution, n_channels, - pixels: Pixels::U8(ptr), encoding: encoding.clone(), }; Self { - view, + base, channel_names, - _storage: storage, + pixels: ptr, } } @@ -205,18 +215,17 @@ impl ImageBuffer { _ => unreachable!(), }; - let view = Image { + let base = ImageBase { format: PixelFormat::U256, resolution, n_channels, - pixels: Pixels::U8(ptr), encoding: encoding.clone(), }; Self { - view, + base, channel_names, - _storage: storage, + pixels: ptr, } } @@ -235,18 +244,17 @@ impl ImageBuffer { _ => unreachable!(), }; - let view = Image { + let base = ImageBase { format: PixelFormat::Half, resolution, n_channels, - pixels: Pixels::F16(ptr), encoding: ColorEncoding::default(), }; Self { - view, + base, channel_names, - _storage: storage, + pixels: ptr, } } @@ -265,18 +273,17 @@ impl ImageBuffer { _ => unreachable!(), }; - let view = Image { + let base = ImageBase { format: PixelFormat::Float, resolution, n_channels, - pixels: Pixels::F32(ptr), encoding: ColorEncoding::default(), }; Self { - view, + base, channel_names, - _storage: storage, + pixels: ptr, } } @@ -412,6 +419,16 @@ impl ImageBuffer { ImageChannelValues(values) } + pub fn get_channel_with_wrap( + &self, + p: Point2i, + c: i32, + wrap_mode: Option, + ) -> Float { + // if !self.remap_pixel_coords + 0. + } + pub fn channel_names_from_desc(&self, desc: &ImageChannelDesc) -> Vec<&str> { desc.offset .iter() @@ -566,9 +583,9 @@ impl ImageBuffer { pub fn mse( &self, desc: ImageChannelDesc, - ref_img: &Image, + ref_img: &DeviceImage, generate_mse_image: bool, - ) -> (ImageChannelValues, Option) { + ) -> (ImageChannelValues, Option) { let mut sum_se: Vec = vec![0.; desc.size()]; let names_ref = self.channel_names_from_desc(&desc); let ref_desc = ref_img @@ -613,7 +630,7 @@ impl ImageBuffer { sum_se.iter().map(|&s| (s / pixel_count) as Float).collect(); let mse_image = if generate_mse_image { - Some(Image::new( + Some(DeviceImage::new( PixelFormat::F32, self.resolution, &names_ref, @@ -633,4 +650,21 @@ impl ImageBuffer { PixelStorage::F32(vec) => Pixels::F32(vec.as_ptr()), }; } + + pub fn has_any_infinite_pixels(&self) -> bool { + if format == PixelFormat::Float { + return false; + } + + for y in 0..self.resolution().y() { + for x in 0..self.resolution().x() { + for c in 0..self.n_channels() { + if self.get_channel(Point2i::new(x, y), c).is_infinite() { + return true; + } + } + } + } + return false; + } } diff --git a/src/core/image/ops.rs b/src/core/image/ops.rs index f4b1770..11b63cd 100644 --- a/src/core/image/ops.rs +++ b/src/core/image/ops.rs @@ -1,5 +1,5 @@ // use rayon::prelude::*; -use super::ImageBuffer; +use super::Image; use rayon::prelude::*; use shared::Float; use shared::core::geometry::{Bounds2i, Point2i}; @@ -13,7 +13,7 @@ pub struct ResampleWeight { pub weight: [Float; 4], } -impl ImageBuffer { +impl Image { pub fn flip_y(&mut self) { let res = self.resolution; let nc = self.n_channels(); diff --git a/src/core/light.rs b/src/core/light.rs index 8497421..4fbf6c7 100644 --- a/src/core/light.rs +++ b/src/core/light.rs @@ -1,31 +1,191 @@ use shared::core::geometry::{Bounds3f, Point2i}; -use shared::core::image::Image; -use shared::core::light::LightBase; +use shared::core::image::DeviceImage; +use shared::core::light::{Light, LightBase}; use shared::core::medium::MediumInterface; use shared::core::spectrum::Spectrum; -use shared::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths}; -use shared::utils::Transform; +use shared::core::texture::SpectrumType; +use shared::lights::{ + DistantLight, GoniometricLight, InfiniteUniformLight, PointLight, ProjectionLight, SpotLight, +}; +use shared::spectra::{DenselySampledSpectrum, RGBColorSpace, SampledSpectrum, SampledWavelengths}; +use shared::utils::{Ptr, Transform}; use shared::{Float, PI}; -use crate::core::spectrum::SPECTRUM_CACHE; +use crate::core::spectrum::{SPECTRUM_CACHE, spectrum_to_photometric}; +use crate::lights::*; use crate::utils::containers::InternCache; +use crate::utils::{Arena, ParameterDictionary, Upload, resolve_filename}; -pub trait LightBaseTrait { - pub fn lookup_spectrum(s: &Spectrum) -> DenselySampledSpectrum { - let cache = SPECTRUM_CACHE.get_or_init(InternCache::new); - let dense_spectrum = DenselySampledSpectrum::from_spectrum(s); - cache.lookup(dense_spectrum).as_ref() - } +pub fn lookup_spectrum(s: &Spectrum) -> DenselySampledSpectrum { + let cache = SPECTRUM_CACHE.get_or_init(InternCache::new); + let dense_spectrum = DenselySampledSpectrum::from_spectrum(s); + cache.lookup(dense_spectrum).as_ref() } -impl LightBaseTrait for LightBase {} - -pub trait LightFactory { +pub trait CreateLight { fn new( render_from_light: Transform, medium_interface: MediumInterface, + le: Spectrum, scale: Float, - iemit: &Spectrum, - image: &Image, + shape: Option>, + alpha: Option>, + image: Option>, + image_color_space: Option>, + two_sided: Option, + fov: Option, + cos_fallof_start: Option, + total_width: Option, + ) -> Self; + + fn create( + arena: &mut Arena, + render_from_light: Transform, + medium: Medium, + parameters: &ParameterDictionary, + loc: &FileLoc, + shape: &Shape, + alpha_tex: &FloatTexture, + colorspace: Option<&RGBColorSpace>, + ) -> Light; +} + +pub trait LightFactory { + fn create( + name: &str, + arena: &mut Arena, + render_from_light: Transform, + medium: Medium, + parameters: &ParameterDictionary, + loc: &FileLoc, + shape: &Shape, + alpha_tex: &FloatTexture, + colorspace: Option<&RGBColorSpace>, ) -> Self; } + +impl LightFactory for Light { + fn create( + name: &str, + arena: &mut Arena, + render_from_light: Transform, + medium: Medium, + parameters: &ParameterDictionary, + loc: &FileLoc, + shape: &Shape, + alpha_tex: &FloatTexture, + colorspace: Option<&RGBColorSpace>, + ) -> Self { + match name { + "point" => PointLight::create( + arena, + render_from_light, + medium, + parameters, + loc, + shape, + alpha_tex, + colorspace, + ), + "spot" => SpotLight::create( + arena, + render_from_light, + medium, + parameters, + loc, + shape, + alpha_tex, + colorspace, + ), + "goniometric" => GoniometricLight::create( + arena, + render_from_light, + medium, + parameters, + loc, + shape, + alpha_tex, + colorspace, + ), + "projection" => ProjectionLight::create( + arena, + render_from_light, + medium, + parameters, + loc, + shape, + alpha_tex, + colorspace, + ), + "distant" => DistantLight::create( + arena, + render_from_light, + medium, + parameters, + loc, + shape, + alpha_tex, + colorspace, + ), + "infinite" => { + let colorspace = parameters.color_space.unwrap(); + let l = parameters.get_spectrum_array("L", SpectrumType::Illuminant); + let mut scale = parameters.get_one_float("scale", 1.); + let portal = parameters.get_point3f_array("portal"); + let filename = resolve_filename(parameters.get_one_string("filename", "")); + let e_v = parameters.get_one_float("illuminance", -1.); + if l.is_empty() && filename.is_empty() && portal.is_empty() { + if e_v > 0. { + let k_e = PI; + scale *= e_v / k_e; + } + let specific = InfiniteUniformLight::new( + render_from_light, + medium_interface, + arena.alloc(le), + scale, + None, + None, + None, + None, + None, + None, + None, + None, + ); + arena.alloc(specific); + return Light::InfiniteUniform(specific); + } else if !l.is_empty() && portal.is_empty() { + if !filename.is_empty() { + panic!( + "{}: Both \"L\" and \"filename\" specified for DiffuseAreaLight.", + loc + ); + } + scale /= spectrum_to_photometric(l[0]); + if e_v > 0. { + let k_e = PI; + scale *= e_v / k_e; + } + let specific = InfiniteUniformLight::new( + render_from_light, + medium_interface, + arena.alloc(le), + scale, + None, + None, + None, + None, + None, + None, + None, + None, + ); + + arena.alloc(specific); + return Light::InfiniteUniform(specific); + } + } + } + } +} diff --git a/src/core/material.rs b/src/core/material.rs index 65f0ac2..873d9dd 100644 --- a/src/core/material.rs +++ b/src/core/material.rs @@ -1,4 +1,4 @@ -use crate::core::image::ImageBuffer; +use crate::core::image::Image; use crate::utils::error::FileLoc; use crate::utils::parameters::ParameterDictionary; use shared::core::material::Material; @@ -8,7 +8,7 @@ use std::collections::HashMap; pub trait CreateMaterial: Sized { fn create( parameters: &TextureParameterDictionary, - normal_map: Option>, + normal_map: Option>, named_materials: &HashMap, loc: &FileLoc, ) -> Self; @@ -35,7 +35,7 @@ pub trait MaterialFactory { fn create( name: &str, params: &TextureParameterDictionary, - normal_map: Arc, + normal_map: Arc, named_materials: HashMap, loc: &FileLoc, ) -> Result; diff --git a/src/core/scene.rs b/src/core/scene.rs index 9e62180..80d7c6d 100644 --- a/src/core/scene.rs +++ b/src/core/scene.rs @@ -1,5 +1,5 @@ use crate::core::filter::FilterFactory; -use crate::core::image::{ImageBuffer, io::ImageIO}; +use crate::core::image::{Image, io::ImageIO}; use crate::core::texture::SpectrumTexture; use crate::utils::parallel::{AsyncJob, run_async}; use crate::utils::parameters::{ @@ -694,7 +694,7 @@ impl BasicScene { let job = crate::parallel::run_async(move || { let path = std::path::Path::new(&filename_clone); - let immeta = ImageBuffer::read(path, Some(ColorEncoding::Linear)) + let immeta = Image::read(path, Some(ColorEncoding::Linear)) .unwrap_or_else(|e| panic!("{}: unable to read normal map: {}", filename_clone, e)); let image = &immeta.image; diff --git a/src/core/shape.rs b/src/core/shape.rs index 4b0a3b1..e81ffe2 100644 --- a/src/core/shape.rs +++ b/src/core/shape.rs @@ -1,6 +1,6 @@ use crate::core::texture::FloatTexture; use crate::shapes::TriQuadMesh; -use crate::utils::{FileLoc, ParameterDictionary, resolve_filename}; +use crate::utils::{Arena, FileLoc, ParameterDictionary, resolve_filename}; use shared::core::options::get_options; use shared::core::shape::*; use shared::shapes::*; @@ -21,6 +21,7 @@ pub trait CreateShape { parameters: ParameterDictionary, float_textures: HashMap, loc: FileLoc, + arena: &mut Arena, ) -> Vec; } @@ -33,6 +34,7 @@ pub trait ShapeFactory { parameters: ParameterDictionary, float_textures: HashMap, loc: FileLoc, + arena: &mut Arena, ) -> Vec; } @@ -45,6 +47,7 @@ impl ShapeFactory for Shape { parameters: ParameterDictionary, float_textures: HashMap, loc: FileLoc, + arena: &mut Arena, ) -> Vec { match name { "sphere" => SphereShape::create( @@ -55,6 +58,7 @@ impl ShapeFactory for Shape { parameters, float_textures, loc, + arena, ), "cylinder" => CylinderShape::create( name, @@ -64,6 +68,7 @@ impl ShapeFactory for Shape { parameters, float_textures, loc, + arena, ), "disk" => DiskShape::create( name, @@ -73,6 +78,7 @@ impl ShapeFactory for Shape { parameters, float_textures, loc, + arena, ), "bilinearmesh" => BilinearPatchShape::create( name, @@ -82,6 +88,7 @@ impl ShapeFactory for Shape { parameters, float_textures, loc, + arena, ), "trianglemesh" => TriangleShape::create( name, @@ -91,6 +98,7 @@ impl ShapeFactory for Shape { parameters, float_textures, loc, + arena, ), "plymesh" => { let filename = resolve_filename(parameters.get_one_string("filename", "")); diff --git a/src/core/spectrum.rs b/src/core/spectrum.rs index 4fc51e1..3114e40 100644 --- a/src/core/spectrum.rs +++ b/src/core/spectrum.rs @@ -1,4 +1,9 @@ +use crate::core::light::LightBaseTrait; +use crate::spectra::cie_y; use crate::utils::containers::InternCache; +use shared::Float; +use shared::core::light::LightBase; +use shared::core::spectrum::Spectrum; pub static SPECTRUM_CACHE: Lazy>> = Lazy::new(|| Mutex::new(HashMap::new())); @@ -6,3 +11,11 @@ pub static SPECTRUM_CACHE: Lazy>> = fn get_spectrum_cache() -> &'static InternCache { SPECTRUM_CACHE.get_or_init(InternCache::new) } + +pub fn spectrum_to_photometric(s: Spectrum) -> Float { + let effective_spectrum = match s { + Spectrum::RGBIlluminant(ill) => &Spectrum::Dense(ill.illuminant), + _ => s, + }; + effective_spectrum.inner_product(cie_y) +} diff --git a/src/materials/coated.rs b/src/materials/coated.rs index ee3a345..6aceb7f 100644 --- a/src/materials/coated.rs +++ b/src/materials/coated.rs @@ -1,6 +1,6 @@ -use crate::core::image::ImageBuffer; +use crate::core::image::Image; use crate::core::material::CreateMaterial; -use crate::utils::parameters::ParameterDictionary; +use crate::utils::{Arena, ParameterDictionary}; use shared::core::spectrum::Spectrum; use shared::core::texture::SpectrumType; use shared::materials::coated::*; @@ -10,9 +10,10 @@ use shared::textures::SpectrumConstantTexture; impl CreateMaterial for CoatedDiffuseMaterial { fn create( parameters: &TextureParameterDictionary, - normal_map: Option>, + normal_map: Option>, named_materials: &HashMap, loc: &FileLoc, + area: &mut Arena, ) -> Self { let reflectance = parameters .get_spectrum_texture("reflectance", None, SpectrumType::Albedo) @@ -45,15 +46,30 @@ impl CreateMaterial for CoatedDiffuseMaterial { }); let displacement = parameters.get_float_texture("displacement"); let remap_roughness = parameters.get_one_bool("remaproughness", true); + arena.alloc(Self::new( + reflectance, + u_roughness, + v_roughness, + thickness, + albedo, + g, + eta, + displacement, + normal_map, + remap_roughness, + max_depth, + n_samples, + )); } } impl CreateMaterial for CoatedConductorMaterial { fn create( parameters: &TextureParameterDictionary, - normal_map: Option>, + normal_map: Option>, named_materials: &HashMap, loc: &FileLoc, + arena: &mut Arena, ) -> Result { let interface_u_roughness = parameters .get_float_texture_or_null("interface.uroughness") @@ -106,7 +122,7 @@ impl CreateMaterial for CoatedConductorMaterial { }); let displacement = parameters.get_float_texture_or_null("displacement"); let remap_roughness = parameters.get_one_bool("remaproughness", true); - Self::new( + let material = Self::new( displacement, normal_map, interface_u_roughness, @@ -123,6 +139,8 @@ impl CreateMaterial for CoatedConductorMaterial { remap_roughness, max_depth, n_samples, - ) + ); + arena.alloc(material); + return material; } } diff --git a/src/materials/complex.rs b/src/materials/complex.rs index 089aed5..53b3839 100644 --- a/src/materials/complex.rs +++ b/src/materials/complex.rs @@ -1,4 +1,5 @@ use crate::core::material::CreateMaterial; +use crate::utils::{Arena, FileLoc, TextureParameterDictionary}; use shared::core::bxdf::HairBxDF; use shared::core::spectrum::Spectrum; use shared::core::texture::{GPUFloatTexture, GPUSpectrumTexture}; @@ -10,6 +11,7 @@ impl CreateMaterial for HairMaterial { normal_map: Option>, named_materials: &HashMap, loc: &FileLoc, + arena: &mut Arena, ) -> Result { let sigma_a = parameters.get_spectrum_texture_or_null("sigma_a", SpectrumType::Unbounded); let reflectance = parameters @@ -57,7 +59,7 @@ impl CreateMaterial for HairMaterial { let beta_m = parameters.get_float_texture("beta_m", 0.3); let beta_n = parameters.get_float_texture("beta_n", 0.3); let alpha = parameters.get_float_texture("alpha", 2.); - HairMaterial::new( + let material = HairMaterial::new( sigma_a, reflectance, eumelanin, @@ -66,7 +68,10 @@ impl CreateMaterial for HairMaterial { beta_m, beta_n, alpha, - ) + ); + + arena.alloc(material); + return material; } } diff --git a/src/shapes/bilinear.rs b/src/shapes/bilinear.rs index 3cb71fb..3e561a4 100644 --- a/src/shapes/bilinear.rs +++ b/src/shapes/bilinear.rs @@ -1,11 +1,12 @@ -use crate::core::shape::{ALL_BILINEAR_MESHES, CreateShape}; +use crate::core::shape::{ALL_BILINEAR_MESHES, CreateMesh, CreateShape}; use crate::core::texture::FloatTexture; -use crate::shapes::mesh::BilinearPatchMeshHost; -use crate::utils::{FileLoc, ParameterDictionary}; +use crate::shapes::mesh::Mesh; +use crate::utils::{Arena, FileLoc, ParameterDictionary}; use shared::shapes::BilinearPatchShape; use shared::utils::Transform; +use std::collections::HashMap; -impl CreateShape for BilinearPatchShape { +impl CreateMesh for BilinearPatchShape { fn create( render_from_object: &Transform, _object_from_render: &Transform, @@ -13,6 +14,7 @@ impl CreateShape for BilinearPatchShape { parameters: &ParameterDictionary, _float_textures: &HashMap, _loc: &FileLoc, + arena: &mut Arena, ) -> Result { let mut vertex_indices = parameters.get_int_array("indices"); let mut p = parameters.get_point3f_array("P"); @@ -128,6 +130,7 @@ impl CreateShape for BilinearPatchShape { rectangle: false, })); } + arena.alloc(shapes); Ok(shapes) } } diff --git a/src/shapes/curves.rs b/src/shapes/curves.rs index bee1949..3aa3191 100644 --- a/src/shapes/curves.rs +++ b/src/shapes/curves.rs @@ -194,6 +194,7 @@ impl CreateShape for CurveShape { curves.extend(new_curves); } + arena.alloc(curves); Ok(curves) } } diff --git a/src/shapes/cylinder.rs b/src/shapes/cylinder.rs index 92df50b..c8d14b5 100644 --- a/src/shapes/cylinder.rs +++ b/src/shapes/cylinder.rs @@ -1,6 +1,6 @@ use crate::core::shape::CreateShape; use crate::core::texture::FloatTexture; -use crate::utils::{FileLoc, ParameterDictionary}; +use crate::utils::{Arena, FileLoc, ParameterDictionary}; use shared::core::shape::Shape; use shared::shapes::CylinderShape; use shared::utils::Transform; @@ -15,6 +15,7 @@ impl CreateShape for CylinderShape { parameters: ParameterDictionary, float_textures: HashMap, loc: FileLoc, + arena: &mut Arena, ) -> Result, String> { let radius = parameters.get_one_float("radius", 1.); let z_min = parameters.get_one_float("zmin", -1.); @@ -30,6 +31,7 @@ impl CreateShape for CylinderShape { phi_max, ); + arena.alloc(Shape::Cylinder(shape)); Ok(vec![Shape::Cylinder(shape)]) } } diff --git a/src/shapes/disk.rs b/src/shapes/disk.rs index 41369b1..49b9c06 100644 --- a/src/shapes/disk.rs +++ b/src/shapes/disk.rs @@ -1,6 +1,6 @@ use crate::core::shape::CreateShape; use crate::core::texture::FloatTexture; -use crate::utils::{FileLoc, ParameterDictionary}; +use crate::utils::{Arena, FileLoc, ParameterDictionary}; use shared::core::shape::Shape; use shared::shapes::DiskShape; use shared::utils::Transform; @@ -15,6 +15,7 @@ impl CreateShape for DiskShape { parameters: ParameterDictionary, float_textures: HashMap, loc: FileLoc, + arena: &mut Arena, ) -> Result, String> { let height = parameters.get_one_float("height", 0.); let radius = parameters.get_one_float("radius", 1.); @@ -30,6 +31,7 @@ impl CreateShape for DiskShape { reverse_orientation, ); + arena.alloc(Shape::Disk(shape)); Ok(vec![Shape::Disk(shape)]) } } diff --git a/src/shapes/mesh.rs b/src/shapes/mesh.rs index 6abd8fc..9420c01 100644 --- a/src/shapes/mesh.rs +++ b/src/shapes/mesh.rs @@ -3,7 +3,7 @@ use ply_rs::parser::Parser; use ply_rs::ply::{DefaultElement, Property}; use shared::utils::Transform; use shared::utils::mesh::{BilinearPatchMesh, TriangleMesh}; -use shared::utils::sampling::PiecewiseConstant2D; +use shared::utils::sampling::DevicePiecewiseConstant2D; use std::collections::HashMap; use std::fs::File; use std::path::Path; @@ -211,40 +211,32 @@ impl TriQuadMesh { } } -#[derive(Debug, Clone, Copy)] -pub struct TriangleMeshStorage { - vertex_indices: Vec, - p: Vec, - n: Vec, - s: Vec, - uv: Vec, - face_indices: Vec, -} - -#[derive(Debug, Clone, Copy)] -pub struct TriangleMeshHost { - pub view: TriangleMesh, - _storage: Arc, -} - -impl Deref for TriangleMeshHost { - type Target = TriangleMesh; - fn deref(&self) -> &Self::Target { - &self.view - } -} - -impl TriangleMeshHost { - pub fn new( - render_from_object: Transform, +pub trait TriangleMeshFactory { + fn create( + arena: &mut Arena, + render_from_object: &Transform, reverse_orientation: bool, - vertex_indices: Vec, - mut p: Vec, - mut s: Vec, - mut n: Vec, + vertex_indices: Vec, + p: Vec, + n: Vec, + s: Vec, uv: Vec, - face_indices: Vec, - ) -> Self { + face_indices: Vec, + ) -> ArenaPtr; +} + +impl TriangleMeshFactory for TriangleMesh { + fn create( + arena: &mut Arena, + render_from_object: &Transform, + reverse_orientation: bool, + vertex_indices: Vec, + p: Vec, + n: Vec, + s: Vec, + uv: Vec, + face_indices: Vec, + ) -> ArenaPtr { let n_triangles = indices.len() / 3; let n_vertices = p.len(); for pt in p.iter_mut() { @@ -342,7 +334,7 @@ pub struct BilinearMeshStorage { p: Vec, n: Vec, uv: Vec, - image_distribution: Option, + image_distribution: Option, } #[derive(Debug, Clone, Copy)] @@ -366,7 +358,7 @@ impl BilinearPatchMeshHost { mut p: Vec, mut n: Vec, uv: Vec, - image_distribution: Option, + image_distribution: Option, ) -> Self { let n_patches = indices.len() / 3; let n_vertices = p.len(); diff --git a/src/shapes/sphere.rs b/src/shapes/sphere.rs index 4cc1667..f98f94f 100644 --- a/src/shapes/sphere.rs +++ b/src/shapes/sphere.rs @@ -1,6 +1,6 @@ use crate::core::shape::CreateShape; use crate::core::texture::FloatTexture; -use crate::utils::{FileLoc, ParameterDictionary}; +use crate::utils::{Arena, FileLoc, ParameterDictionary}; use shared::core::shape::Shape; use shared::shapes::SphereShape; use shared::utils::Transform; @@ -14,6 +14,7 @@ impl CreateShape for SphereShape { parameters: ParameterDictionary, float_textures: HashMap, loc: FileLoc, + arena: &mut Arena, ) -> Result, String> { let radius = parameters.get_one_float("radius", 1.); let zmin = parameters.get_one_float("zmin", -radius); @@ -28,6 +29,7 @@ impl CreateShape for SphereShape { zmax, phimax, ); + arena.alloc(vec![Shape::Sphere(SphereShape)]); Ok(vec![Shape::Sphere(SphereShape)]) } } diff --git a/src/shapes/triangle.rs b/src/shapes/triangle.rs index 9d9ddaa..2bc32b7 100644 --- a/src/shapes/triangle.rs +++ b/src/shapes/triangle.rs @@ -1,7 +1,7 @@ use crate::core::shape::{ALL_TRIANGLE_MESHES, CreateShape}; use crate::core::texture::FloatTexture; use crate::shapes::mesh::TriangleMeshHost; -use crate::utils::{FileLoc, ParameterDictionary}; +use crate::utils::{Arena, FileLoc, ParameterDictionary}; use shared::shapes::TriangleShape; use shared::utils::Transform; @@ -12,6 +12,7 @@ impl CreateShape for TriangleShape { reverse_orientation: bool, parameters: ParameterDictionary, loc: FileLoc, + arena: &mut Arena, ) -> Result { let mut vertex_indices = parameters.get_int_array("indices"); let mut p = parameters.get_point3f_array("P"); @@ -104,6 +105,8 @@ impl CreateShape for TriangleShape { tri_index: i, })); } + + arena.alloc(shapes); Ok(shapes) } } diff --git a/src/textures/image.rs b/src/textures/image.rs index d106289..bda13ab 100644 --- a/src/textures/image.rs +++ b/src/textures/image.rs @@ -134,7 +134,7 @@ impl SpectrumTextureTrait for SpectrumImageTexture { #[derive(Debug, Clone)] pub struct FloatImageTexture { - base: ImageTextureBase, + pub base: ImageTextureBase, } impl FloatImageTexture { diff --git a/src/textures/mix.rs b/src/textures/mix.rs index c565da9..1f72fc9 100644 --- a/src/textures/mix.rs +++ b/src/textures/mix.rs @@ -1,16 +1,16 @@ use crate::core::texture::{ FloatTexture, FloatTextureTrait, SpectrumTexture, SpectrumTextureTrait, }; -use crate::utils::{FileLoc, TextureParameterDictionary}; +use crate::utils::{Arena, FileLoc, TextureParameterDictionary}; use shared::core::geometry::Vector3f; use shared::utils::Transform; use std::sync::Arc; #[derive(Debug, Clone)] pub struct FloatMixTexture { - tex1: Arc, - tex2: Arc, - amount: Arc, + pub tex1: Arc, + pub tex2: Arc, + pub amount: Arc, } impl FloatMixTexture { @@ -26,11 +26,12 @@ impl FloatMixTexture { _render_from_texture: &Transform, params: &TextureParameterDictionary, _loc: &FileLoc, + arena: &mut Arena, ) -> Self { let tex1 = params.get_float_texture("tex1", 0.); let tex2 = params.get_float_texture("tex2", 1.); let amount = params.get_float_texture("amount", 0.5); - Self::new(tex1, tex2, amount) + arena.alloc(Self::new(tex1, tex2, amount)) } } @@ -51,9 +52,9 @@ impl FloatTextureTrait for FloatMixTexture { #[derive(Debug, Clone)] pub struct FloatDirectionMixTexture { - tex1: Arc, - tex2: Arc, - dir: Vector3f, + pub tex1: Arc, + pub tex2: Arc, + pub dir: Vector3f, } impl FloatDirectionMixTexture { @@ -65,12 +66,13 @@ impl FloatDirectionMixTexture { render_from_texture: &Transform, params: &TextureParameterDictionary, _loc: &FileLoc, + arena: &mut Arena, ) -> Self { let dir_raw = params.get_one_vector3f("dir", Vector3f::new(0., 1., 0.)); let dir = render_from_texture.apply_to_vector(dir_raw).normalize(); let tex1 = params.get_float_texture("tex1", 0.); let tex2 = params.get_float_texture("tex2", 1.); - Self::new(tex1, tex2, dir) + arena.alloc(Self::new(tex1, tex2, dir)) } } diff --git a/src/textures/ptex.rs b/src/textures/ptex.rs index e80202d..115b7cc 100644 --- a/src/textures/ptex.rs +++ b/src/textures/ptex.rs @@ -1,4 +1,4 @@ -use crate::utils::{FileLoc, TextureParameterDictionary}; +use crate::utils::{Arena, FileLoc, TextureParameterDictionary}; use shared::core::texture::{SpectrumType, TextureEvalContext}; use shared::spectra::ColorEncoding; use shared::spectra::color::RGB; diff --git a/src/textures/scaled.rs b/src/textures/scaled.rs index 98eb25e..247fca7 100644 --- a/src/textures/scaled.rs +++ b/src/textures/scaled.rs @@ -1,15 +1,15 @@ use crate::core::texture::{ FloatTexture, FloatTextureTrait, SpectrumTexture, SpectrumTextureTrait, }; -use crate::utils::{FileLoc, TextureParameterDictionary}; +use crate::utils::{Arena, FileLoc, TextureParameterDictionary}; use shared::core::texture::TextureEvalContext; use shared::spectra::{SampledSpectrum, SampledWavelengths}; use shared::utils::Transform; #[derive(Debug, Clone)] pub struct FloatScaledTexture { - tex: Arc, - scale: Arc, + pub tex: Arc, + pub scale: Arc, } impl FloatScaledTexture { @@ -21,6 +21,7 @@ impl FloatScaledTexture { _render_from_texture: &Transform, params: &TextureParameterDictionary, _loc: &FileLoc, + arena: &mut Arena, ) -> FloatTexture { let mut tex = params.get_float_texture("tex", 1.); let mut scale = params.get_float_texture("scale", 1.); @@ -40,6 +41,7 @@ impl FloatScaledTexture { std::mem::swap(&mut tex, &mut scale); } std::mem::swap(&mut tex, &mut scale); + arena.alloc(FloatScaledTexture::new(tex, scale)); FloatTexture::FloatScaled(FloatScaledTexture::new(tex, scale)) } } @@ -56,8 +58,8 @@ impl FloatTextureTrait for FloatScaledTexture { #[derive(Clone, Debug)] pub struct SpectrumScaledTexture { - tex: Arc, - scale: Arc, + pub tex: Arc, + pub scale: Arc, } impl SpectrumTextureTrait for SpectrumScaledTexture { diff --git a/src/utils/math.rs b/src/utils/math.rs index 9c562c5..449b2eb 100644 --- a/src/utils/math.rs +++ b/src/utils/math.rs @@ -1,6 +1,6 @@ use half::f16; use shared::Float; -use shared::utils::Ptr; +use shared::utils::DevicePtr; use shared::utils::math::{DigitPermutation, PRIMES}; pub fn new_digit_permutation(base: u32, seed: u64) -> Vec { @@ -56,7 +56,7 @@ pub fn compute_radical_inverse_permutations(seed: u64) -> (Vec, Vec, - _cdf: Vec, +pub struct PiecewiseConstant1D { + pub func: Vec, + pub cdf: Vec, + pub func_integral: Float, + pub min: Float, + pub max: Float, } -impl std::ops::Deref for PiecewiseConstant1DHost { - type Target = PiecewiseConstant1D; - fn deref(&self) -> &Self::Target { - &self.view - } -} - -impl PiecewiseConstant1DHost { +impl PiecewiseConstant1D { pub fn new(f: &[Float]) -> Self { Self::new_with_bounds(f, 0.0, 1.0) } + pub fn to_shared(&self, arena: &mut Arena) -> DevicePiecewiseConstant1D { + let func_ptr = arena.alloc_slice(&self.func); + let cdf_ptr = arena.alloc_slice(&self.cdf); + + DevicePiecewiseConstant1D { + func: func_ptr, + cdf: cdf_ptr, + func_integral: self.func_integral, + n: func.len(), + min: self.min, + max: self.max, + } + } + pub fn new_with_bounds(f: &[Float], min: Float, max: Float) -> Self { let n = f.len(); @@ -47,44 +56,31 @@ impl PiecewiseConstant1DHost { } } - let view = PiecewiseConstant1D { - func: Ptr(func_vec.as_ptr()), - cdf: Ptr(cdf_vec.as_ptr()), + Self { + func: func_vec, + cdf: cdf_vec, + func_integral, min, max, - n: n as u32, - func_integral, - }; - - Self { - view, - _func: func_vec, - _cdf: cdf_vec, } } } #[derive(Debug, Clone)] -pub struct PiecewiseConstant2DHost { - pub view: PiecewiseConstant2D, - _p_conditional_v: Vec, +pub struct PiecewiseConstant2D { + pub domain: Bounds2f, + pub p_marginal: PiecewiseConstant1D, + pub p_conditionals: Vec, } -impl std::ops::Deref for PiecewiseConstant2DHost { - type Target = PiecewiseConstant2D; - fn deref(&self) -> &Self::Target { - &self.view - } -} - -impl PiecewiseConstant2DHost { +impl PiecewiseConstant2D { pub fn new(data: &Array2D, x_size: u32, y_size: u32, domain: Bounds2f) -> Self { let nu = x_size as usize; let nv = y_size as usize; let mut conditionals = Vec::with_capacity(nv); for v in 0..nv { let row = unsafe { core::slice::from_raw_parts(data.values.add(v * nu), nu) }; - conditionals.push(PiecewiseConstant1D::new_with_bounds( + conditionals.push(DevicePiecewiseConstant1D::new_with_bounds( row, domain.p_min.x(), domain.p_max.x(), @@ -92,24 +88,16 @@ impl PiecewiseConstant2DHost { } let marginal_funcs: Vec = conditionals.iter().map(|c| c.func_integral).collect(); - let p_marginal = PiecewiseConstant1D::new_with_bounds( + let p_marginal = DevicePiecewiseConstant1D::new_with_bounds( &marginal_funcs, domain.p_min.y(), domain.p_max.y(), ); - let p_conditional_v = conditionals.as_mut_ptr(); - std::mem::forget(conditionals); - let view = PiecewiseConstant2D { + Self { domain, p_marginal, - n_conditionals: nv, - p_conditional_v: Ptr(p_conditional_v), - }; - - Self { - view, - _p_conditional_v: p_conditional_v, + p_conditionals: conditionals, } }