Implementing arena based memory allocation

This commit is contained in:
pingu 2026-01-10 00:20:43 +00:00
parent 0ef563d1a5
commit f94c5d78c7
73 changed files with 953 additions and 672 deletions

View file

@ -19,7 +19,7 @@ use crate::spectra::{
N_SPECTRUM_SAMPLES, RGBColorSpace, RGBUnboundedSpectrum, SampledSpectrum, SampledWavelengths, N_SPECTRUM_SAMPLES, RGBColorSpace, RGBUnboundedSpectrum, SampledSpectrum, SampledWavelengths,
StandardColorSpaces, StandardColorSpaces,
}; };
use crate::utils::Ptr; use crate::utils::DevicePtr;
use crate::utils::hash::hash_buffer; use crate::utils::hash::hash_buffer;
use crate::utils::math::{ use crate::utils::math::{
clamp, fast_exp, i0, lerp, log_i0, radians, safe_acos, safe_asin, safe_sqrt, sample_discrete, clamp, fast_exp, i0, lerp, log_i0, radians, safe_acos, safe_asin, safe_sqrt, sample_discrete,

View file

@ -8,7 +8,7 @@ use crate::core::geometry::{
use crate::core::scattering::reflect; use crate::core::scattering::reflect;
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::math::square; 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::utils::sampling::{PiecewiseLinear2D, cosine_hemisphere_pdf, sample_cosine_hemisphere};
use crate::{Float, INV_PI, PI, PI_OVER_2}; use crate::{Float, INV_PI, PI, PI_OVER_2};
use core::any::Any; use core::any::Any;
@ -28,7 +28,7 @@ pub struct MeasuredBxDFData {
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MeasuredBxDF { pub struct MeasuredBxDF {
pub brdf: Ptr<MeasuredBxDFData>, pub brdf: DevicePtr<MeasuredBxDFData>,
pub lambda: SampledWavelengths, pub lambda: SampledWavelengths,
} }
@ -38,7 +38,7 @@ unsafe impl Sync for MeasuredBxDF {}
impl MeasuredBxDF { impl MeasuredBxDF {
pub fn new(brdf: &MeasuredBxDFData, lambda: &SampledWavelengths) -> Self { pub fn new(brdf: &MeasuredBxDFData, lambda: &SampledWavelengths) -> Self {
Self { Self {
brdf: Ptr::from(brdf), brdf: DevicePtr::from(brdf),
lambda: *lambda, lambda: *lambda,
} }
} }

View file

@ -5,7 +5,7 @@ use crate::core::film::Film;
use crate::core::geometry::{ use crate::core::geometry::{
Bounds2f, Normal3f, Point2f, Point2i, Point3f, Ray, Vector2f, Vector2i, Vector3f, VectorLike, 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::medium::Medium;
use crate::core::pbrt::Float; use crate::core::pbrt::Float;
use crate::core::sampler::CameraSample; use crate::core::sampler::CameraSample;
@ -37,7 +37,7 @@ pub struct RealisticCamera {
base: CameraBase, base: CameraBase,
focus_distance: Float, focus_distance: Float,
set_aperture_diameter: Float, set_aperture_diameter: Float,
aperture_image: *const Image, aperture_image: *const DeviceImage,
element_interfaces: *const LensElementInterface, element_interfaces: *const LensElementInterface,
n_elements: usize, n_elements: usize,
physical_extent: Bounds2f, physical_extent: Bounds2f,
@ -51,7 +51,7 @@ impl RealisticCamera {
lens_params: &[Float], lens_params: &[Float],
focus_distance: Float, focus_distance: Float,
set_aperture_diameter: Float, set_aperture_diameter: Float,
aperture_image: Option<Image>, aperture_image: Option<DeviceImage>,
) -> Self { ) -> Self {
let film_ptr = base.film; let film_ptr = base.film;
if film_ptr.is_null() { if film_ptr.is_null() {

View file

@ -2,17 +2,17 @@ use crate::Float;
use crate::core::bxdf::{BSDFSample, BxDF, BxDFFlags, BxDFTrait, FArgs, TransportMode}; use crate::core::bxdf::{BSDFSample, BxDF, BxDFFlags, BxDFTrait, FArgs, TransportMode};
use crate::core::geometry::{Frame, Normal3f, Point2f, Vector3f, VectorLike}; use crate::core::geometry::{Frame, Normal3f, Point2f, Vector3f, VectorLike};
use crate::spectra::SampledSpectrum; use crate::spectra::SampledSpectrum;
use crate::utils::Ptr; use crate::utils::DevicePtr;
#[repr(C)] #[repr(C)]
#[derive(Copy, Debug, Default)] #[derive(Copy, Debug, Default)]
pub struct BSDF { pub struct BSDF {
bxdf: Ptr<BxDF>, bxdf: DevicePtr<BxDF>,
shading_frame: Frame, shading_frame: Frame,
} }
impl BSDF { impl BSDF {
pub fn new(ns: Normal3f, dpdus: Vector3f, bxdf: Ptr<BxDF>) -> Self { pub fn new(ns: Normal3f, dpdus: Vector3f, bxdf: DevicePtr<BxDF>) -> Self {
Self { Self {
bxdf, bxdf,
shading_frame: Frame::new(dpdus.normalize(), Vector3f::from(ns)), shading_frame: Frame::new(dpdus.normalize(), Vector3f::from(ns)),

View file

@ -3,10 +3,10 @@ use crate::core::geometry::{Frame, Normal3f, Point2f, Point3f, Point3fi, Vector3
use crate::core::interaction::{InteractionBase, ShadingGeom, SurfaceInteraction}; use crate::core::interaction::{InteractionBase, ShadingGeom, SurfaceInteraction};
use crate::core::shape::Shape; use crate::core::shape::Shape;
use crate::spectra::{N_SPECTRUM_SAMPLES, SampledSpectrum}; 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::math::{catmull_rom_weights, square};
use crate::utils::sampling::sample_catmull_rom_2d; 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 crate::{Float, PI};
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use std::sync::Arc; use std::sync::Arc;
@ -78,15 +78,15 @@ impl From<&SubsurfaceInteraction> for SurfaceInteraction {
dndv: Normal3f::zero(), dndv: Normal3f::zero(),
}, },
face_index: 0, face_index: 0,
area_light: Ptr::null(), area_light: DevicePtr::null(),
material: Ptr::null(), material: DevicePtr::null(),
dpdx: Vector3f::zero(), dpdx: Vector3f::zero(),
dpdy: Vector3f::zero(), dpdy: Vector3f::zero(),
dudx: 0., dudx: 0.,
dvdx: 0., dvdx: 0.,
dudy: 0., dudy: 0.,
dvdy: 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 struct BSSRDFTable {
pub n_rho_samples: u32, pub n_rho_samples: u32,
pub n_radius_samples: u32, pub n_radius_samples: u32,
pub rho_samples: Ptr<Float>, pub rho_samples: DevicePtr<Float>,
pub radius_samples: Ptr<Float>, pub radius_samples: DevicePtr<Float>,
pub profile: Ptr<Float>, pub profile: DevicePtr<Float>,
pub rho_eff: Ptr<Float>, pub rho_eff: DevicePtr<Float>,
pub profile_cdf: Ptr<Float>, pub profile_cdf: DevicePtr<Float>,
} }
impl BSSRDFTable { impl BSSRDFTable {
@ -165,7 +165,7 @@ pub struct TabulatedBSSRDF {
eta: Float, eta: Float,
sigma_t: SampledSpectrum, sigma_t: SampledSpectrum,
rho: SampledSpectrum, rho: SampledSpectrum,
table: Ptr<BSSRDFTable>, table: DevicePtr<BSSRDFTable>,
} }
impl TabulatedBSSRDF { impl TabulatedBSSRDF {
@ -187,7 +187,7 @@ impl TabulatedBSSRDF {
eta, eta,
sigma_t, sigma_t,
rho, rho,
table: Ptr::from(table), table: DevicePtr::from(table),
} }
} }

View file

@ -10,7 +10,7 @@ use crate::core::pbrt::Float;
use crate::core::sampler::CameraSample; use crate::core::sampler::CameraSample;
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::math::lerp; use crate::utils::math::lerp;
use crate::utils::ptr::Ptr; use crate::utils::ptr::DevicePtr;
use crate::utils::transform::{AnimatedTransform, Transform}; use crate::utils::transform::{AnimatedTransform, Transform};
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
@ -113,8 +113,8 @@ pub struct CameraBase {
pub min_pos_differential_y: Vector3f, pub min_pos_differential_y: Vector3f,
pub min_dir_differential_x: Vector3f, pub min_dir_differential_x: Vector3f,
pub min_dir_differential_y: Vector3f, pub min_dir_differential_y: Vector3f,
pub film: Ptr<Film>, pub film: DevicePtr<Film>,
pub medium: Ptr<Medium>, pub medium: DevicePtr<Medium>,
} }
#[enum_dispatch(CameraTrait)] #[enum_dispatch(CameraTrait)]
@ -232,13 +232,13 @@ pub trait CameraTrait {
Point3f::new(0., 0., 0.) + self.base().min_pos_differential_x, Point3f::new(0., 0., 0.) + self.base().min_pos_differential_x,
Vector3f::new(0., 0., 1.) + self.base().min_dir_differential_x, Vector3f::new(0., 0., 1.) + self.base().min_dir_differential_x,
None, None,
&Ptr::default(), &DevicePtr::default(),
); );
let y_ray = Ray::new( let y_ray = Ray::new(
Point3f::new(0., 0., 0.) + self.base().min_pos_differential_y, Point3f::new(0., 0., 0.) + self.base().min_pos_differential_y,
Vector3f::new(0., 0., 1.) + self.base().min_dir_differential_y, Vector3f::new(0., 0., 1.) + self.base().min_dir_differential_y,
None, None,
&Ptr::default(), &DevicePtr::default(),
); );
let n_down = Vector3f::from(n_down_z); let n_down = Vector3f::from(n_down_z);
let tx = -(n_down.dot(y_ray.o.into())) / n_down.dot(x_ray.d); let tx = -(n_down.dot(y_ray.o.into())) / n_down.dot(x_ray.d);

View file

@ -5,7 +5,7 @@ use crate::core::geometry::{
Bounds2f, Bounds2fi, Bounds2i, Normal3f, Point2f, Point2i, Point3f, Tuple, Vector2f, Vector2fi, Bounds2f, Bounds2fi, Bounds2i, Normal3f, Point2f, Point2i, Point3f, Tuple, Vector2f, Vector2fi,
Vector2i, Vector3f, Vector2i, Vector3f,
}; };
use crate::core::image::{Image, PixelFormat}; use crate::core::image::{DeviceImage, PixelFormat};
use crate::core::interaction::SurfaceInteraction; use crate::core::interaction::SurfaceInteraction;
use crate::core::pbrt::Float; use crate::core::pbrt::Float;
use crate::core::spectrum::{Spectrum, SpectrumTrait, StandardSpectra}; use crate::core::spectrum::{Spectrum, SpectrumTrait, StandardSpectra};
@ -17,7 +17,7 @@ use crate::utils::AtomicFloat;
use crate::utils::containers::Array2D; use crate::utils::containers::Array2D;
use crate::utils::math::linear_least_squares; use crate::utils::math::linear_least_squares;
use crate::utils::math::{SquareMatrix, wrap_equal_area_square}; 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::sampling::VarianceEstimator;
use crate::utils::transform::AnimatedTransform; use crate::utils::transform::AnimatedTransform;
@ -472,7 +472,7 @@ impl PixelSensor {
pub fn new_with_white_balance( pub fn new_with_white_balance(
output_colorspace: &RGBColorSpace, output_colorspace: &RGBColorSpace,
sensor_illum: Ptr<Spectrum>, sensor_illum: DevicePtr<Spectrum>,
imaging_ratio: Float, imaging_ratio: Float,
spectra: *const StandardSpectra, spectra: *const StandardSpectra,
) -> Self { ) -> Self {

View file

@ -3,7 +3,7 @@ use crate::core::pbrt::Float;
use crate::filters::*; use crate::filters::*;
use crate::utils::containers::Array2D; use crate::utils::containers::Array2D;
use crate::utils::math::{gaussian, gaussian_integral, lerp, sample_tent, windowed_sinc}; 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; use enum_dispatch::enum_dispatch;
pub struct FilterSample { pub struct FilterSample {
@ -15,7 +15,7 @@ pub struct FilterSample {
#[derive(Clone, Debug, Copy)] #[derive(Clone, Debug, Copy)]
pub struct FilterSampler { pub struct FilterSampler {
pub domain: Bounds2f, pub domain: Bounds2f,
pub distrib: PiecewiseConstant2D, pub distrib: DevicePiecewiseConstant2D,
pub f: Array2D<Float>, pub f: Array2D<Float>,
} }
@ -43,7 +43,7 @@ impl FilterSampler {
f[(x as i32, y as i32)] = func(p); 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 } Self { domain, f, distrib }
} }

View file

@ -2,7 +2,7 @@ use super::{Normal3f, Point3f, Point3fi, Vector3f, VectorLike};
use crate::core::medium::Medium; use crate::core::medium::Medium;
use crate::core::pbrt::Float; use crate::core::pbrt::Float;
use crate::utils::math::{next_float_down, next_float_up}; use crate::utils::math::{next_float_down, next_float_up};
use crate::utils::ptr::Ptr; use crate::utils::ptr::DevicePtr;
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
@ -10,7 +10,7 @@ pub struct Ray {
pub o: Point3f, pub o: Point3f,
pub d: Vector3f, pub d: Vector3f,
pub time: Float, pub time: Float,
pub medium: Ptr<Medium>, pub medium: DevicePtr<Medium>,
// We do this instead of creating a trait for Rayable or some gnarly thing like that // We do this instead of creating a trait for Rayable or some gnarly thing like that
pub has_differentials: bool, pub has_differentials: bool,
pub differential: RayDifferential, pub differential: RayDifferential,
@ -21,7 +21,7 @@ impl Default for Ray {
Self { Self {
o: Point3f::new(0.0, 0.0, 0.0), o: Point3f::new(0.0, 0.0, 0.0),
d: Vector3f::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, time: 0.0,
has_differentials: false, has_differentials: false,
differential: RayDifferential::default(), differential: RayDifferential::default(),
@ -35,7 +35,7 @@ impl Ray {
o, o,
d, d,
time: time.unwrap_or_else(|| Self::default().time), time: time.unwrap_or_else(|| Self::default().time),
medium: Ptr::from(medium), medium: DevicePtr::from(medium),
..Self::default() ..Self::default()
} }
} }
@ -71,7 +71,7 @@ impl Ray {
o: origin, o: origin,
d, d,
time, time,
medium: Ptr::null(), medium: DevicePtr::null(),
has_differentials: false, has_differentials: false,
differential: RayDifferential::default(), differential: RayDifferential::default(),
} }
@ -99,7 +99,7 @@ impl Ray {
o: pf, o: pf,
d, d,
time, time,
medium: Ptr::null(), medium: DevicePtr::null(),
has_differentials: false, has_differentials: false,
differential: RayDifferential::default(), differential: RayDifferential::default(),
} }

View file

@ -66,87 +66,75 @@ pub enum Pixels {
} }
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy)] #[derive(Clone, Copy, Debug)]
pub struct Image { pub struct ImageBase {
pub format: PixelFormat, pub format: PixelFormat,
pub pixels: Pixels,
pub encoding: ColorEncoding, pub encoding: ColorEncoding,
pub resolution: Point2i, pub resolution: Point2i,
pub n_channels: i32, pub n_channels: i32,
} }
impl Image { impl ImageBase {
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())
}
pub fn remap_pixel_coords(&self, p: &mut Point2i, wrap_mode: WrapMode2D) -> bool { pub fn remap_pixel_coords(&self, p: &mut Point2i, wrap_mode: WrapMode2D) -> bool {
let resolution = self.resolution;
for i in 0..2 { for i in 0..2 {
if p[i] >= 0 && p[i] < self.resolution[i] { if p[i] >= 0 && p[i] < resolution[i] {
continue; continue;
} }
match wrap_mode.uv[i] { match wrap_mode.uv[i] {
WrapMode::Black => return false, WrapMode::Black => return false,
WrapMode::Clamp => p[i] = p[i].clamp(0, self.resolution[i] - 1), WrapMode::Clamp => p[i] = p[i].clamp(0, resolution[i] - 1),
WrapMode::Repeat => p[i] = p[i].rem_euclid(self.resolution[i]), WrapMode::Repeat => p[i] = p[i].rem_euclid(resolution[i]),
WrapMode::OctahedralSphere => { WrapMode::OctahedralSphere => {
p[i] = p[i].clamp(0, self.resolution[i] - 1); p[i] = p[i].clamp(0, resolution[i] - 1);
} }
} }
} }
true 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 { pub fn bilerp_channel(&self, p: Point2f, c: i32) -> Float {
self.bilerp_channel_with_wrap(p, c, WrapMode::Clamp.into()) 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 { 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 x = p.x() * self.resolution().x() as Float - 0.5;
let y = p.y() * self.resolution.y() as Float - 0.5; let y = p.y() * self.resolution().y() as Float - 0.5;
let xi = x.floor() as i32; let xi = x.floor() as i32;
let yi = y.floor() as i32; let yi = y.floor() as i32;
let dx = x - xi as Float; 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); 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)) lerp(dy, lerp(dx, v00, v10), lerp(dx, v01, v11))
} }
}
pub fn lookup_nearest_channel_with_wrap( pub trait ImageAccess {
&self, fn get_channel_with_wrap(&self, p: Point2i, c: i32, wrap_mode: WrapMode2D) -> Float;
p: Point2f, fn get_channel(&self, p: Point2i, c: i32) -> Float;
c: i32, fn lookup_nearest_channel_with_wrap(&self, p: Point2f, c: i32, wrap_mode: WrapMode2D) -> Float;
wrap_mode: WrapMode2D, fn lookup_nearest_channel(&self, p: Point2f, c: i32) -> Float;
) -> 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( let pi = Point2i::new(
p.x() as i32 * self.resolution.x(), p.x() as i32 * self.resolution().x(),
p.y() as i32 * self.resolution.y(), p.y() as i32 * self.resolution().y(),
); );
self.get_channel_with_wrap(pi, c, wrap_mode) 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()) self.lookup_nearest_channel_with_wrap(p, c, WrapMode::Clamp.into())
} }
} }

View file

@ -5,7 +5,7 @@ use crate::core::camera::{Camera, CameraTrait};
use crate::core::geometry::{ use crate::core::geometry::{
Normal3f, Point2f, Point3f, Point3fi, Ray, RayDifferential, Vector3f, VectorLike, 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::light::{Light, LightTrait};
use crate::core::material::{ use crate::core::material::{
Material, MaterialEvalContext, MaterialTrait, NormalBumpEvalContext, bump_map, normal_map, 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::shape::Shape;
use crate::core::texture::{GPUFloatTexture, UniversalTextureEvaluator}; use crate::core::texture::{GPUFloatTexture, UniversalTextureEvaluator};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::DevicePtr;
use crate::utils::math::{clamp, difference_of_products, square}; use crate::utils::math::{clamp, difference_of_products, square};
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
use std::any::Any; use std::any::Any;
@ -31,7 +31,7 @@ pub struct InteractionBase {
pub wo: Vector3f, pub wo: Vector3f,
pub uv: Point2f, pub uv: Point2f,
pub medium_interface: MediumInterface, pub medium_interface: MediumInterface,
pub medium: Ptr<Medium>, pub medium: DevicePtr<Medium>,
} }
impl InteractionBase { impl InteractionBase {
@ -49,11 +49,11 @@ impl InteractionBase {
wo: wo.normalize(), wo: wo.normalize(),
time, time,
medium_interface: MediumInterface::default(), medium_interface: MediumInterface::default(),
medium: Ptr::null(), medium: DevicePtr::null(),
} }
} }
pub fn new_medium(p: Point3f, wo: Vector3f, time: Float, medium: Ptr<Medium>) -> Self { pub fn new_medium(p: Point3f, wo: Vector3f, time: Float, medium: DevicePtr<Medium>) -> Self {
Self { Self {
pi: Point3fi::new_from_point(p), pi: Point3fi::new_from_point(p),
n: Normal3f::zero(), n: Normal3f::zero(),
@ -114,7 +114,7 @@ pub trait InteractionTrait {
false false
} }
fn get_medium(&self, w: Vector3f) -> Ptr<Medium> { fn get_medium(&self, w: Vector3f) -> DevicePtr<Medium> {
let data = self.get_common(); let data = self.get_common();
if !data.medium_interface.inside.is_null() || !data.medium_interface.outside.is_null() { if !data.medium_interface.inside.is_null() || !data.medium_interface.outside.is_null() {
if w.dot(data.n.into()) > 0.0 { if w.dot(data.n.into()) > 0.0 {
@ -225,9 +225,9 @@ pub struct SurfaceInteraction {
pub dndv: Normal3f, pub dndv: Normal3f,
pub shading: ShadingGeom, pub shading: ShadingGeom,
pub face_index: u32, pub face_index: u32,
pub area_light: Ptr<Light>, pub area_light: DevicePtr<Light>,
pub material: Ptr<Material>, pub material: DevicePtr<Material>,
pub shape: Ptr<Shape>, pub shape: DevicePtr<Shape>,
pub dpdx: Vector3f, pub dpdx: Vector3f,
pub dpdy: Vector3f, pub dpdy: Vector3f,
pub dudx: Float, pub dudx: Float,
@ -412,8 +412,8 @@ impl SurfaceInteraction {
fn compute_bump_geom( fn compute_bump_geom(
&mut self, &mut self,
tex_eval: &UniversalTextureEvaluator, tex_eval: &UniversalTextureEvaluator,
displacement: Ptr<GPUFloatTexture>, displacement: DevicePtr<GPUFloatTexture>,
normal_image: Ptr<Image>, normal_image: DevicePtr<DeviceImage>,
) { ) {
let ctx = NormalBumpEvalContext::from(&*self); let ctx = NormalBumpEvalContext::from(&*self);
let (dpdu, dpdv) = if !displacement.is_null() { let (dpdu, dpdv) = if !displacement.is_null() {
@ -536,7 +536,7 @@ impl InteractionTrait for SurfaceInteraction {
&mut self.common &mut self.common
} }
fn get_medium(&self, w: Vector3f) -> Ptr<Medium> { fn get_medium(&self, w: Vector3f) -> DevicePtr<Medium> {
let interface = self.common.medium_interface; let interface = self.common.medium_interface;
if self.n().dot(w.into()) > 0.0 { if self.n().dot(w.into()) > 0.0 {
interface.outside interface.outside
@ -583,16 +583,16 @@ impl SurfaceInteraction {
dndu, dndu,
dndv, dndv,
}, },
material: Ptr::null(), material: DevicePtr::null(),
face_index: 0, face_index: 0,
area_light: Ptr::null(), area_light: DevicePtr::null(),
dpdx: Vector3f::zero(), dpdx: Vector3f::zero(),
dpdy: Vector3f::zero(), dpdy: Vector3f::zero(),
dudx: 0.0, dudx: 0.0,
dudy: 0.0, dudy: 0.0,
dvdx: 0.0, dvdx: 0.0,
dvdy: 0.0, dvdy: 0.0,
shape: Ptr::null(), shape: DevicePtr::null(),
} }
} }
@ -658,13 +658,13 @@ impl SurfaceInteraction {
ray_medium: &Medium, ray_medium: &Medium,
prim_medium_interface: MediumInterface, prim_medium_interface: MediumInterface,
) { ) {
self.material = Ptr::from(mtl); self.material = DevicePtr::from(mtl);
self.area_light = Ptr::from(area); self.area_light = DevicePtr::from(area);
if prim_medium_interface.is_medium_transition() { if prim_medium_interface.is_medium_transition() {
self.common.medium_interface = prim_medium_interface; self.common.medium_interface = prim_medium_interface;
} else { } else {
self.common.medium = Ptr::from(ray_medium); self.common.medium = DevicePtr::from(ray_medium);
} }
} }
} }
@ -681,7 +681,7 @@ impl MediumInteraction {
p: Point3f, p: Point3f,
wo: Vector3f, wo: Vector3f,
time: Float, time: Float,
medium: Ptr<Medium>, medium: DevicePtr<Medium>,
phase: PhaseFunction, phase: PhaseFunction,
) -> Self { ) -> Self {
Self { Self {

View file

@ -3,7 +3,7 @@ use crate::core::geometry::{
Bounds2f, Bounds3f, DirectionCone, Normal3f, Point2f, Point2i, Point3f, Point3fi, Ray, Bounds2f, Bounds3f, DirectionCone, Normal3f, Point2f, Point2i, Point3f, Point3fi, Ray,
Vector3f, VectorLike, cos_theta, Vector3f, VectorLike, cos_theta,
}; };
use crate::core::image::Image; use crate::core::image::DeviceImage;
use crate::core::interaction::{ use crate::core::interaction::{
Interaction, InteractionBase, InteractionTrait, MediumInteraction, SimpleInteraction, Interaction, InteractionBase, InteractionTrait, MediumInteraction, SimpleInteraction,
SurfaceInteraction, SurfaceInteraction,
@ -17,8 +17,8 @@ use crate::spectra::{
}; };
use crate::utils::Transform; use crate::utils::Transform;
use crate::utils::math::{equal_area_sphere_to_square, radians, safe_sqrt, smooth_step, square}; use crate::utils::math::{equal_area_sphere_to_square, radians, safe_sqrt, smooth_step, square};
use crate::utils::ptr::Ptr; use crate::utils::ptr::{DevicePtr, Ptr};
use crate::utils::sampling::PiecewiseConstant2D; use crate::utils::sampling::DevicePiecewiseConstant2D;
use crate::{Float, PI}; use crate::{Float, PI};
use bitflags::bitflags; use bitflags::bitflags;

View file

@ -10,7 +10,7 @@ use crate::core::bsdf::BSDF;
use crate::core::bssrdf::BSSRDF; use crate::core::bssrdf::BSSRDF;
use crate::core::bxdf::BxDF; use crate::core::bxdf::BxDF;
use crate::core::geometry::{Frame, Normal3f, Point2f, Point3f, Vector2f, Vector3f, VectorLike}; 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::interaction::{Interaction, InteractionTrait, ShadingGeom, SurfaceInteraction};
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
@ -19,7 +19,7 @@ use crate::core::texture::{
}; };
use crate::materials::*; use crate::materials::*;
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::DevicePtr;
use crate::utils::hash::hash_float; use crate::utils::hash::hash_float;
use crate::utils::math::clamp; 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 wrap = WrapMode2D::from(WrapMode::Repeat);
let uv = Point2f::new(ctx.uv[0], 1. - ctx.uv[1]); let uv = Point2f::new(ctx.uv[0], 1. - ctx.uv[1]);
let r = normal_map.bilerp_channel_with_wrap(uv, 0, wrap); let r = normal_map.bilerp_channel_with_wrap(uv, 0, wrap);
@ -125,7 +125,7 @@ pub fn bump_map<T: TextureEvaluator>(
displacement: &GPUFloatTexture, displacement: &GPUFloatTexture,
ctx: &NormalBumpEvalContext, ctx: &NormalBumpEvalContext,
) -> (Vector3f, Vector3f) { ) -> (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()); let mut du = 0.5 * (ctx.dudx.abs() + ctx.dudy.abs());
if du == 0.0 { if du == 0.0 {
du = 0.0005; du = 0.0005;
@ -173,8 +173,8 @@ pub trait MaterialTrait {
) -> Option<BSSRDF>; ) -> Option<BSSRDF>;
fn can_evaluate_textures(&self, tex_eval: &dyn TextureEvaluator) -> bool; fn can_evaluate_textures(&self, tex_eval: &dyn TextureEvaluator) -> bool;
fn get_normal_map(&self) -> Option<&Image>; fn get_normal_map(&self) -> Option<&DeviceImage>;
fn get_displacement(&self) -> Ptr<GPUFloatTexture>; fn get_displacement(&self) -> DevicePtr<GPUFloatTexture>;
fn has_subsurface_scattering(&self) -> bool; fn has_subsurface_scattering(&self) -> bool;
} }

View file

@ -12,7 +12,7 @@ use crate::spectra::{
}; };
use crate::utils::containers::SampledGrid; use crate::utils::containers::SampledGrid;
use crate::utils::math::{clamp, square}; use crate::utils::math::{clamp, square};
use crate::utils::ptr::Ptr; use crate::utils::ptr::DevicePtr;
use crate::utils::rng::Rng; use crate::utils::rng::Rng;
use crate::utils::transform::Transform; use crate::utils::transform::Transform;
@ -829,8 +829,8 @@ impl MediumTrait for NanoVDBMedium {
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct MediumInterface { pub struct MediumInterface {
pub inside: Ptr<Medium>, pub inside: DevicePtr<Medium>,
pub outside: Ptr<Medium>, pub outside: DevicePtr<Medium>,
} }
unsafe impl Send for MediumInterface {} unsafe impl Send for MediumInterface {}
@ -839,17 +839,32 @@ unsafe impl Sync for MediumInterface {}
impl Default for MediumInterface { impl Default for MediumInterface {
fn default() -> Self { fn default() -> Self {
Self { Self {
inside: Ptr::null(), inside: DevicePtr::null(),
outside: Ptr::null(), outside: DevicePtr::null(),
} }
} }
} }
impl From<Medium> 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 { impl MediumInterface {
pub fn new(inside: &Medium, outside: &Medium) -> Self { pub fn new(inside: &Medium, outside: &Medium) -> Self {
Self { Self {
inside: Ptr::from(inside), inside: DevicePtr::from(inside),
outside: Ptr::from(outside), outside: DevicePtr::from(outside),
} }
} }

View file

@ -7,7 +7,7 @@ use crate::core::medium::{Medium, MediumInterface};
use crate::core::pbrt::Float; use crate::core::pbrt::Float;
use crate::core::shape::{Shape, ShapeIntersection, ShapeTrait}; use crate::core::shape::{Shape, ShapeIntersection, ShapeTrait};
use crate::core::texture::{GPUFloatTexture, TextureEvalContext}; use crate::core::texture::{GPUFloatTexture, TextureEvalContext};
use crate::utils::ArenaPtr; use crate::utils::Ptr;
use crate::utils::hash::hash_float; use crate::utils::hash::hash_float;
use crate::utils::transform::{AnimatedTransform, Transform}; use crate::utils::transform::{AnimatedTransform, Transform};
@ -88,13 +88,13 @@ impl PrimitiveTrait for GeometricPrimitive {
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct SimplePrimitive { pub struct SimplePrimitive {
shape: ArenaPtr<Shape>, shape: Ptr<Shape>,
material: ArenaPtr<Material>, material: Ptr<Material>,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct TransformedPrimitive { pub struct TransformedPrimitive {
pub primitive: ArenaPtr<Primitive>, pub primitive: Ptr<Primitive>,
pub render_from_primitive: Transform, pub render_from_primitive: Transform,
} }
@ -129,7 +129,7 @@ impl PrimitiveTrait for TransformedPrimitive {
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct AnimatedPrimitive { pub struct AnimatedPrimitive {
primitive: ArenaPtr<Primitive>, primitive: Ptr<Primitive>,
render_from_primitive: AnimatedTransform, render_from_primitive: AnimatedTransform,
} }
@ -164,7 +164,7 @@ impl PrimitiveTrait for AnimatedPrimitive {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct BVHAggregatePrimitive { pub struct BVHAggregatePrimitive {
max_prims_in_node: u32, max_prims_in_node: u32,
primitives: *const ArenaPtr<Primitive>, primitives: *const Ptr<Primitive>,
nodes: *const LinearBVHNode, nodes: *const LinearBVHNode,
} }

View file

@ -2,7 +2,7 @@ use crate::core::filter::FilterTrait;
use crate::core::geometry::{Bounds2f, Point2f, Point2i, Vector2f}; use crate::core::geometry::{Bounds2f, Point2f, Point2i, Vector2f};
use crate::core::options::{PBRTOptions, get_options}; 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::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::containers::Array2D;
use crate::utils::math::{ use crate::utils::math::{
BinaryPermuteScrambler, DigitPermutation, FastOwenScrambler, NoRandomizer, OwenScrambler, BinaryPermuteScrambler, DigitPermutation, FastOwenScrambler, NoRandomizer, OwenScrambler,
@ -103,7 +103,7 @@ pub struct HaltonSampler {
mult_inverse: [u64; 2], mult_inverse: [u64; 2],
halton_index: u64, halton_index: u64,
dim: u32, dim: u32,
digit_permutations: Ptr<DigitPermutation>, digit_permutations: DevicePtr<DigitPermutation>,
} }
impl HaltonSampler { impl HaltonSampler {

View file

@ -10,7 +10,7 @@ use crate::core::material::Material;
use crate::core::medium::{Medium, MediumInterface}; use crate::core::medium::{Medium, MediumInterface};
use crate::shapes::*; use crate::shapes::*;
use crate::utils::math::{next_float_down, next_float_up}; 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 crate::{Float, PI};
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
@ -118,7 +118,12 @@ impl ShapeSampleContext {
} }
pub fn spawn_ray(&self, w: Vector3f) -> Ray { 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(),
)
} }
} }

View file

@ -9,7 +9,7 @@ use crate::spectra::{
SampledWavelengths, SampledWavelengths,
}; };
use crate::textures::*; use crate::textures::*;
use crate::utils::Ptr; use crate::utils::DevicePtr;
use crate::utils::Transform; use crate::utils::Transform;
use crate::utils::math::square; use crate::utils::math::square;
use crate::{Float, INV_2_PI, INV_PI, PI}; use crate::{Float, INV_2_PI, INV_PI, PI};
@ -428,8 +428,8 @@ pub trait TextureEvaluator: Send + Sync {
fn can_evaluate( fn can_evaluate(
&self, &self,
_ftex: &[Ptr<GPUFloatTexture>], _ftex: &[DevicePtr<GPUFloatTexture>],
_stex: &[Ptr<GPUSpectrumTexture>], _stex: &[DevicePtr<GPUSpectrumTexture>],
) -> bool; ) -> bool;
} }
@ -453,8 +453,8 @@ impl TextureEvaluator for UniversalTextureEvaluator {
fn can_evaluate( fn can_evaluate(
&self, &self,
_float_textures: &[Ptr<GPUFloatTexture>], _float_textures: &[DevicePtr<GPUFloatTexture>],
_spectrum_textures: &[Ptr<GPUSpectrumTexture>], _spectrum_textures: &[DevicePtr<GPUSpectrumTexture>],
) -> bool { ) -> bool {
true true
} }

View file

@ -1,7 +1,7 @@
use crate::PI; use crate::PI;
use crate::core::color::{RGB, XYZ}; use crate::core::color::{RGB, XYZ};
use crate::core::geometry::*; use crate::core::geometry::*;
use crate::core::image::Image; use crate::core::image::{DeviceImage, ImageAccess};
use crate::core::interaction::{ use crate::core::interaction::{
Interaction, InteractionTrait, MediumInteraction, SurfaceInteraction, Interaction, InteractionTrait, MediumInteraction, SurfaceInteraction,
}; };
@ -17,17 +17,17 @@ use crate::core::texture::{
}; };
use crate::spectra::*; use crate::spectra::*;
use crate::utils::hash::hash_float; use crate::utils::hash::hash_float;
use crate::utils::{Ptr, Transform}; use crate::utils::{DevicePtr, Transform};
#[repr(C)] #[repr(C)]
#[derive(Clone, Debug, Copy)] #[derive(Clone, Debug, Copy)]
pub struct DiffuseAreaLight { pub struct DiffuseAreaLight {
pub base: LightBase, pub base: LightBase,
pub shape: Ptr<Shape>, pub shape: DevicePtr<Shape>,
pub alpha: Ptr<GPUFloatTexture>, pub alpha: DevicePtr<GPUFloatTexture>,
pub image_color_space: Ptr<RGBColorSpace>, pub image_color_space: DevicePtr<RGBColorSpace>,
pub lemit: Ptr<DenselySampledSpectrum>, pub lemit: DevicePtr<DenselySampledSpectrum>,
pub image: Ptr<Image>, pub image: DevicePtr<DeviceImage>,
pub area: Float, pub area: Float,
pub two_sided: bool, pub two_sided: bool,
pub scale: Float, pub scale: Float,
@ -175,8 +175,8 @@ impl LightTrait for DiffuseAreaLight {
fn bounds(&self) -> Option<LightBounds> { fn bounds(&self) -> Option<LightBounds> {
let mut phi = 0.; let mut phi = 0.;
if !self.image.is_null() { if !self.image.is_null() {
for y in 0..self.image.resolution.y() { for y in 0..self.image.base.resolution.y() {
for x in 0..self.image.resolution.x() { for x in 0..self.image.base.resolution.x() {
for c in 0..3 { for c in 0..3 {
phi += self.image.get_channel(Point2i::new(x, y), c); phi += self.image.get_channel(Point2i::new(x, y), c);
} }

View file

@ -5,14 +5,14 @@ use crate::core::interaction::{Interaction, InteractionBase, SimpleInteraction};
use crate::core::light::{LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait}; use crate::core::light::{LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait};
use crate::core::spectrum::SpectrumTrait; use crate::core::spectrum::SpectrumTrait;
use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths}; use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths};
use crate::utils::{ArenaPtr, Ptr}; use crate::utils::{DevicePtr, Ptr};
use crate::{Float, PI}; use crate::{Float, PI};
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct DistantLight { pub struct DistantLight {
pub base: LightBase, pub base: LightBase,
pub lemit: Ptr<DenselySampledSpectrum>, pub lemit: DevicePtr<DenselySampledSpectrum>,
pub scale: Float, pub scale: Float,
pub scene_center: Point3f, pub scene_center: Point3f,
pub scene_radius: Float, pub scene_radius: Float,

View file

@ -1,5 +1,5 @@
use crate::core::geometry::{Bounds3f, Normal3f, Point2f, Point2i, Point3f, Ray, Vector3f}; 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::{ use crate::core::light::{
LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait, LightType, LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait, LightType,
}; };
@ -7,17 +7,17 @@ use crate::core::medium::MediumInterface;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths}; use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths};
use crate::utils::math::equal_area_sphere_to_square; use crate::utils::math::equal_area_sphere_to_square;
use crate::utils::sampling::PiecewiseConstant2D; use crate::utils::sampling::DevicePiecewiseConstant2D;
use crate::utils::{Ptr, Transform}; use crate::utils::{DevicePtr, Transform};
use crate::{Float, PI}; use crate::{Float, PI};
#[derive(Debug, Clone)] #[derive(Debug, Clone, Copy)]
pub struct GoniometricLight { pub struct GoniometricLight {
pub base: LightBase, pub base: LightBase,
iemit: DenselySampledSpectrum, pub iemit: DenselySampledSpectrum,
scale: Float, pub scale: Float,
image: Ptr<Image>, pub image: DevicePtr<DeviceImage>,
distrib: Ptr<PiecewiseConstant2D>, pub distrib: DevicePtr<DevicePiecewiseConstant2D>,
} }
impl GoniometricLight { impl GoniometricLight {
@ -77,13 +77,14 @@ impl LightTrait for GoniometricLight {
#[cfg(not(target_os = "cuda"))] #[cfg(not(target_os = "cuda"))]
fn phi(&self, lambda: SampledWavelengths) -> SampledSpectrum { fn phi(&self, lambda: SampledWavelengths) -> SampledSpectrum {
let resolution = self.image.resolution();
let mut sum_y = 0.; let mut sum_y = 0.;
for y in 0..self.image.resolution.y() { for y in 0..resolution.y() {
for x in 0..self.image.resolution.x() { for x in 0..resolution.x() {
sum_y += self.image.get_channel(Point2i::new(x, y), 0); sum_y += self.image.get_channel(Point2i::new(x, y), 0);
} }
} }
self.scale * self.iemit.sample(&lambda) * 4. * PI * sum_y 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
} }
} }

View file

@ -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::color::RGB;
use crate::core::geometry::{ use crate::core::geometry::{
Bounds2f, Bounds3f, Normal3f, Point2f, Point2i, Point3f, Ray, Vector2f, Vector3f, 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::interaction::{Interaction, SimpleInteraction};
use crate::core::light::{ use crate::core::light::{
LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait, LightType, LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait, LightType,
@ -25,8 +12,14 @@ use crate::core::light::{
use crate::core::medium::{Medium, MediumInterface}; use crate::core::medium::{Medium, MediumInterface};
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths}; use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths};
use crate::spectra::{RGBColorSpace, RGBIlluminantSpectrum};
use crate::utils::Transform; 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 crate::{Float, PI};
use std::sync::Arc; use std::sync::Arc;
@ -34,7 +27,7 @@ use std::sync::Arc;
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct InfiniteUniformLight { pub struct InfiniteUniformLight {
pub base: LightBase, pub base: LightBase,
pub lemit: Ptr<DenselySampledSpectrum>, pub lemit: DevicePtr<DenselySampledSpectrum>,
pub scale: Float, pub scale: Float,
pub scene_center: Point3f, pub scene_center: Point3f,
pub scene_radius: Float, pub scene_radius: Float,
@ -122,10 +115,10 @@ impl LightTrait for InfiniteUniformLight {
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct InfiniteImageLight { pub struct InfiniteImageLight {
pub base: LightBase, pub base: LightBase,
pub image: Ptr<Image>, pub image: DevicePtr<DeviceImage>,
pub image_color_space: Ptr<RGBColorSpace>, pub image_color_space: DevicePtr<RGBColorSpace>,
pub distrib: Ptr<PiecewiseConstant2D>, pub distrib: DevicePtr<DevicePiecewiseConstant2D>,
pub compensated_distrib: Ptr<PiecewiseConstant2D>, pub compensated_distrib: DevicePtr<DevicePiecewiseConstant2D>,
pub scale: Float, pub scale: Float,
pub scene_radius: Float, pub scene_radius: Float,
pub scene_center: Point3f, pub scene_center: Point3f,
@ -258,8 +251,8 @@ impl LightTrait for InfiniteImageLight {
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct InfinitePortalLight { pub struct InfinitePortalLight {
pub base: LightBase, pub base: LightBase,
pub image: Ptr<Image>, pub image: DevicePtr<DeviceImage>,
pub image_color_space: Ptr<RGBColorSpace>, pub image_color_space: DevicePtr<RGBColorSpace>,
pub scale: Float, pub scale: Float,
pub portal: [Point3f; 4], pub portal: [Point3f; 4],
pub portal_frame: Frame, pub portal_frame: Frame,

View file

@ -7,7 +7,7 @@ use crate::core::light::{
}; };
use crate::core::spectrum::SpectrumTrait; use crate::core::spectrum::SpectrumTrait;
use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths}; use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths};
use crate::utils::ptr::Ptr; use crate::utils::ptr::DevicePtr;
use crate::{Float, PI}; use crate::{Float, PI};
#[repr(C)] #[repr(C)]
@ -15,7 +15,7 @@ use crate::{Float, PI};
pub struct PointLight { pub struct PointLight {
pub base: LightBase, pub base: LightBase,
pub scale: Float, pub scale: Float,
pub i: Ptr<DenselySampledSpectrum>, pub i: DevicePtr<DenselySampledSpectrum>,
} }
impl LightTrait for PointLight { impl LightTrait for PointLight {

View file

@ -3,7 +3,7 @@ use crate::core::color::RGB;
use crate::core::geometry::{ use crate::core::geometry::{
Bounds2f, Bounds3f, Normal3f, Point2f, Point2i, Point3f, Ray, Vector3f, VectorLike, cos_theta, 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::{ use crate::core::light::{
LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait, LightType, LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait, LightType,
}; };
@ -11,10 +11,10 @@ use crate::core::medium::MediumInterface;
use crate::core::spectrum::SpectrumTrait; use crate::core::spectrum::SpectrumTrait;
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::math::{radians, square}; use crate::utils::math::{radians, square};
use crate::utils::ptr::Ptr; use crate::utils::ptr::DevicePtr;
use crate::{ use crate::{
spectra::{RGBColorSpace, RGBIlluminantSpectrum}, spectra::{RGBColorSpace, RGBIlluminantSpectrum},
utils::{Transform, sampling::PiecewiseConstant2D}, utils::{Transform, sampling::DevicePiecewiseConstant2D},
}; };
#[repr(C)] #[repr(C)]
@ -27,9 +27,9 @@ pub struct ProjectionLight {
pub screen_from_light: Transform, pub screen_from_light: Transform,
pub light_from_screen: Transform, pub light_from_screen: Transform,
pub a: Float, pub a: Float,
pub image: Ptr<Image>, pub image: DevicePtr<DeviceImage>,
pub distrib: Ptr<PiecewiseConstant2D>, pub distrib: DevicePtr<DevicePiecewiseConstant2D>,
pub image_color_space: Ptr<RGBColorSpace>, pub image_color_space: DevicePtr<RGBColorSpace>,
} }
impl ProjectionLight { impl ProjectionLight {

View file

@ -6,7 +6,7 @@ use crate::core::light::{LightBounds, LightSampleContext};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::math::{clamp, lerp, sample_discrete}; use crate::utils::math::{clamp, lerp, sample_discrete};
use crate::utils::math::{safe_sqrt, square}; 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::utils::sampling::AliasTable;
use crate::{Float, ONE_MINUS_EPSILON, PI}; use crate::{Float, ONE_MINUS_EPSILON, PI};
use enum_dispatch::enum_dispatch; use enum_dispatch::enum_dispatch;
@ -154,14 +154,14 @@ impl CompactLightBounds {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct SampledLight { pub struct SampledLight {
pub light: Ptr<Light>, pub light: DevicePtr<Light>,
pub p: Float, pub p: Float,
} }
impl SampledLight { impl SampledLight {
pub fn new(light: Light, p: Float) -> Self { pub fn new(light: Light, p: Float) -> Self {
Self { Self {
light: Ptr::from(&light), light: DevicePtr::from(&light),
p, 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; let light_index = (u as u32 * self.lights_len).min(self.lights_len - 1) as usize;
Some(SampledLight { Some(SampledLight {
light: Ptr::from(&self.light(light_index)), light: DevicePtr::from(&self.light(light_index)),
p: 1. / self.lights_len as Float, p: 1. / self.lights_len as Float,
}) })
} }
@ -262,7 +262,7 @@ impl LightSamplerTrait for PowerLightSampler {
let light_ref = &self.lights[light_index as usize]; let light_ref = &self.lights[light_index as usize];
Some(SampledLight { Some(SampledLight {
light: Ptr::from(light_ref), light: DevicePtr::from(light_ref),
p: pmf, p: pmf,
}) })
} }

View file

@ -5,14 +5,14 @@ use crate::core::interaction::{Interaction, InteractionBase, InteractionTrait, S
use crate::core::light::{LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait}; use crate::core::light::{LightBase, LightBounds, LightLiSample, LightSampleContext, LightTrait};
use crate::core::spectrum::SpectrumTrait; use crate::core::spectrum::SpectrumTrait;
use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths}; use crate::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::DevicePtr;
use crate::{Float, PI}; use crate::{Float, PI};
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct SpotLight { pub struct SpotLight {
pub base: LightBase, pub base: LightBase,
pub iemit: Ptr<DenselySampledSpectrum>, pub iemit: DevicePtr<DenselySampledSpectrum>,
pub scale: Float, pub scale: Float,
pub cos_falloff_start: Float, pub cos_falloff_start: Float,
pub cos_falloff_end: Float, pub cos_falloff_end: Float,

View file

@ -4,27 +4,27 @@ use crate::bxdfs::{
use crate::core::bsdf::BSDF; use crate::core::bsdf::BSDF;
use crate::core::bssrdf::BSSRDF; use crate::core::bssrdf::BSSRDF;
use crate::core::bxdf::BxDF; 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::material::{Material, MaterialEvalContext, MaterialTrait};
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::DevicePtr;
use crate::utils::math::clamp; use crate::utils::math::clamp;
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct CoatedDiffuseMaterial { pub struct CoatedDiffuseMaterial {
pub normal_map: Ptr<Image>, pub normal_map: DevicePtr<DeviceImage>,
pub displacement: Ptr<GPUFloatTexture>, pub displacement: DevicePtr<GPUFloatTexture>,
pub reflectance: Ptr<GPUSpectrumTexture>, pub reflectance: DevicePtr<GPUSpectrumTexture>,
pub albedo: Ptr<GPUSpectrumTexture>, pub albedo: DevicePtr<GPUSpectrumTexture>,
pub u_roughness: Ptr<GPUFloatTexture>, pub u_roughness: DevicePtr<GPUFloatTexture>,
pub v_roughness: Ptr<GPUFloatTexture>, pub v_roughness: DevicePtr<GPUFloatTexture>,
pub thickness: Ptr<GPUFloatTexture>, pub thickness: DevicePtr<GPUFloatTexture>,
pub g: Ptr<GPUFloatTexture>, pub g: DevicePtr<GPUFloatTexture>,
pub eta: Ptr<Spectrum>, pub eta: DevicePtr<Spectrum>,
pub remap_roughness: bool, pub remap_roughness: bool,
pub max_depth: usize, pub max_depth: usize,
pub n_samples: usize, pub n_samples: usize,
@ -42,21 +42,21 @@ impl CoatedDiffuseMaterial {
g: &GPUFloatTexture, g: &GPUFloatTexture,
eta: &Spectrum, eta: &Spectrum,
displacement: &GPUFloatTexture, displacement: &GPUFloatTexture,
normal_map: &Image, normal_map: &DeviceImage,
remap_roughness: bool, remap_roughness: bool,
max_depth: usize, max_depth: usize,
n_samples: usize, n_samples: usize,
) -> Self { ) -> Self {
Self { Self {
displacement: Ptr::from(displacement), displacement: DevicePtr::from(displacement),
normal_map: Ptr::from(normal_map), normal_map: DevicePtr::from(normal_map),
reflectance: Ptr::from(reflectance), reflectance: DevicePtr::from(reflectance),
albedo: Ptr::from(albedo), albedo: DevicePtr::from(albedo),
u_roughness: Ptr::from(u_roughness), u_roughness: DevicePtr::from(u_roughness),
v_roughness: Ptr::from(v_roughness), v_roughness: DevicePtr::from(v_roughness),
thickness: Ptr::from(thickness), thickness: DevicePtr::from(thickness),
g: Ptr::from(g), g: DevicePtr::from(g),
eta: Ptr::from(eta), eta: DevicePtr::from(eta),
remap_roughness, remap_roughness,
max_depth, max_depth,
n_samples, n_samples,
@ -115,7 +115,7 @@ impl MaterialTrait for CoatedDiffuseMaterial {
self.n_samples, self.n_samples,
)); ));
BSDF::new(ctx.ns, ctx.dpdus, Ptr::from(&bxdf)) BSDF::new(ctx.ns, ctx.dpdus, DevicePtr::from(&bxdf))
} }
fn get_bssrdf<T>( fn get_bssrdf<T>(
@ -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) Some(&*self.normal_map)
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> DevicePtr<GPUFloatTexture> {
self.displacement self.displacement
} }
@ -150,19 +150,19 @@ impl MaterialTrait for CoatedDiffuseMaterial {
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct CoatedConductorMaterial { pub struct CoatedConductorMaterial {
normal_map: Ptr<Image>, normal_map: DevicePtr<DeviceImage>,
displacement: Ptr<GPUFloatTexture>, displacement: DevicePtr<GPUFloatTexture>,
interface_uroughness: Ptr<GPUFloatTexture>, interface_uroughness: DevicePtr<GPUFloatTexture>,
interface_vroughness: Ptr<GPUFloatTexture>, interface_vroughness: DevicePtr<GPUFloatTexture>,
thickness: Ptr<GPUFloatTexture>, thickness: DevicePtr<GPUFloatTexture>,
interface_eta: Ptr<Spectrum>, interface_eta: DevicePtr<Spectrum>,
g: Ptr<GPUFloatTexture>, g: DevicePtr<GPUFloatTexture>,
albedo: Ptr<GPUSpectrumTexture>, albedo: DevicePtr<GPUSpectrumTexture>,
conductor_uroughness: Ptr<GPUFloatTexture>, conductor_uroughness: DevicePtr<GPUFloatTexture>,
conductor_vroughness: Ptr<GPUFloatTexture>, conductor_vroughness: DevicePtr<GPUFloatTexture>,
conductor_eta: Ptr<GPUSpectrumTexture>, conductor_eta: DevicePtr<GPUSpectrumTexture>,
k: Ptr<GPUSpectrumTexture>, k: DevicePtr<GPUSpectrumTexture>,
reflectance: Ptr<GPUSpectrumTexture>, reflectance: DevicePtr<GPUSpectrumTexture>,
remap_roughness: bool, remap_roughness: bool,
max_depth: u32, max_depth: u32,
n_samples: u32, n_samples: u32,
@ -172,7 +172,7 @@ impl CoatedConductorMaterial {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
#[cfg(not(target_os = "cuda"))] #[cfg(not(target_os = "cuda"))]
pub fn new( pub fn new(
normal_map: &Image, normal_map: &DeviceImage,
displacement: &GPUFloatTexture, displacement: &GPUFloatTexture,
interface_uroughness: &GPUFloatTexture, interface_uroughness: &GPUFloatTexture,
interface_vroughness: &GPUFloatTexture, interface_vroughness: &GPUFloatTexture,
@ -190,19 +190,19 @@ impl CoatedConductorMaterial {
n_samples: u32, n_samples: u32,
) -> Self { ) -> Self {
Self { Self {
displacement: Ptr::from(displacement), displacement: DevicePtr::from(displacement),
normal_map: Ptr::from(normal_map), normal_map: DevicePtr::from(normal_map),
interface_uroughness: Ptr::from(interface_uroughness), interface_uroughness: DevicePtr::from(interface_uroughness),
interface_vroughness: Ptr::from(interface_vroughness), interface_vroughness: DevicePtr::from(interface_vroughness),
thickness: Ptr::from(thickness), thickness: DevicePtr::from(thickness),
interface_eta: Ptr::from(interface_eta), interface_eta: DevicePtr::from(interface_eta),
g: Ptr::from(g), g: DevicePtr::from(g),
albedo: Ptr::from(albedo), albedo: DevicePtr::from(albedo),
conductor_uroughness: Ptr::from(conductor_uroughness), conductor_uroughness: DevicePtr::from(conductor_uroughness),
conductor_vroughness: Ptr::from(conductor_vroughness), conductor_vroughness: DevicePtr::from(conductor_vroughness),
conductor_eta: Ptr::from(conductor_eta), conductor_eta: DevicePtr::from(conductor_eta),
k: Ptr::from(k), k: DevicePtr::from(k),
reflectance: Ptr::from(reflectance), reflectance: DevicePtr::from(reflectance),
remap_roughness, remap_roughness,
max_depth, max_depth,
n_samples, n_samples,
@ -285,7 +285,7 @@ impl MaterialTrait for CoatedConductorMaterial {
self.max_depth as usize, self.max_depth as usize,
self.n_samples 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<T>( fn get_bssrdf<T>(
@ -326,11 +326,11 @@ impl MaterialTrait for CoatedConductorMaterial {
tex_eval.can_evaluate(&float_textures, &spectrum_textures) 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) Some(&*self.normal_map)
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> DevicePtr<GPUFloatTexture> {
self.displacement self.displacement
} }

View file

@ -6,40 +6,40 @@ use crate::bxdfs::{
use crate::core::bsdf::BSDF; use crate::core::bsdf::BSDF;
use crate::core::bssrdf::{BSSRDF, BSSRDFTable}; use crate::core::bssrdf::{BSSRDF, BSSRDFTable};
use crate::core::bxdf::BxDF; 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::material::{Material, MaterialEvalContext, MaterialTrait};
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::textures::GPUSpectrumMixTexture; use crate::textures::GPUSpectrumMixTexture;
use crate::utils::Ptr; use crate::utils::DevicePtr;
use crate::utils::math::clamp; use crate::utils::math::clamp;
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct HairMaterial { pub struct HairMaterial {
pub sigma_a: Ptr<GPUSpectrumTexture>, pub sigma_a: DevicePtr<GPUSpectrumTexture>,
pub color: Ptr<GPUSpectrumTexture>, pub color: DevicePtr<GPUSpectrumTexture>,
pub eumelanin: Ptr<GPUFloatTexture>, pub eumelanin: DevicePtr<GPUFloatTexture>,
pub pheomelanin: Ptr<GPUFloatTexture>, pub pheomelanin: DevicePtr<GPUFloatTexture>,
pub eta: Ptr<GPUFloatTexture>, pub eta: DevicePtr<GPUFloatTexture>,
pub beta_m: Ptr<GPUFloatTexture>, pub beta_m: DevicePtr<GPUFloatTexture>,
pub beta_n: Ptr<GPUFloatTexture>, pub beta_n: DevicePtr<GPUFloatTexture>,
pub alpha: Ptr<GPUFloatTexture>, pub alpha: DevicePtr<GPUFloatTexture>,
} }
impl HairMaterial { impl HairMaterial {
#[cfg(not(target_os = "cuda"))] #[cfg(not(target_os = "cuda"))]
pub fn new( pub fn new(
sigma_a: Ptr<GPUSpectrumTexture>, sigma_a: DevicePtr<GPUSpectrumTexture>,
color: Ptr<GPUSpectrumTexture>, color: DevicePtr<GPUSpectrumTexture>,
eumelanin: Ptr<GPUFloatTexture>, eumelanin: DevicePtr<GPUFloatTexture>,
pheomelanin: Ptr<GPUFloatTexture>, pheomelanin: DevicePtr<GPUFloatTexture>,
eta: Ptr<GPUFloatTexture>, eta: DevicePtr<GPUFloatTexture>,
beta_m: Ptr<GPUFloatTexture>, beta_m: DevicePtr<GPUFloatTexture>,
beta_n: Ptr<GPUFloatTexture>, beta_n: DevicePtr<GPUFloatTexture>,
alpha: Ptr<GPUFloatTexture>, alpha: DevicePtr<GPUFloatTexture>,
) -> Self { ) -> Self {
Self { Self {
sigma_a, sigma_a,
@ -76,12 +76,12 @@ impl MaterialTrait for HairMaterial {
todo!() todo!()
} }
fn get_normal_map(&self) -> Option<&Image> { fn get_normal_map(&self) -> Option<&DeviceImage> {
todo!() todo!()
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> DevicePtr<GPUFloatTexture> {
Ptr::null() DevicePtr::null()
} }
fn has_subsurface_scattering(&self) -> bool { fn has_subsurface_scattering(&self) -> bool {
@ -92,9 +92,9 @@ impl MaterialTrait for HairMaterial {
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct MeasuredMaterial { pub struct MeasuredMaterial {
pub displacement: Ptr<GPUFloatTexture>, pub displacement: DevicePtr<GPUFloatTexture>,
pub normal_map: Ptr<Image>, pub normal_map: DevicePtr<DeviceImage>,
pub brdf: Ptr<MeasuredBxDFData>, pub brdf: DevicePtr<MeasuredBxDFData>,
} }
impl MaterialTrait for MeasuredMaterial { impl MaterialTrait for MeasuredMaterial {
@ -121,11 +121,11 @@ impl MaterialTrait for MeasuredMaterial {
true true
} }
fn get_normal_map(&self) -> Option<&Image> { fn get_normal_map(&self) -> Option<&DeviceImage> {
Some(&*self.normal_map) Some(&*self.normal_map)
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> DevicePtr<GPUFloatTexture> {
self.displacement self.displacement
} }
@ -137,16 +137,16 @@ impl MaterialTrait for MeasuredMaterial {
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct SubsurfaceMaterial { pub struct SubsurfaceMaterial {
pub normal_map: Ptr<Image>, pub normal_map: DevicePtr<DeviceImage>,
pub displacement: Ptr<GPUFloatTexture>, pub displacement: DevicePtr<GPUFloatTexture>,
pub sigma_a: Ptr<GPUSpectrumTexture>, pub sigma_a: DevicePtr<GPUSpectrumTexture>,
pub sigma_s: Ptr<GPUSpectrumMixTexture>, pub sigma_s: DevicePtr<GPUSpectrumMixTexture>,
pub reflectance: Ptr<GPUSpectrumMixTexture>, pub reflectance: DevicePtr<GPUSpectrumMixTexture>,
pub mfp: Ptr<GPUSpectrumMixTexture>, pub mfp: DevicePtr<GPUSpectrumMixTexture>,
pub eta: Float, pub eta: Float,
pub scale: Float, pub scale: Float,
pub u_roughness: Ptr<GPUFloatTexture>, pub u_roughness: DevicePtr<GPUFloatTexture>,
pub v_roughness: Ptr<GPUFloatTexture>, pub v_roughness: DevicePtr<GPUFloatTexture>,
pub remap_roughness: bool, pub remap_roughness: bool,
pub table: BSSRDFTable, pub table: BSSRDFTable,
} }
@ -173,11 +173,11 @@ impl MaterialTrait for SubsurfaceMaterial {
todo!() todo!()
} }
fn get_normal_map(&self) -> Option<&Image> { fn get_normal_map(&self) -> Option<&DeviceImage> {
todo!() todo!()
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> DevicePtr<GPUFloatTexture> {
todo!() todo!()
} }

View file

@ -4,26 +4,26 @@ use crate::bxdfs::{
use crate::core::bsdf::BSDF; use crate::core::bsdf::BSDF;
use crate::core::bssrdf::BSSRDF; use crate::core::bssrdf::BSSRDF;
use crate::core::bxdf::BxDF; 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::material::{Material, MaterialEvalContext, MaterialTrait};
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::DevicePtr;
use crate::utils::math::clamp; use crate::utils::math::clamp;
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct ConductorMaterial { pub struct ConductorMaterial {
pub displacement: Ptr<GPUFloatTexture>, pub displacement: DevicePtr<GPUFloatTexture>,
pub eta: Ptr<GPUSpectrumTexture>, pub eta: DevicePtr<GPUSpectrumTexture>,
pub k: Ptr<GPUSpectrumTexture>, pub k: DevicePtr<GPUSpectrumTexture>,
pub reflectance: Ptr<GPUSpectrumTexture>, pub reflectance: DevicePtr<GPUSpectrumTexture>,
pub u_roughness: Ptr<GPUFloatTexture>, pub u_roughness: DevicePtr<GPUFloatTexture>,
pub v_roughness: Ptr<GPUFloatTexture>, pub v_roughness: DevicePtr<GPUFloatTexture>,
pub remap_roughness: bool, pub remap_roughness: bool,
pub normal_map: Ptr<Image>, pub normal_map: DevicePtr<DeviceImage>,
} }
impl MaterialTrait for ConductorMaterial { 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!() todo!()
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> DevicePtr<GPUFloatTexture> {
todo!() todo!()
} }

View file

@ -4,23 +4,23 @@ use crate::bxdfs::{
use crate::core::bsdf::BSDF; use crate::core::bsdf::BSDF;
use crate::core::bssrdf::BSSRDF; use crate::core::bssrdf::BSSRDF;
use crate::core::bxdf::BxDF; 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::material::{Material, MaterialEvalContext, MaterialTrait};
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::DevicePtr;
use crate::utils::math::clamp; use crate::utils::math::clamp;
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct DielectricMaterial { pub struct DielectricMaterial {
normal_map: Ptr<Image>, normal_map: DevicePtr<DeviceImage>,
displacement: Ptr<GPUFloatTexture>, displacement: DevicePtr<GPUFloatTexture>,
u_roughness: Ptr<GPUFloatTexture>, u_roughness: DevicePtr<GPUFloatTexture>,
v_roughness: Ptr<GPUFloatTexture>, v_roughness: DevicePtr<GPUFloatTexture>,
eta: Ptr<Spectrum>, eta: DevicePtr<Spectrum>,
remap_roughness: bool, remap_roughness: bool,
} }
@ -51,7 +51,7 @@ impl MaterialTrait for DielectricMaterial {
let distrib = TrowbridgeReitzDistribution::new(u_rough, v_rough); let distrib = TrowbridgeReitzDistribution::new(u_rough, v_rough);
let bxdf = BxDF::Dielectric(DielectricBxDF::new(sampled_eta, distrib)); 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<T>( fn get_bssrdf<T>(
@ -67,11 +67,11 @@ impl MaterialTrait for DielectricMaterial {
tex_eval.can_evaluate(&[self.u_roughness, self.v_roughness], &[]) 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) Some(&*self.normal_map)
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> DevicePtr<GPUFloatTexture> {
self.displacement self.displacement
} }
@ -83,9 +83,9 @@ impl MaterialTrait for DielectricMaterial {
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct ThinDielectricMaterial { pub struct ThinDielectricMaterial {
pub displacement: Ptr<GPUFloatTexture>, pub displacement: DevicePtr<GPUFloatTexture>,
pub normal_map: Ptr<Image>, pub normal_map: DevicePtr<DeviceImage>,
pub eta: Ptr<Spectrum>, pub eta: DevicePtr<Spectrum>,
} }
impl MaterialTrait for ThinDielectricMaterial { impl MaterialTrait for ThinDielectricMaterial {
fn get_bsdf<T: TextureEvaluator>( fn get_bsdf<T: TextureEvaluator>(
@ -109,11 +109,11 @@ impl MaterialTrait for ThinDielectricMaterial {
true true
} }
fn get_normal_map(&self) -> Option<&Image> { fn get_normal_map(&self) -> Option<&DeviceImage> {
Some(&*self.normal_map) Some(&*self.normal_map)
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> DevicePtr<GPUFloatTexture> {
self.displacement self.displacement
} }

View file

@ -5,21 +5,21 @@ use crate::bxdfs::{
use crate::core::bsdf::BSDF; use crate::core::bsdf::BSDF;
use crate::core::bssrdf::BSSRDF; use crate::core::bssrdf::BSSRDF;
use crate::core::bxdf::BxDF; 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::material::{Material, MaterialEvalContext, MaterialTrait};
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator}; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::DevicePtr;
use crate::utils::math::clamp; use crate::utils::math::clamp;
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct DiffuseMaterial { pub struct DiffuseMaterial {
pub normal_map: Ptr<Image>, pub normal_map: DevicePtr<DeviceImage>,
pub displacement: Ptr<GPUFloatTexture>, pub displacement: DevicePtr<GPUFloatTexture>,
pub reflectance: Ptr<GPUSpectrumTexture>, pub reflectance: DevicePtr<GPUSpectrumTexture>,
} }
impl MaterialTrait for DiffuseMaterial { impl MaterialTrait for DiffuseMaterial {
@ -31,7 +31,7 @@ impl MaterialTrait for DiffuseMaterial {
) -> BSDF { ) -> BSDF {
let r = tex_eval.evaluate_spectrum(&self.reflectance, ctx, lambda); let r = tex_eval.evaluate_spectrum(&self.reflectance, ctx, lambda);
let bxdf = BxDF::Diffuse(DiffuseBxDF::new(r)); 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<T>( fn get_bssrdf<T>(
@ -47,11 +47,11 @@ impl MaterialTrait for DiffuseMaterial {
tex_eval.can_evaluate(&[], &[self.reflectance]) tex_eval.can_evaluate(&[], &[self.reflectance])
} }
fn get_normal_map(&self) -> Option<&Image> { fn get_normal_map(&self) -> Option<&DeviceImage> {
Some(&*self.normal_map) Some(&*self.normal_map)
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> DevicePtr<GPUFloatTexture> {
self.displacement self.displacement
} }
@ -63,10 +63,10 @@ impl MaterialTrait for DiffuseMaterial {
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct DiffuseTransmissionMaterial { pub struct DiffuseTransmissionMaterial {
pub image: Ptr<Image>, pub image: DevicePtr<DeviceImage>,
pub displacement: Ptr<GPUFloatTexture>, pub displacement: DevicePtr<GPUFloatTexture>,
pub reflectance: Ptr<GPUFloatTexture>, pub reflectance: DevicePtr<GPUFloatTexture>,
pub transmittance: Ptr<GPUFloatTexture>, pub transmittance: DevicePtr<GPUFloatTexture>,
pub scale: Float, pub scale: Float,
} }
@ -92,11 +92,11 @@ impl MaterialTrait for DiffuseTransmissionMaterial {
tex_eval.can_evaluate(&[self.reflectance, self.transmittance], &[]) 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) Some(&*self.image)
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> DevicePtr<GPUFloatTexture> {
self.displacement self.displacement
} }

View file

@ -4,7 +4,7 @@ use crate::bxdfs::{
use crate::core::bsdf::BSDF; use crate::core::bsdf::BSDF;
use crate::core::bssrdf::BSSRDF; use crate::core::bssrdf::BSSRDF;
use crate::core::bxdf::BxDF; 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::material::{Material, MaterialEvalContext, MaterialTrait};
use crate::core::scattering::TrowbridgeReitzDistribution; use crate::core::scattering::TrowbridgeReitzDistribution;
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
@ -12,13 +12,13 @@ use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvaluator
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::hash::hash_float; use crate::utils::hash::hash_float;
use crate::utils::math::clamp; use crate::utils::math::clamp;
use crate::utils::{ArenaPtr, Ptr}; use crate::utils::{DevicePtr, Ptr};
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct MixMaterial { pub struct MixMaterial {
pub amount: Ptr<GPUFloatTexture>, pub amount: DevicePtr<GPUFloatTexture>,
pub materials: [ArenaPtr<Material>; 2], pub materials: [Ptr<Material>; 2],
} }
impl MixMaterial { impl MixMaterial {
@ -69,11 +69,11 @@ impl MaterialTrait for MixMaterial {
tex_eval.can_evaluate(&[self.amount], &[]) tex_eval.can_evaluate(&[self.amount], &[])
} }
fn get_normal_map(&self) -> Option<&Image> { fn get_normal_map(&self) -> Option<&DeviceImage> {
None None
} }
fn get_displacement(&self) -> Ptr<GPUFloatTexture> { fn get_displacement(&self) -> DevicePtr<GPUFloatTexture> {
panic!( panic!(
"MixMaterial::get_displacement() shouldn't be called. \ "MixMaterial::get_displacement() shouldn't be called. \
Displacement is not supported on Mix materials directly." Displacement is not supported on Mix materials directly."

View file

@ -3,17 +3,17 @@ use crate::core::geometry::Point2f;
use crate::core::pbrt::Float; use crate::core::pbrt::Float;
use crate::spectra::{DenselySampledSpectrum, SampledSpectrum}; use crate::spectra::{DenselySampledSpectrum, SampledSpectrum};
use crate::utils::math::SquareMatrix3f; use crate::utils::math::SquareMatrix3f;
use crate::utils::ptr::Ptr; use crate::utils::ptr::DevicePtr;
use std::cmp::{Eq, PartialEq}; use std::cmp::{Eq, PartialEq};
#[repr(C)] #[repr(C)]
#[derive(Copy, Debug, Clone)] #[derive(Copy, Debug, Clone)]
pub struct StandardColorSpaces { pub struct StandardColorSpaces {
pub srgb: Ptr<RGBColorSpace>, pub srgb: DevicePtr<RGBColorSpace>,
pub dci_p3: Ptr<RGBColorSpace>, pub dci_p3: DevicePtr<RGBColorSpace>,
pub rec2020: Ptr<RGBColorSpace>, pub rec2020: DevicePtr<RGBColorSpace>,
pub aces2065_1: Ptr<RGBColorSpace>, pub aces2065_1: DevicePtr<RGBColorSpace>,
} }
#[repr(C)] #[repr(C)]
@ -24,7 +24,7 @@ pub struct RGBColorSpace {
pub b: Point2f, pub b: Point2f,
pub w: Point2f, pub w: Point2f,
pub illuminant: DenselySampledSpectrum, pub illuminant: DenselySampledSpectrum,
pub rgb_to_spectrum_table: Ptr<RGBToSpectrumTable>, pub rgb_to_spectrum_table: DevicePtr<RGBToSpectrumTable>,
pub xyz_from_rgb: SquareMatrix3f, pub xyz_from_rgb: SquareMatrix3f,
pub rgb_from_xyz: SquareMatrix3f, pub rgb_from_xyz: SquareMatrix3f,
} }
@ -52,6 +52,14 @@ impl RGBColorSpace {
self.rgb_from_xyz * other.xyz_from_rgb 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 { impl PartialEq for RGBColorSpace {

View file

@ -4,7 +4,7 @@ use super::{
}; };
use crate::core::color::{RGB, RGBSigmoidPolynomial, XYZ}; use crate::core::color::{RGB, RGBSigmoidPolynomial, XYZ};
use crate::core::spectrum::SpectrumTrait; use crate::core::spectrum::SpectrumTrait;
use crate::utils::Ptr; use crate::utils::DevicePtr;
use crate::Float; use crate::Float;
@ -69,7 +69,7 @@ impl SpectrumTrait for UnboundedRGBSpectrum {
pub struct RGBIlluminantSpectrum { pub struct RGBIlluminantSpectrum {
pub scale: Float, pub scale: Float,
pub rsp: RGBSigmoidPolynomial, pub rsp: RGBSigmoidPolynomial,
pub illuminant: Ptr<DenselySampledSpectrum>, pub illuminant: DevicePtr<DenselySampledSpectrum>,
} }
impl RGBIlluminantSpectrum { impl RGBIlluminantSpectrum {
@ -85,7 +85,7 @@ impl RGBIlluminantSpectrum {
Self { Self {
scale, scale,
rsp, rsp,
illuminant: Ptr::from(&illuminant), illuminant: DevicePtr::from(&illuminant),
} }
} }
} }

View file

@ -2,7 +2,7 @@ use super::cie::*;
use super::sampled::{LAMBDA_MAX, LAMBDA_MIN}; use super::sampled::{LAMBDA_MAX, LAMBDA_MIN};
use crate::core::spectrum::{Spectrum, SpectrumTrait}; use crate::core::spectrum::{Spectrum, SpectrumTrait};
use crate::spectra::{N_SPECTRUM_SAMPLES, SampledSpectrum, SampledWavelengths}; use crate::spectra::{N_SPECTRUM_SAMPLES, SampledSpectrum, SampledWavelengths};
use crate::utils::ptr::Ptr; use crate::utils::ptr::DevicePtr;
use crate::{Float, find_interval}; use crate::{Float, find_interval};
use core::slice; use core::slice;
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
@ -35,7 +35,7 @@ impl SpectrumTrait for ConstantSpectrum {
pub struct DenselySampledSpectrum { pub struct DenselySampledSpectrum {
pub lambda_min: i32, pub lambda_min: i32,
pub lambda_max: i32, pub lambda_max: i32,
pub values: Ptr<Float>, pub values: DevicePtr<Float>,
} }
unsafe impl Send for DenselySampledSpectrum {} unsafe impl Send for DenselySampledSpectrum {}
@ -130,8 +130,8 @@ impl SpectrumTrait for DenselySampledSpectrum {
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct PiecewiseLinearSpectrum { pub struct PiecewiseLinearSpectrum {
pub lambdas: Ptr<Float>, pub lambdas: DevicePtr<Float>,
pub values: Ptr<Float>, pub values: DevicePtr<Float>,
pub count: u32, pub count: u32,
} }

View file

@ -3,7 +3,7 @@ use crate::core::spectrum::Spectrum;
use crate::core::spectrum::SpectrumTrait; use crate::core::spectrum::SpectrumTrait;
use crate::core::texture::{TextureEvalContext, TextureMapping2D}; use crate::core::texture::{TextureEvalContext, TextureMapping2D};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::{Ptr, Transform}; use crate::utils::{DevicePtr, Transform};
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
@ -48,19 +48,19 @@ impl FloatBilerpTexture {
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct SpectrumBilerpTexture { pub struct SpectrumBilerpTexture {
pub mapping: TextureMapping2D, pub mapping: TextureMapping2D,
pub v00: Ptr<Spectrum>, pub v00: DevicePtr<Spectrum>,
pub v01: Ptr<Spectrum>, pub v01: DevicePtr<Spectrum>,
pub v10: Ptr<Spectrum>, pub v10: DevicePtr<Spectrum>,
pub v11: Ptr<Spectrum>, pub v11: DevicePtr<Spectrum>,
} }
impl SpectrumBilerpTexture { impl SpectrumBilerpTexture {
pub fn new( pub fn new(
mapping: TextureMapping2D, mapping: TextureMapping2D,
v00: Ptr<Spectrum>, v00: DevicePtr<Spectrum>,
v01: Ptr<Spectrum>, v01: DevicePtr<Spectrum>,
v10: Ptr<Spectrum>, v10: DevicePtr<Spectrum>,
v11: Ptr<Spectrum>, v11: DevicePtr<Spectrum>,
) -> Self { ) -> Self {
Self { Self {
mapping, mapping,

View file

@ -4,12 +4,12 @@ use crate::core::texture::{
TextureMapping3DTrait, TextureMapping3DTrait,
}; };
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::{ArenaPtr, Ptr, math::square}; use crate::utils::{DevicePtr, Ptr, math::square};
fn checkerboard( fn checkerboard(
ctx: &TextureEvalContext, ctx: &TextureEvalContext,
map2d: Ptr<TextureMapping2D>, map2d: DevicePtr<TextureMapping2D>,
map3d: Ptr<TextureMapping3D>, map3d: DevicePtr<TextureMapping3D>,
) -> Float { ) -> Float {
let d = |x: Float| -> Float { let d = |x: Float| -> Float {
let y = x / 2. - (x / 2.).floor() - 0.5; let y = x / 2. - (x / 2.).floor() - 0.5;
@ -43,9 +43,9 @@ fn checkerboard(
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct FloatCheckerboardTexture { pub struct FloatCheckerboardTexture {
pub map2d: Ptr<TextureMapping2D>, pub map2d: DevicePtr<TextureMapping2D>,
pub map3d: Ptr<TextureMapping3D>, pub map3d: DevicePtr<TextureMapping3D>,
pub tex: [ArenaPtr<GPUFloatTexture>; 2], pub tex: [Ptr<GPUFloatTexture>; 2],
} }
impl FloatCheckerboardTexture { impl FloatCheckerboardTexture {
@ -74,9 +74,9 @@ impl FloatCheckerboardTexture {
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct SpectrumCheckerboardTexture { pub struct SpectrumCheckerboardTexture {
pub map2d: Ptr<TextureMapping2D>, pub map2d: DevicePtr<TextureMapping2D>,
pub map3d: Ptr<TextureMapping3D>, pub map3d: DevicePtr<TextureMapping3D>,
pub tex: [ArenaPtr<GPUSpectrumTexture>; 2], pub tex: [Ptr<GPUSpectrumTexture>; 2],
} }
impl SpectrumCheckerboardTexture { impl SpectrumCheckerboardTexture {

View file

@ -4,7 +4,7 @@ use crate::core::texture::{
GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext, TextureMapping2D, GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext, TextureMapping2D,
}; };
use crate::spectra::sampled::{SampledSpectrum, SampledWavelengths}; use crate::spectra::sampled::{SampledSpectrum, SampledWavelengths};
use crate::utils::Ptr; use crate::utils::DevicePtr;
use crate::utils::math::square; use crate::utils::math::square;
use crate::utils::noise::noise_2d; use crate::utils::noise::noise_2d;
@ -28,8 +28,8 @@ fn inside_polka_dot(st: Point2f) -> bool {
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct FloatDotsTexture { pub struct FloatDotsTexture {
pub mapping: TextureMapping2D, pub mapping: TextureMapping2D,
pub outside_dot: Ptr<GPUFloatTexture>, pub outside_dot: DevicePtr<GPUFloatTexture>,
pub inside_dot: Ptr<GPUFloatTexture>, pub inside_dot: DevicePtr<GPUFloatTexture>,
} }
impl FloatDotsTexture { impl FloatDotsTexture {
@ -53,8 +53,8 @@ impl FloatDotsTexture {
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct SpectrumDotsTexture { pub struct SpectrumDotsTexture {
pub mapping: TextureMapping2D, pub mapping: TextureMapping2D,
pub outside_dot: Ptr<GPUSpectrumTexture>, pub outside_dot: DevicePtr<GPUSpectrumTexture>,
pub inside_dot: Ptr<GPUSpectrumTexture>, pub inside_dot: DevicePtr<GPUSpectrumTexture>,
} }
impl SpectrumDotsTexture { impl SpectrumDotsTexture {

View file

@ -95,11 +95,13 @@ impl GPUFloatImageTexture {
let d_p_dy = [c.dsdy, c.dtdy]; 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) }; let val: Float = unsafe { intrinsics::tex2d_grad(self.tex_obj, u, v, d_p_dx, d_p_dy) };
if self.invert { let result = if self.invert {
return (1. - v).max(0.); (1.0 - val).max(0.0) // Invert the pixel intensity
} else { } else {
return v; val
} };
return result * self.scale;
} }
} }
} }

View file

@ -6,7 +6,7 @@ use crate::core::texture::{TextureEvalContext, TextureMapping3D};
use crate::spectra::{RGBAlbedoSpectrum, RGBColorSpace, SampledSpectrum, SampledWavelengths}; use crate::spectra::{RGBAlbedoSpectrum, RGBColorSpace, SampledSpectrum, SampledWavelengths};
use crate::utils::math::clamp; use crate::utils::math::clamp;
use crate::utils::noise::fbm; use crate::utils::noise::fbm;
use crate::utils::ptr::Ptr; use crate::utils::ptr::DevicePtr;
use crate::utils::splines::evaluate_cubic_bezier; use crate::utils::splines::evaluate_cubic_bezier;
#[repr(C)] #[repr(C)]
@ -18,7 +18,7 @@ pub struct MarbleTexture {
pub scale: Float, pub scale: Float,
pub variation: Float, pub variation: Float,
// TODO: DO not forget to pass StandardColorSpace here!! // TODO: DO not forget to pass StandardColorSpace here!!
pub colorspace: Ptr<RGBColorSpace>, pub colorspace: DevicePtr<RGBColorSpace>,
} }
unsafe impl Send for MarbleTexture {} unsafe impl Send for MarbleTexture {}

View file

@ -2,14 +2,14 @@ use crate::Float;
use crate::core::geometry::{Vector3f, VectorLike}; use crate::core::geometry::{Vector3f, VectorLike};
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext}; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::ArenaPtr; use crate::utils::Ptr;
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct GPUFloatMixTexture { pub struct GPUFloatMixTexture {
pub tex1: ArenaPtr<GPUFloatTexture>, pub tex1: Ptr<GPUFloatTexture>,
pub tex2: ArenaPtr<GPUFloatTexture>, pub tex2: Ptr<GPUFloatTexture>,
pub amount: ArenaPtr<GPUFloatTexture>, pub amount: Ptr<GPUFloatTexture>,
} }
impl GPUFloatMixTexture { impl GPUFloatMixTexture {
@ -34,8 +34,8 @@ impl GPUFloatMixTexture {
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct GPUFloatDirectionMixTexture { pub struct GPUFloatDirectionMixTexture {
pub tex1: ArenaPtr<GPUFloatTexture>, pub tex1: Ptr<GPUFloatTexture>,
pub tex2: ArenaPtr<GPUFloatTexture>, pub tex2: Ptr<GPUFloatTexture>,
pub dir: Vector3f, pub dir: Vector3f,
} }
@ -61,9 +61,9 @@ impl GPUFloatDirectionMixTexture {
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct GPUSpectrumMixTexture { pub struct GPUSpectrumMixTexture {
pub tex1: ArenaPtr<GPUSpectrumTexture>, pub tex1: Ptr<GPUSpectrumTexture>,
pub tex2: ArenaPtr<GPUSpectrumTexture>, pub tex2: Ptr<GPUSpectrumTexture>,
pub amount: ArenaPtr<GPUFloatTexture>, pub amount: Ptr<GPUFloatTexture>,
} }
impl GPUSpectrumMixTexture { impl GPUSpectrumMixTexture {
@ -98,8 +98,8 @@ impl GPUSpectrumMixTexture {
#[repr(C)] #[repr(C)]
#[derive(Copy, Clone, Debug)] #[derive(Copy, Clone, Debug)]
pub struct GPUSpectrumDirectionMixTexture { pub struct GPUSpectrumDirectionMixTexture {
pub tex1: ArenaPtr<GPUSpectrumTexture>, pub tex1: Ptr<GPUSpectrumTexture>,
pub tex2: ArenaPtr<GPUSpectrumTexture>, pub tex2: Ptr<GPUSpectrumTexture>,
pub dir: Vector3f, pub dir: Vector3f,
} }

View file

@ -6,7 +6,7 @@ use crate::spectra::{
RGBAlbedoSpectrum, RGBColorSpace, RGBIlluminantSpectrum, RGBUnboundedSpectrum, SampledSpectrum, RGBAlbedoSpectrum, RGBColorSpace, RGBIlluminantSpectrum, RGBUnboundedSpectrum, SampledSpectrum,
SampledWavelengths, StandardColorSpaces, SampledWavelengths, StandardColorSpaces,
}; };
use crate::utils::ptr::{Ptr, Slice}; use crate::utils::ptr::{DevicePtr, Slice};
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]

View file

@ -1,13 +1,13 @@
use crate::Float; use crate::Float;
use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext}; use crate::core::texture::{GPUFloatTexture, GPUSpectrumTexture, TextureEvalContext};
use crate::spectra::{SampledSpectrum, SampledWavelengths}; use crate::spectra::{SampledSpectrum, SampledWavelengths};
use crate::utils::ArenaPtr; use crate::utils::Ptr;
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct GPUFloatScaledTexture { pub struct GPUFloatScaledTexture {
pub tex: ArenaPtr<GPUFloatTexture>, pub tex: Ptr<GPUFloatTexture>,
pub scale: ArenaPtr<GPUFloatTexture>, pub scale: Ptr<GPUFloatTexture>,
} }
impl GPUFloatScaledTexture { impl GPUFloatScaledTexture {
@ -23,8 +23,8 @@ impl GPUFloatScaledTexture {
#[repr(C)] #[repr(C)]
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct GPUSpectrumScaledTexture { pub struct GPUSpectrumScaledTexture {
pub tex: ArenaPtr<GPUSpectrumTexture>, pub tex: Ptr<GPUSpectrumTexture>,
pub scale: ArenaPtr<GPUFloatTexture>, pub scale: Ptr<GPUFloatTexture>,
} }
impl GPUSpectrumScaledTexture { impl GPUSpectrumScaledTexture {

View file

@ -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::hash::{hash_buffer, mix_bits};
use crate::utils::sobol::{SOBOL_MATRICES_32, VDC_SOBOL_MATRICES, VDC_SOBOL_MATRICES_INV}; 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 half::f16;
use num_traits::{Float as NumFloat, Num, One, Signed, Zero}; use num_traits::{Float as NumFloat, Num, One, Signed, Zero};
use std::error::Error; 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 struct DigitPermutation {
pub base: u32, pub base: u32,
pub n_digits: u32, pub n_digits: u32,
pub permutations: Ptr<u16>, pub permutations: DevicePtr<u16>,
} }
impl DigitPermutation { impl DigitPermutation {

View file

@ -1,8 +1,8 @@
use crate::Float; use crate::Float;
use crate::core::geometry::{Normal3f, Point2f, Point3f, Vector3f}; use crate::core::geometry::{Normal3f, Point2f, Point3f, Vector3f};
use crate::utils::Ptr;
use crate::utils::Transform; use crate::utils::Transform;
use crate::utils::ptr::Ptr; use crate::utils::sampling::DevicePiecewiseConstant2D;
use crate::utils::sampling::PiecewiseConstant2D;
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
@ -30,5 +30,5 @@ pub struct BilinearPatchMesh {
pub p: Ptr<Point3f>, pub p: Ptr<Point3f>,
pub n: Ptr<Normal3f>, pub n: Ptr<Normal3f>,
pub uv: Ptr<Point2f>, pub uv: Ptr<Point2f>,
pub image_distribution: Ptr<PiecewiseConstant2D>, pub image_distribution: Ptr<DevicePiecewiseConstant2D>,
} }

View file

@ -15,7 +15,7 @@ pub mod sobol;
pub mod splines; pub mod splines;
pub mod transform; pub mod transform;
pub use ptr::{ArenaPtr, Ptr}; pub use ptr::{DevicePtr, Ptr};
pub use transform::{AnimatedTransform, Transform, TransformGeneric}; pub use transform::{AnimatedTransform, Transform, TransformGeneric};
#[inline] #[inline]

View file

@ -3,84 +3,63 @@ use core::ops::Index;
#[repr(C)] #[repr(C)]
#[derive(Debug)] #[derive(Debug)]
pub struct ArenaPtr<T: ?Sized> { pub struct Ptr<T: ?Sized> {
offset: i32, pub offset: u32,
_marker: PhantomData<T>, pub _marker: PhantomData<T>,
} }
impl<T: ?Sized> Clone for ArenaPtr<T> { impl<T: ?Sized> Clone for Ptr<T> {
fn clone(&self) -> Self { fn clone(&self) -> Self {
*self *self
} }
} }
impl<T: ?Sized> Copy for Ptr<T> {}
impl<T: ?Sized> Copy for ArenaPtr<T> {} impl<T> Ptr<T> {
pub const NULL_OFFSET: u32 = 0xFFFFFFFF;
impl<T> ArenaPtr<T> {
pub fn null() -> Self { pub fn null() -> Self {
Self { Self {
offset: 0xFFFFFFFF, offset: Self::NULL_OFFSET,
_marker: PhantomData, _marker: PhantomData,
} }
} }
pub fn is_null(&self) -> bool { pub fn is_null(&self) -> bool {
self.offset == 0xFFFFFFFF self.offset == Self::NULL_OFFSET
} }
#[inline(always)] #[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() { if self.is_null() {
core::ptr::null() panic!("Null pointer dereference");
} else {
unsafe { base.add(self.offset as usize) as *const T }
} }
} unsafe {
let ptr = base.add(self.offset as usize);
#[inline(always)] &*(ptr as *const T)
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,
} }
} }
} }
#[repr(transparent)] #[repr(transparent)]
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct Ptr<T>(pub *const T); pub struct DevicePtr<T>(pub *const T);
impl<T> Default for Ptr<T> { impl<T> Default for DevicePtr<T> {
fn default() -> Self { fn default() -> Self {
Self(core::ptr::null()) Self(core::ptr::null())
} }
} }
impl<T> PartialEq for Ptr<T> { impl<T> PartialEq for DevicePtr<T> {
#[inline(always)] #[inline(always)]
fn eq(&self, other: &Self) -> bool { fn eq(&self, other: &Self) -> bool {
self.0 == other.0 self.0 == other.0
} }
} }
impl<T> Eq for Ptr<T> {} impl<T> Eq for DevicePtr<T> {}
impl<T> Ptr<T> { impl<T> DevicePtr<T> {
pub fn null() -> Self { pub fn null() -> Self {
Self::default() Self::default()
} }
@ -107,10 +86,10 @@ impl<T> Ptr<T> {
} }
} }
unsafe impl<T: Sync> Send for Ptr<T> {} unsafe impl<T: Sync> Send for DevicePtr<T> {}
unsafe impl<T: Sync> Sync for Ptr<T> {} unsafe impl<T: Sync> Sync for DevicePtr<T> {}
impl<T> std::ops::Deref for Ptr<T> { impl<T> std::ops::Deref for DevicePtr<T> {
type Target = T; type Target = T;
#[inline(always)] #[inline(always)]
@ -119,19 +98,19 @@ impl<T> std::ops::Deref for Ptr<T> {
} }
} }
impl<T> From<&T> for Ptr<T> { impl<T> From<&T> for DevicePtr<T> {
fn from(r: &T) -> Self { fn from(r: &T) -> Self {
Self(r as *const T) Self(r as *const T)
} }
} }
impl<T> From<&mut T> for Ptr<T> { impl<T> From<&mut T> for DevicePtr<T> {
fn from(r: &mut T) -> Self { fn from(r: &mut T) -> Self {
Self(r as *const T) Self(r as *const T)
} }
} }
impl<T> Index<usize> for Ptr<T> { impl<T> Index<usize> for DevicePtr<T> {
type Output = T; type Output = T;
#[inline(always)] #[inline(always)]
@ -142,7 +121,7 @@ impl<T> Index<usize> for Ptr<T> {
} }
} }
impl<T> Index<u32> for Ptr<T> { impl<T> Index<u32> for DevicePtr<T> {
type Output = T; type Output = T;
#[inline(always)] #[inline(always)]
@ -154,7 +133,7 @@ impl<T> Index<u32> for Ptr<T> {
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub struct Slice<T> { pub struct Slice<T> {
pub ptr: Ptr<T>, pub ptr: DevicePtr<T>,
pub len: u32, pub len: u32,
pub _marker: PhantomData<T>, pub _marker: PhantomData<T>,
} }
@ -163,7 +142,7 @@ unsafe impl<T: Sync> Send for Slice<T> {}
unsafe impl<T: Sync> Sync for Slice<T> {} unsafe impl<T: Sync> Sync for Slice<T> {}
impl<T> Slice<T> { impl<T> Slice<T> {
pub fn new(ptr: Ptr<T>, len: u32) -> Self { pub fn new(ptr: DevicePtr<T>, len: u32) -> Self {
Self { Self {
ptr, ptr,
len, len,

View file

@ -8,7 +8,7 @@ use crate::utils::math::{
catmull_rom_weights, clamp, difference_of_products, evaluate_polynomial, lerp, logistic, catmull_rom_weights, clamp, difference_of_products, evaluate_polynomial, lerp, logistic,
newton_bisection, safe_sqrt, square, sum_of_products, 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::utils::rng::Rng;
use crate::{ use crate::{
Float, INV_2_PI, INV_4_PI, INV_PI, ONE_MINUS_EPSILON, PI, PI_OVER_2, PI_OVER_4, find_interval, 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)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct PiecewiseConstant1D { pub struct DevicePiecewiseConstant1D {
pub func: Ptr<Float>, pub func: DevicePtr<Float>,
pub cdf: Ptr<Float>, pub cdf: DevicePtr<Float>,
pub min: Float, pub min: Float,
pub max: Float, pub max: Float,
pub n: u32, pub n: u32,
pub func_integral: Float, pub func_integral: Float,
} }
unsafe impl Send for PiecewiseConstant1D {} unsafe impl Send for DevicePiecewiseConstant1D {}
unsafe impl Sync for PiecewiseConstant1D {} unsafe impl Sync for DevicePiecewiseConstant1D {}
impl PiecewiseConstant1D { impl DevicePiecewiseConstant1D {
pub fn integral(&self) -> Float { pub fn integral(&self) -> Float {
self.func_integral self.func_integral
} }
@ -742,14 +742,14 @@ impl PiecewiseConstant1D {
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct PiecewiseConstant2D { pub struct DevicePiecewiseConstant2D {
pub domain: Bounds2f, pub domain: Bounds2f,
pub p_marginal: PiecewiseConstant1D, pub p_marginal: DevicePiecewiseConstant1D,
pub n_conditionals: usize, pub n_conditionals: usize,
pub p_conditional_v: Ptr<PiecewiseConstant1D>, pub p_conditional_v: DevicePtr<DevicePiecewiseConstant1D>,
} }
impl PiecewiseConstant2D { impl DevicePiecewiseConstant2D {
pub fn resolution(&self) -> Point2i { pub fn resolution(&self) -> Point2i {
Point2i::new( Point2i::new(
self.p_conditional_v[0u32].size() as i32, self.p_conditional_v[0u32].size() as i32,
@ -1056,10 +1056,10 @@ pub struct PiecewiseLinear2D<const N: usize> {
pub inv_patch_size: Vector2f, pub inv_patch_size: Vector2f,
pub param_size: [u32; N], pub param_size: [u32; N],
pub param_strides: [u32; N], pub param_strides: [u32; N],
pub param_values: [Ptr<Float>; N], pub param_values: [DevicePtr<Float>; N],
pub data: Ptr<Float>, pub data: DevicePtr<Float>,
pub marginal_cdf: Ptr<Float>, pub marginal_cdf: DevicePtr<Float>,
pub conditional_cdf: Ptr<Float>, pub conditional_cdf: DevicePtr<Float>,
} }
impl<const N: usize> PiecewiseLinear2D<N> { impl<const N: usize> PiecewiseLinear2D<N> {
@ -1311,7 +1311,7 @@ impl<const N: usize> PiecewiseLinear2D<N> {
fn lookup( fn lookup(
&self, &self,
data: Ptr<Float>, data: DevicePtr<Float>,
i0: u32, i0: u32,
size: u32, size: u32,
param_weight: &[(Float, Float); N], param_weight: &[(Float, Float); N],

View file

@ -7,7 +7,7 @@ use super::math::{SquareMatrix, radians, safe_acos};
use super::quaternion::Quaternion; use super::quaternion::Quaternion;
use crate::core::color::{RGB, XYZ}; use crate::core::color::{RGB, XYZ};
use crate::core::geometry::{ 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, VectorLike,
}; };
use crate::core::interaction::{ use crate::core::interaction::{
@ -714,6 +714,30 @@ where
} }
} }
} }
impl From<Frame> for TransformGeneric<Float> {
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<Quaternion> for TransformGeneric<Float> { impl From<Quaternion> for TransformGeneric<Float> {
fn from(q: Quaternion) -> Self { fn from(q: Quaternion) -> Self {
let xx = q.v.x() * q.v.x(); let xx = q.v.x() * q.v.x();

View file

@ -1,4 +1,4 @@
use super::ImageBuffer; use super::{Image, ImageAndMetadata};
use crate::utils::error::ImageError; use crate::utils::error::ImageError;
use anyhow::{Context, Result, bail}; use anyhow::{Context, Result, bail};
use exr::prelude::{read_first_rgba_layer_from_file, write_rgba_file}; 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 image_rs::{DynamicImage, ImageBuffer, Rgb, Rgba};
use shared::Float; use shared::Float;
use shared::core::color::{ColorEncoding, LINEAR, SRGB}; use shared::core::color::{ColorEncoding, LINEAR, SRGB};
use shared::core::image::Image; use shared::core::image::DeviceImage;
use std::fs::File; use std::fs::File;
use std::io::{BufRead, BufReader, BufWriter, Read, Write}; use std::io::{BufRead, BufReader, BufWriter, Read, Write};
use std::path::Path; use std::path::Path;
@ -21,7 +21,7 @@ pub trait ImageIO {
fn to_u8_buffer(&self) -> Vec<u8>; fn to_u8_buffer(&self) -> Vec<u8>;
} }
impl ImageIO for ImageBuffer { impl ImageIO for Image {
fn read(path: &Path, encoding: Option<ColorEncoding>) -> Result<ImageAndMetadata> { fn read(path: &Path, encoding: Option<ColorEncoding>) -> Result<ImageAndMetadata> {
let ext = path let ext = path
.extension() .extension()
@ -206,14 +206,14 @@ fn read_generic(path: &Path, encoding: Option<ColorEncoding>) -> Result<ImageAnd
// Check if it was loaded as high precision or standard // Check if it was loaded as high precision or standard
let image = match dyn_img { let image = match dyn_img {
DynamicImage::ImageRgb32F(buf) => Image { DynamicImage::ImageRgb32F(buf) => DeviceImage {
format: PixelFormat::F32, format: PixelFormat::F32,
resolution: res, resolution: res,
channel_names: vec!["R".into(), "G".into(), "B".into()], channel_names: vec!["R".into(), "G".into(), "B".into()],
encoding: LINEAR, encoding: LINEAR,
pixels: PixelData::F32(buf.into_raw()), pixels: PixelData::F32(buf.into_raw()),
}, },
DynamicImage::ImageRgba32F(buf) => Image { DynamicImage::ImageRgba32F(buf) => DeviceImage {
format: PixelFormat::F32, format: PixelFormat::F32,
resolution: res, resolution: res,
channel_names: vec!["R".into(), "G".into(), "B".into(), "A".into()], channel_names: vec!["R".into(), "G".into(), "B".into(), "A".into()],
@ -224,7 +224,7 @@ fn read_generic(path: &Path, encoding: Option<ColorEncoding>) -> Result<ImageAnd
// Default to RGB8 for everything else // Default to RGB8 for everything else
if dyn_img.color().has_alpha() { if dyn_img.color().has_alpha() {
let buf = dyn_img.to_rgba8(); let buf = dyn_img.to_rgba8();
Image { DeviceImage {
format: PixelFormat::U8, format: PixelFormat::U8,
resolution: res, resolution: res,
channel_names: vec!["R".into(), "G".into(), "B".into(), "A".into()], channel_names: vec!["R".into(), "G".into(), "B".into(), "A".into()],
@ -233,7 +233,7 @@ fn read_generic(path: &Path, encoding: Option<ColorEncoding>) -> Result<ImageAnd
} }
} else { } else {
let buf = dyn_img.to_rgb8(); let buf = dyn_img.to_rgb8();
Image { DeviceImage {
format: PixelFormat::U8, format: PixelFormat::U8,
resolution: res, resolution: res,
channel_names: vec!["R".into(), "G".into(), "B".into()], channel_names: vec!["R".into(), "G".into(), "B".into()],
@ -270,7 +270,7 @@ fn read_exr(path: &Path) -> Result<ImageAndMetadata> {
let w = image.layer_data.size.width() as i32; let w = image.layer_data.size.width() as i32;
let h = image.layer_data.size.height() as i32; let h = image.layer_data.size.height() as i32;
let image = Image { let image = DeviceImage {
format: PixelFormat::F32, format: PixelFormat::F32,
resolution: Point2i::new(w, h), resolution: Point2i::new(w, h),
channel_names: vec!["R".into(), "G".into(), "B".into(), "A".into()], channel_names: vec!["R".into(), "G".into(), "B".into(), "A".into()],
@ -355,7 +355,7 @@ fn read_pfm(path: &Path) -> Result<ImageAndMetadata> {
vec!["R".into(), "G".into(), "B".into()] vec!["R".into(), "G".into(), "B".into()]
}; };
let image = Image { let image = DeviceImage {
format: PixelFormat::F32, format: PixelFormat::F32,
resolution: Point2i::new(w, h), resolution: Point2i::new(w, h),
channel_names: names, channel_names: names,

View file

@ -1,5 +1,5 @@
use shared::core::geometry::Point2i; 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 shared::utils::math::f16_to_f32;
use std::ops::Deref; use std::ops::Deref;
@ -8,6 +8,7 @@ pub mod metadata;
pub mod ops; pub mod ops;
pub mod pixel; pub mod pixel;
pub use io::ImageIO;
pub use metadata::*; pub use metadata::*;
impl std::fmt::Display for PixelFormat { impl std::fmt::Display for PixelFormat {
@ -75,39 +76,50 @@ pub enum PixelStorage {
F32(Vec<f32>), F32(Vec<f32>),
} }
pub struct ImageBuffer { pub struct Image {
pub view: Image, pub base: ImageBase,
pub pixels: PixelStorage,
pub channel_names: Vec<String>, pub channel_names: Vec<String>,
_storage: PixelStorage,
} }
impl Deref for ImageBuffer { impl ImageAccess for Image {
type Target = Image; fn get_channel_with_wrap(&self, p: Point2i, c: i32, wrap_mode: WrapMode2D) -> Float {
fn deref(&self) -> &Self::Target { todo!()
&self.view }
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)] #[derive(Debug, Clone)]
pub struct ImageAndMetadata { pub struct ImageAndMetadata {
pub image: ImageBuffer, pub image: Image,
pub metadata: ImageMetadata, pub metadata: ImageMetadata,
} }
impl ImageBuffer { impl Image {
fn resolution(&self) { pub fn resolution(&self) -> Point2i {
self.view.resolution() self.base.resolution
}
fn n_channels(&self) -> i32 {
self.base.n_channels
} }
pub fn new_empty() -> Self { pub fn new_empty() -> Self {
Self { Self {
channel_names: Vec::new(), channel_names: Vec::new(),
_storage: PixelStorage::U8(Vec::new()), pixels: PixelStorage::U8(Vec::new()),
view: Image { base: ImageBase {
format: PixelFormat::U256, format: PixelFormat::U256,
resolution: Point2i::new(0, 0), resolution: Point2i::new(0, 0),
n_channels: 0, n_channels: 0,
pixels: Pixels::U8(std::ptr::null()),
encoding: ColorEncoding::default(), encoding: ColorEncoding::default(),
}, },
} }
@ -120,23 +132,22 @@ impl ImageBuffer {
encoding: ColorEncoding, encoding: ColorEncoding,
) -> Self { ) -> Self {
let n_channels = channel_names.len() as i32; 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::U8(vec) => (PixelFormat::U8, ImagePixels::U8(vec.as_ptr())),
PixelStorage::F16(vec) => (PixelFormat::F16, ImagePixels::F16(vec.as_ptr())), PixelStorage::F16(vec) => (PixelFormat::F16, ImagePixels::F16(vec.as_ptr())),
PixelStorage::F32(vec) => (PixelFormat::F32, ImagePixels::F32(vec.as_ptr())), PixelStorage::F32(vec) => (PixelFormat::F32, ImagePixels::F32(vec.as_ptr())),
}; };
let view = Image { let base = ImageBase {
format, format,
resolution, resolution,
n_channels, n_channels,
encoding, encoding,
pixels: pixels_view,
}; };
Self { Self {
view, base,
_storage: storage, pixels,
channel_names, channel_names,
} }
} }
@ -165,18 +176,17 @@ impl ImageBuffer {
_ => unreachable!(), _ => unreachable!(),
}; };
let view = Image { let base = ImageBase {
format: PixelFormat::U256, format: PixelFormat::U256,
resolution, resolution,
n_channels, n_channels,
pixels: Pixels::U8(ptr),
encoding: encoding.clone(), encoding: encoding.clone(),
}; };
Self { Self {
view, base,
channel_names, channel_names,
_storage: storage, pixels: ptr,
} }
} }
@ -205,18 +215,17 @@ impl ImageBuffer {
_ => unreachable!(), _ => unreachable!(),
}; };
let view = Image { let base = ImageBase {
format: PixelFormat::U256, format: PixelFormat::U256,
resolution, resolution,
n_channels, n_channels,
pixels: Pixels::U8(ptr),
encoding: encoding.clone(), encoding: encoding.clone(),
}; };
Self { Self {
view, base,
channel_names, channel_names,
_storage: storage, pixels: ptr,
} }
} }
@ -235,18 +244,17 @@ impl ImageBuffer {
_ => unreachable!(), _ => unreachable!(),
}; };
let view = Image { let base = ImageBase {
format: PixelFormat::Half, format: PixelFormat::Half,
resolution, resolution,
n_channels, n_channels,
pixels: Pixels::F16(ptr),
encoding: ColorEncoding::default(), encoding: ColorEncoding::default(),
}; };
Self { Self {
view, base,
channel_names, channel_names,
_storage: storage, pixels: ptr,
} }
} }
@ -265,18 +273,17 @@ impl ImageBuffer {
_ => unreachable!(), _ => unreachable!(),
}; };
let view = Image { let base = ImageBase {
format: PixelFormat::Float, format: PixelFormat::Float,
resolution, resolution,
n_channels, n_channels,
pixels: Pixels::F32(ptr),
encoding: ColorEncoding::default(), encoding: ColorEncoding::default(),
}; };
Self { Self {
view, base,
channel_names, channel_names,
_storage: storage, pixels: ptr,
} }
} }
@ -412,6 +419,16 @@ impl ImageBuffer {
ImageChannelValues(values) ImageChannelValues(values)
} }
pub fn get_channel_with_wrap(
&self,
p: Point2i,
c: i32,
wrap_mode: Option<WrapMode2D>,
) -> Float {
// if !self.remap_pixel_coords
0.
}
pub fn channel_names_from_desc(&self, desc: &ImageChannelDesc) -> Vec<&str> { pub fn channel_names_from_desc(&self, desc: &ImageChannelDesc) -> Vec<&str> {
desc.offset desc.offset
.iter() .iter()
@ -566,9 +583,9 @@ impl ImageBuffer {
pub fn mse( pub fn mse(
&self, &self,
desc: ImageChannelDesc, desc: ImageChannelDesc,
ref_img: &Image, ref_img: &DeviceImage,
generate_mse_image: bool, generate_mse_image: bool,
) -> (ImageChannelValues, Option<Image>) { ) -> (ImageChannelValues, Option<DeviceImage>) {
let mut sum_se: Vec<f64> = vec![0.; desc.size()]; let mut sum_se: Vec<f64> = vec![0.; desc.size()];
let names_ref = self.channel_names_from_desc(&desc); let names_ref = self.channel_names_from_desc(&desc);
let ref_desc = ref_img let ref_desc = ref_img
@ -613,7 +630,7 @@ impl ImageBuffer {
sum_se.iter().map(|&s| (s / pixel_count) as Float).collect(); sum_se.iter().map(|&s| (s / pixel_count) as Float).collect();
let mse_image = if generate_mse_image { let mse_image = if generate_mse_image {
Some(Image::new( Some(DeviceImage::new(
PixelFormat::F32, PixelFormat::F32,
self.resolution, self.resolution,
&names_ref, &names_ref,
@ -633,4 +650,21 @@ impl ImageBuffer {
PixelStorage::F32(vec) => Pixels::F32(vec.as_ptr()), 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;
}
} }

View file

@ -1,5 +1,5 @@
// use rayon::prelude::*; // use rayon::prelude::*;
use super::ImageBuffer; use super::Image;
use rayon::prelude::*; use rayon::prelude::*;
use shared::Float; use shared::Float;
use shared::core::geometry::{Bounds2i, Point2i}; use shared::core::geometry::{Bounds2i, Point2i};
@ -13,7 +13,7 @@ pub struct ResampleWeight {
pub weight: [Float; 4], pub weight: [Float; 4],
} }
impl ImageBuffer { impl Image {
pub fn flip_y(&mut self) { pub fn flip_y(&mut self) {
let res = self.resolution; let res = self.resolution;
let nc = self.n_channels(); let nc = self.n_channels();

View file

@ -1,31 +1,191 @@
use shared::core::geometry::{Bounds3f, Point2i}; use shared::core::geometry::{Bounds3f, Point2i};
use shared::core::image::Image; use shared::core::image::DeviceImage;
use shared::core::light::LightBase; use shared::core::light::{Light, LightBase};
use shared::core::medium::MediumInterface; use shared::core::medium::MediumInterface;
use shared::core::spectrum::Spectrum; use shared::core::spectrum::Spectrum;
use shared::spectra::{DenselySampledSpectrum, SampledSpectrum, SampledWavelengths}; use shared::core::texture::SpectrumType;
use shared::utils::Transform; 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 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::containers::InternCache;
use crate::utils::{Arena, ParameterDictionary, Upload, resolve_filename};
pub trait LightBaseTrait {
pub fn lookup_spectrum(s: &Spectrum) -> DenselySampledSpectrum { pub fn lookup_spectrum(s: &Spectrum) -> DenselySampledSpectrum {
let cache = SPECTRUM_CACHE.get_or_init(InternCache::new); let cache = SPECTRUM_CACHE.get_or_init(InternCache::new);
let dense_spectrum = DenselySampledSpectrum::from_spectrum(s); let dense_spectrum = DenselySampledSpectrum::from_spectrum(s);
cache.lookup(dense_spectrum).as_ref() cache.lookup(dense_spectrum).as_ref()
} }
}
impl LightBaseTrait for LightBase {} pub trait CreateLight {
pub trait LightFactory {
fn new( fn new(
render_from_light: Transform, render_from_light: Transform,
medium_interface: MediumInterface, medium_interface: MediumInterface,
le: Spectrum,
scale: Float, scale: Float,
iemit: &Spectrum, shape: Option<Ptr<Shape>>,
image: &Image, alpha: Option<Ptr<FloatTexture>>,
image: Option<Ptr<Image>>,
image_color_space: Option<Ptr<RGBColorSpace>>,
two_sided: Option<bool>,
fov: Option<Float>,
cos_fallof_start: Option<Float>,
total_width: Option<Float>,
) -> 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; ) -> 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);
}
}
}
}
}

View file

@ -1,4 +1,4 @@
use crate::core::image::ImageBuffer; use crate::core::image::Image;
use crate::utils::error::FileLoc; use crate::utils::error::FileLoc;
use crate::utils::parameters::ParameterDictionary; use crate::utils::parameters::ParameterDictionary;
use shared::core::material::Material; use shared::core::material::Material;
@ -8,7 +8,7 @@ use std::collections::HashMap;
pub trait CreateMaterial: Sized { pub trait CreateMaterial: Sized {
fn create( fn create(
parameters: &TextureParameterDictionary, parameters: &TextureParameterDictionary,
normal_map: Option<Arc<ImageBuffer>>, normal_map: Option<Arc<Image>>,
named_materials: &HashMap<String, Material>, named_materials: &HashMap<String, Material>,
loc: &FileLoc, loc: &FileLoc,
) -> Self; ) -> Self;
@ -35,7 +35,7 @@ pub trait MaterialFactory {
fn create( fn create(
name: &str, name: &str,
params: &TextureParameterDictionary, params: &TextureParameterDictionary,
normal_map: Arc<ImageBuffer>, normal_map: Arc<Image>,
named_materials: HashMap<String, Material>, named_materials: HashMap<String, Material>,
loc: &FileLoc, loc: &FileLoc,
) -> Result<Self, String>; ) -> Result<Self, String>;

View file

@ -1,5 +1,5 @@
use crate::core::filter::FilterFactory; 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::core::texture::SpectrumTexture;
use crate::utils::parallel::{AsyncJob, run_async}; use crate::utils::parallel::{AsyncJob, run_async};
use crate::utils::parameters::{ use crate::utils::parameters::{
@ -694,7 +694,7 @@ impl BasicScene {
let job = crate::parallel::run_async(move || { let job = crate::parallel::run_async(move || {
let path = std::path::Path::new(&filename_clone); 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)); .unwrap_or_else(|e| panic!("{}: unable to read normal map: {}", filename_clone, e));
let image = &immeta.image; let image = &immeta.image;

View file

@ -1,6 +1,6 @@
use crate::core::texture::FloatTexture; use crate::core::texture::FloatTexture;
use crate::shapes::TriQuadMesh; 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::options::get_options;
use shared::core::shape::*; use shared::core::shape::*;
use shared::shapes::*; use shared::shapes::*;
@ -21,6 +21,7 @@ pub trait CreateShape {
parameters: ParameterDictionary, parameters: ParameterDictionary,
float_textures: HashMap<String, FloatTexture>, float_textures: HashMap<String, FloatTexture>,
loc: FileLoc, loc: FileLoc,
arena: &mut Arena,
) -> Vec<Shape>; ) -> Vec<Shape>;
} }
@ -33,6 +34,7 @@ pub trait ShapeFactory {
parameters: ParameterDictionary, parameters: ParameterDictionary,
float_textures: HashMap<String, FloatTexture>, float_textures: HashMap<String, FloatTexture>,
loc: FileLoc, loc: FileLoc,
arena: &mut Arena,
) -> Vec<Shape>; ) -> Vec<Shape>;
} }
@ -45,6 +47,7 @@ impl ShapeFactory for Shape {
parameters: ParameterDictionary, parameters: ParameterDictionary,
float_textures: HashMap<String, FloatTexture>, float_textures: HashMap<String, FloatTexture>,
loc: FileLoc, loc: FileLoc,
arena: &mut Arena,
) -> Vec<Shape> { ) -> Vec<Shape> {
match name { match name {
"sphere" => SphereShape::create( "sphere" => SphereShape::create(
@ -55,6 +58,7 @@ impl ShapeFactory for Shape {
parameters, parameters,
float_textures, float_textures,
loc, loc,
arena,
), ),
"cylinder" => CylinderShape::create( "cylinder" => CylinderShape::create(
name, name,
@ -64,6 +68,7 @@ impl ShapeFactory for Shape {
parameters, parameters,
float_textures, float_textures,
loc, loc,
arena,
), ),
"disk" => DiskShape::create( "disk" => DiskShape::create(
name, name,
@ -73,6 +78,7 @@ impl ShapeFactory for Shape {
parameters, parameters,
float_textures, float_textures,
loc, loc,
arena,
), ),
"bilinearmesh" => BilinearPatchShape::create( "bilinearmesh" => BilinearPatchShape::create(
name, name,
@ -82,6 +88,7 @@ impl ShapeFactory for Shape {
parameters, parameters,
float_textures, float_textures,
loc, loc,
arena,
), ),
"trianglemesh" => TriangleShape::create( "trianglemesh" => TriangleShape::create(
name, name,
@ -91,6 +98,7 @@ impl ShapeFactory for Shape {
parameters, parameters,
float_textures, float_textures,
loc, loc,
arena,
), ),
"plymesh" => { "plymesh" => {
let filename = resolve_filename(parameters.get_one_string("filename", "")); let filename = resolve_filename(parameters.get_one_string("filename", ""));

View file

@ -1,4 +1,9 @@
use crate::core::light::LightBaseTrait;
use crate::spectra::cie_y;
use crate::utils::containers::InternCache; use crate::utils::containers::InternCache;
use shared::Float;
use shared::core::light::LightBase;
use shared::core::spectrum::Spectrum;
pub static SPECTRUM_CACHE: Lazy<Mutex<HashMap<String, Spectrum>>> = pub static SPECTRUM_CACHE: Lazy<Mutex<HashMap<String, Spectrum>>> =
Lazy::new(|| Mutex::new(HashMap::new())); Lazy::new(|| Mutex::new(HashMap::new()));
@ -6,3 +11,11 @@ pub static SPECTRUM_CACHE: Lazy<Mutex<HashMap<String, Spectrum>>> =
fn get_spectrum_cache() -> &'static InternCache<DenselySampledSpectrum> { fn get_spectrum_cache() -> &'static InternCache<DenselySampledSpectrum> {
SPECTRUM_CACHE.get_or_init(InternCache::new) 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)
}

View file

@ -1,6 +1,6 @@
use crate::core::image::ImageBuffer; use crate::core::image::Image;
use crate::core::material::CreateMaterial; use crate::core::material::CreateMaterial;
use crate::utils::parameters::ParameterDictionary; use crate::utils::{Arena, ParameterDictionary};
use shared::core::spectrum::Spectrum; use shared::core::spectrum::Spectrum;
use shared::core::texture::SpectrumType; use shared::core::texture::SpectrumType;
use shared::materials::coated::*; use shared::materials::coated::*;
@ -10,9 +10,10 @@ use shared::textures::SpectrumConstantTexture;
impl CreateMaterial for CoatedDiffuseMaterial { impl CreateMaterial for CoatedDiffuseMaterial {
fn create( fn create(
parameters: &TextureParameterDictionary, parameters: &TextureParameterDictionary,
normal_map: Option<Arc<ImageBuffer>>, normal_map: Option<Arc<Image>>,
named_materials: &HashMap<String, Material>, named_materials: &HashMap<String, Material>,
loc: &FileLoc, loc: &FileLoc,
area: &mut Arena,
) -> Self { ) -> Self {
let reflectance = parameters let reflectance = parameters
.get_spectrum_texture("reflectance", None, SpectrumType::Albedo) .get_spectrum_texture("reflectance", None, SpectrumType::Albedo)
@ -45,15 +46,30 @@ impl CreateMaterial for CoatedDiffuseMaterial {
}); });
let displacement = parameters.get_float_texture("displacement"); let displacement = parameters.get_float_texture("displacement");
let remap_roughness = parameters.get_one_bool("remaproughness", true); 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 { impl CreateMaterial for CoatedConductorMaterial {
fn create( fn create(
parameters: &TextureParameterDictionary, parameters: &TextureParameterDictionary,
normal_map: Option<Arc<ImageBuffer>>, normal_map: Option<Arc<Image>>,
named_materials: &HashMap<String, Material>, named_materials: &HashMap<String, Material>,
loc: &FileLoc, loc: &FileLoc,
arena: &mut Arena,
) -> Result<Self, String> { ) -> Result<Self, String> {
let interface_u_roughness = parameters let interface_u_roughness = parameters
.get_float_texture_or_null("interface.uroughness") .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 displacement = parameters.get_float_texture_or_null("displacement");
let remap_roughness = parameters.get_one_bool("remaproughness", true); let remap_roughness = parameters.get_one_bool("remaproughness", true);
Self::new( let material = Self::new(
displacement, displacement,
normal_map, normal_map,
interface_u_roughness, interface_u_roughness,
@ -123,6 +139,8 @@ impl CreateMaterial for CoatedConductorMaterial {
remap_roughness, remap_roughness,
max_depth, max_depth,
n_samples, n_samples,
) );
arena.alloc(material);
return material;
} }
} }

View file

@ -1,4 +1,5 @@
use crate::core::material::CreateMaterial; use crate::core::material::CreateMaterial;
use crate::utils::{Arena, FileLoc, TextureParameterDictionary};
use shared::core::bxdf::HairBxDF; use shared::core::bxdf::HairBxDF;
use shared::core::spectrum::Spectrum; use shared::core::spectrum::Spectrum;
use shared::core::texture::{GPUFloatTexture, GPUSpectrumTexture}; use shared::core::texture::{GPUFloatTexture, GPUSpectrumTexture};
@ -10,6 +11,7 @@ impl CreateMaterial for HairMaterial {
normal_map: Option<Arc<ImageBuffer>>, normal_map: Option<Arc<ImageBuffer>>,
named_materials: &HashMap<String, Material>, named_materials: &HashMap<String, Material>,
loc: &FileLoc, loc: &FileLoc,
arena: &mut Arena,
) -> Result<Self, String> { ) -> Result<Self, String> {
let sigma_a = parameters.get_spectrum_texture_or_null("sigma_a", SpectrumType::Unbounded); let sigma_a = parameters.get_spectrum_texture_or_null("sigma_a", SpectrumType::Unbounded);
let reflectance = parameters let reflectance = parameters
@ -57,7 +59,7 @@ impl CreateMaterial for HairMaterial {
let beta_m = parameters.get_float_texture("beta_m", 0.3); let beta_m = parameters.get_float_texture("beta_m", 0.3);
let beta_n = parameters.get_float_texture("beta_n", 0.3); let beta_n = parameters.get_float_texture("beta_n", 0.3);
let alpha = parameters.get_float_texture("alpha", 2.); let alpha = parameters.get_float_texture("alpha", 2.);
HairMaterial::new( let material = HairMaterial::new(
sigma_a, sigma_a,
reflectance, reflectance,
eumelanin, eumelanin,
@ -66,7 +68,10 @@ impl CreateMaterial for HairMaterial {
beta_m, beta_m,
beta_n, beta_n,
alpha, alpha,
) );
arena.alloc(material);
return material;
} }
} }

View file

@ -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::core::texture::FloatTexture;
use crate::shapes::mesh::BilinearPatchMeshHost; use crate::shapes::mesh::Mesh;
use crate::utils::{FileLoc, ParameterDictionary}; use crate::utils::{Arena, FileLoc, ParameterDictionary};
use shared::shapes::BilinearPatchShape; use shared::shapes::BilinearPatchShape;
use shared::utils::Transform; use shared::utils::Transform;
use std::collections::HashMap;
impl CreateShape for BilinearPatchShape { impl CreateMesh for BilinearPatchShape {
fn create( fn create(
render_from_object: &Transform, render_from_object: &Transform,
_object_from_render: &Transform, _object_from_render: &Transform,
@ -13,6 +14,7 @@ impl CreateShape for BilinearPatchShape {
parameters: &ParameterDictionary, parameters: &ParameterDictionary,
_float_textures: &HashMap<String, FloatTexture>, _float_textures: &HashMap<String, FloatTexture>,
_loc: &FileLoc, _loc: &FileLoc,
arena: &mut Arena,
) -> Result<Mesh, String> { ) -> Result<Mesh, String> {
let mut vertex_indices = parameters.get_int_array("indices"); let mut vertex_indices = parameters.get_int_array("indices");
let mut p = parameters.get_point3f_array("P"); let mut p = parameters.get_point3f_array("P");
@ -128,6 +130,7 @@ impl CreateShape for BilinearPatchShape {
rectangle: false, rectangle: false,
})); }));
} }
arena.alloc(shapes);
Ok(shapes) Ok(shapes)
} }
} }

View file

@ -194,6 +194,7 @@ impl CreateShape for CurveShape {
curves.extend(new_curves); curves.extend(new_curves);
} }
arena.alloc(curves);
Ok(curves) Ok(curves)
} }
} }

View file

@ -1,6 +1,6 @@
use crate::core::shape::CreateShape; use crate::core::shape::CreateShape;
use crate::core::texture::FloatTexture; use crate::core::texture::FloatTexture;
use crate::utils::{FileLoc, ParameterDictionary}; use crate::utils::{Arena, FileLoc, ParameterDictionary};
use shared::core::shape::Shape; use shared::core::shape::Shape;
use shared::shapes::CylinderShape; use shared::shapes::CylinderShape;
use shared::utils::Transform; use shared::utils::Transform;
@ -15,6 +15,7 @@ impl CreateShape for CylinderShape {
parameters: ParameterDictionary, parameters: ParameterDictionary,
float_textures: HashMap<String, FloatTexture>, float_textures: HashMap<String, FloatTexture>,
loc: FileLoc, loc: FileLoc,
arena: &mut Arena,
) -> Result<Vec<Shape>, String> { ) -> Result<Vec<Shape>, String> {
let radius = parameters.get_one_float("radius", 1.); let radius = parameters.get_one_float("radius", 1.);
let z_min = parameters.get_one_float("zmin", -1.); let z_min = parameters.get_one_float("zmin", -1.);
@ -30,6 +31,7 @@ impl CreateShape for CylinderShape {
phi_max, phi_max,
); );
arena.alloc(Shape::Cylinder(shape));
Ok(vec![Shape::Cylinder(shape)]) Ok(vec![Shape::Cylinder(shape)])
} }
} }

View file

@ -1,6 +1,6 @@
use crate::core::shape::CreateShape; use crate::core::shape::CreateShape;
use crate::core::texture::FloatTexture; use crate::core::texture::FloatTexture;
use crate::utils::{FileLoc, ParameterDictionary}; use crate::utils::{Arena, FileLoc, ParameterDictionary};
use shared::core::shape::Shape; use shared::core::shape::Shape;
use shared::shapes::DiskShape; use shared::shapes::DiskShape;
use shared::utils::Transform; use shared::utils::Transform;
@ -15,6 +15,7 @@ impl CreateShape for DiskShape {
parameters: ParameterDictionary, parameters: ParameterDictionary,
float_textures: HashMap<String, FloatTexture>, float_textures: HashMap<String, FloatTexture>,
loc: FileLoc, loc: FileLoc,
arena: &mut Arena,
) -> Result<Vec<Shape>, String> { ) -> Result<Vec<Shape>, String> {
let height = parameters.get_one_float("height", 0.); let height = parameters.get_one_float("height", 0.);
let radius = parameters.get_one_float("radius", 1.); let radius = parameters.get_one_float("radius", 1.);
@ -30,6 +31,7 @@ impl CreateShape for DiskShape {
reverse_orientation, reverse_orientation,
); );
arena.alloc(Shape::Disk(shape));
Ok(vec![Shape::Disk(shape)]) Ok(vec![Shape::Disk(shape)])
} }
} }

View file

@ -3,7 +3,7 @@ use ply_rs::parser::Parser;
use ply_rs::ply::{DefaultElement, Property}; use ply_rs::ply::{DefaultElement, Property};
use shared::utils::Transform; use shared::utils::Transform;
use shared::utils::mesh::{BilinearPatchMesh, TriangleMesh}; use shared::utils::mesh::{BilinearPatchMesh, TriangleMesh};
use shared::utils::sampling::PiecewiseConstant2D; use shared::utils::sampling::DevicePiecewiseConstant2D;
use std::collections::HashMap; use std::collections::HashMap;
use std::fs::File; use std::fs::File;
use std::path::Path; use std::path::Path;
@ -211,40 +211,32 @@ impl TriQuadMesh {
} }
} }
#[derive(Debug, Clone, Copy)] pub trait TriangleMeshFactory {
pub struct TriangleMeshStorage { fn create(
arena: &mut Arena,
render_from_object: &Transform,
reverse_orientation: bool,
vertex_indices: Vec<u32>, vertex_indices: Vec<u32>,
p: Vec<Point3f>, p: Vec<Point3f>,
n: Vec<Normal3f>, n: Vec<Normal3f>,
s: Vec<Vector3f>, s: Vec<Vector3f>,
uv: Vec<Point2f>, uv: Vec<Point2f>,
face_indices: Vec<u32>, face_indices: Vec<u32>,
) -> ArenaPtr<TriangleMesh>;
} }
#[derive(Debug, Clone, Copy)] impl TriangleMeshFactory for TriangleMesh {
pub struct TriangleMeshHost { fn create(
pub view: TriangleMesh, arena: &mut Arena,
_storage: Arc<TriangleMeshStorage>, render_from_object: &Transform,
}
impl Deref for TriangleMeshHost {
type Target = TriangleMesh;
fn deref(&self) -> &Self::Target {
&self.view
}
}
impl TriangleMeshHost {
pub fn new(
render_from_object: Transform,
reverse_orientation: bool, reverse_orientation: bool,
vertex_indices: Vec<usize>, vertex_indices: Vec<u32>,
mut p: Vec<Point3f>, p: Vec<Point3f>,
mut s: Vec<Vector3f>, n: Vec<Normal3f>,
mut n: Vec<Normal3f>, s: Vec<Vector3f>,
uv: Vec<Point2f>, uv: Vec<Point2f>,
face_indices: Vec<usize>, face_indices: Vec<u32>,
) -> Self { ) -> ArenaPtr<TriangleMesh> {
let n_triangles = indices.len() / 3; let n_triangles = indices.len() / 3;
let n_vertices = p.len(); let n_vertices = p.len();
for pt in p.iter_mut() { for pt in p.iter_mut() {
@ -342,7 +334,7 @@ pub struct BilinearMeshStorage {
p: Vec<Point3f>, p: Vec<Point3f>,
n: Vec<Normal3f>, n: Vec<Normal3f>,
uv: Vec<Point2f>, uv: Vec<Point2f>,
image_distribution: Option<PiecewiseConstant2D>, image_distribution: Option<DevicePiecewiseConstant2D>,
} }
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
@ -366,7 +358,7 @@ impl BilinearPatchMeshHost {
mut p: Vec<Point3f>, mut p: Vec<Point3f>,
mut n: Vec<Normal3f>, mut n: Vec<Normal3f>,
uv: Vec<Point2f>, uv: Vec<Point2f>,
image_distribution: Option<PiecewiseConstant2D>, image_distribution: Option<DevicePiecewiseConstant2D>,
) -> Self { ) -> Self {
let n_patches = indices.len() / 3; let n_patches = indices.len() / 3;
let n_vertices = p.len(); let n_vertices = p.len();

View file

@ -1,6 +1,6 @@
use crate::core::shape::CreateShape; use crate::core::shape::CreateShape;
use crate::core::texture::FloatTexture; use crate::core::texture::FloatTexture;
use crate::utils::{FileLoc, ParameterDictionary}; use crate::utils::{Arena, FileLoc, ParameterDictionary};
use shared::core::shape::Shape; use shared::core::shape::Shape;
use shared::shapes::SphereShape; use shared::shapes::SphereShape;
use shared::utils::Transform; use shared::utils::Transform;
@ -14,6 +14,7 @@ impl CreateShape for SphereShape {
parameters: ParameterDictionary, parameters: ParameterDictionary,
float_textures: HashMap<String, FloatTexture>, float_textures: HashMap<String, FloatTexture>,
loc: FileLoc, loc: FileLoc,
arena: &mut Arena,
) -> Result<Vec<Shape>, String> { ) -> Result<Vec<Shape>, String> {
let radius = parameters.get_one_float("radius", 1.); let radius = parameters.get_one_float("radius", 1.);
let zmin = parameters.get_one_float("zmin", -radius); let zmin = parameters.get_one_float("zmin", -radius);
@ -28,6 +29,7 @@ impl CreateShape for SphereShape {
zmax, zmax,
phimax, phimax,
); );
arena.alloc(vec![Shape::Sphere(SphereShape)]);
Ok(vec![Shape::Sphere(SphereShape)]) Ok(vec![Shape::Sphere(SphereShape)])
} }
} }

View file

@ -1,7 +1,7 @@
use crate::core::shape::{ALL_TRIANGLE_MESHES, CreateShape}; use crate::core::shape::{ALL_TRIANGLE_MESHES, CreateShape};
use crate::core::texture::FloatTexture; use crate::core::texture::FloatTexture;
use crate::shapes::mesh::TriangleMeshHost; use crate::shapes::mesh::TriangleMeshHost;
use crate::utils::{FileLoc, ParameterDictionary}; use crate::utils::{Arena, FileLoc, ParameterDictionary};
use shared::shapes::TriangleShape; use shared::shapes::TriangleShape;
use shared::utils::Transform; use shared::utils::Transform;
@ -12,6 +12,7 @@ impl CreateShape for TriangleShape {
reverse_orientation: bool, reverse_orientation: bool,
parameters: ParameterDictionary, parameters: ParameterDictionary,
loc: FileLoc, loc: FileLoc,
arena: &mut Arena,
) -> Result<Mesh, String> { ) -> Result<Mesh, String> {
let mut vertex_indices = parameters.get_int_array("indices"); let mut vertex_indices = parameters.get_int_array("indices");
let mut p = parameters.get_point3f_array("P"); let mut p = parameters.get_point3f_array("P");
@ -104,6 +105,8 @@ impl CreateShape for TriangleShape {
tri_index: i, tri_index: i,
})); }));
} }
arena.alloc(shapes);
Ok(shapes) Ok(shapes)
} }
} }

View file

@ -134,7 +134,7 @@ impl SpectrumTextureTrait for SpectrumImageTexture {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct FloatImageTexture { pub struct FloatImageTexture {
base: ImageTextureBase, pub base: ImageTextureBase,
} }
impl FloatImageTexture { impl FloatImageTexture {

View file

@ -1,16 +1,16 @@
use crate::core::texture::{ use crate::core::texture::{
FloatTexture, FloatTextureTrait, SpectrumTexture, SpectrumTextureTrait, FloatTexture, FloatTextureTrait, SpectrumTexture, SpectrumTextureTrait,
}; };
use crate::utils::{FileLoc, TextureParameterDictionary}; use crate::utils::{Arena, FileLoc, TextureParameterDictionary};
use shared::core::geometry::Vector3f; use shared::core::geometry::Vector3f;
use shared::utils::Transform; use shared::utils::Transform;
use std::sync::Arc; use std::sync::Arc;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct FloatMixTexture { pub struct FloatMixTexture {
tex1: Arc<FloatTexture>, pub tex1: Arc<FloatTexture>,
tex2: Arc<FloatTexture>, pub tex2: Arc<FloatTexture>,
amount: Arc<FloatTexture>, pub amount: Arc<FloatTexture>,
} }
impl FloatMixTexture { impl FloatMixTexture {
@ -26,11 +26,12 @@ impl FloatMixTexture {
_render_from_texture: &Transform, _render_from_texture: &Transform,
params: &TextureParameterDictionary, params: &TextureParameterDictionary,
_loc: &FileLoc, _loc: &FileLoc,
arena: &mut Arena,
) -> Self { ) -> Self {
let tex1 = params.get_float_texture("tex1", 0.); let tex1 = params.get_float_texture("tex1", 0.);
let tex2 = params.get_float_texture("tex2", 1.); let tex2 = params.get_float_texture("tex2", 1.);
let amount = params.get_float_texture("amount", 0.5); 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)] #[derive(Debug, Clone)]
pub struct FloatDirectionMixTexture { pub struct FloatDirectionMixTexture {
tex1: Arc<FloatTexture>, pub tex1: Arc<FloatTexture>,
tex2: Arc<FloatTexture>, pub tex2: Arc<FloatTexture>,
dir: Vector3f, pub dir: Vector3f,
} }
impl FloatDirectionMixTexture { impl FloatDirectionMixTexture {
@ -65,12 +66,13 @@ impl FloatDirectionMixTexture {
render_from_texture: &Transform, render_from_texture: &Transform,
params: &TextureParameterDictionary, params: &TextureParameterDictionary,
_loc: &FileLoc, _loc: &FileLoc,
arena: &mut Arena,
) -> Self { ) -> Self {
let dir_raw = params.get_one_vector3f("dir", Vector3f::new(0., 1., 0.)); 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 dir = render_from_texture.apply_to_vector(dir_raw).normalize();
let tex1 = params.get_float_texture("tex1", 0.); let tex1 = params.get_float_texture("tex1", 0.);
let tex2 = params.get_float_texture("tex2", 1.); let tex2 = params.get_float_texture("tex2", 1.);
Self::new(tex1, tex2, dir) arena.alloc(Self::new(tex1, tex2, dir))
} }
} }

View file

@ -1,4 +1,4 @@
use crate::utils::{FileLoc, TextureParameterDictionary}; use crate::utils::{Arena, FileLoc, TextureParameterDictionary};
use shared::core::texture::{SpectrumType, TextureEvalContext}; use shared::core::texture::{SpectrumType, TextureEvalContext};
use shared::spectra::ColorEncoding; use shared::spectra::ColorEncoding;
use shared::spectra::color::RGB; use shared::spectra::color::RGB;

View file

@ -1,15 +1,15 @@
use crate::core::texture::{ use crate::core::texture::{
FloatTexture, FloatTextureTrait, SpectrumTexture, SpectrumTextureTrait, FloatTexture, FloatTextureTrait, SpectrumTexture, SpectrumTextureTrait,
}; };
use crate::utils::{FileLoc, TextureParameterDictionary}; use crate::utils::{Arena, FileLoc, TextureParameterDictionary};
use shared::core::texture::TextureEvalContext; use shared::core::texture::TextureEvalContext;
use shared::spectra::{SampledSpectrum, SampledWavelengths}; use shared::spectra::{SampledSpectrum, SampledWavelengths};
use shared::utils::Transform; use shared::utils::Transform;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct FloatScaledTexture { pub struct FloatScaledTexture {
tex: Arc<FloatTexture>, pub tex: Arc<FloatTexture>,
scale: Arc<FloatTexture>, pub scale: Arc<FloatTexture>,
} }
impl FloatScaledTexture { impl FloatScaledTexture {
@ -21,6 +21,7 @@ impl FloatScaledTexture {
_render_from_texture: &Transform, _render_from_texture: &Transform,
params: &TextureParameterDictionary, params: &TextureParameterDictionary,
_loc: &FileLoc, _loc: &FileLoc,
arena: &mut Arena,
) -> FloatTexture { ) -> FloatTexture {
let mut tex = params.get_float_texture("tex", 1.); let mut tex = params.get_float_texture("tex", 1.);
let mut scale = params.get_float_texture("scale", 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);
} }
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)) FloatTexture::FloatScaled(FloatScaledTexture::new(tex, scale))
} }
} }
@ -56,8 +58,8 @@ impl FloatTextureTrait for FloatScaledTexture {
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct SpectrumScaledTexture { pub struct SpectrumScaledTexture {
tex: Arc<SpectrumTexture>, pub tex: Arc<SpectrumTexture>,
scale: Arc<FloatTexture>, pub scale: Arc<FloatTexture>,
} }
impl SpectrumTextureTrait for SpectrumScaledTexture { impl SpectrumTextureTrait for SpectrumScaledTexture {

View file

@ -1,6 +1,6 @@
use half::f16; use half::f16;
use shared::Float; use shared::Float;
use shared::utils::Ptr; use shared::utils::DevicePtr;
use shared::utils::math::{DigitPermutation, PRIMES}; use shared::utils::math::{DigitPermutation, PRIMES};
pub fn new_digit_permutation(base: u32, seed: u64) -> Vec<u16> { pub fn new_digit_permutation(base: u32, seed: u64) -> Vec<u16> {
@ -56,7 +56,7 @@ pub fn compute_radical_inverse_permutations(seed: u64) -> (Vec<u16>, Vec<DigitPe
views.push(DigitPermutation::new( views.push(DigitPermutation::new(
base as u32, base as u32,
n_digits, n_digits,
Ptr(ptr_to_data), DevicePtr(ptr_to_data),
)); ));
} }

View file

@ -1,3 +1,4 @@
pub mod arena;
pub mod containers; pub mod containers;
pub mod error; pub mod error;
pub mod file; pub mod file;
@ -9,6 +10,7 @@ pub mod parameters;
pub mod parser; pub mod parser;
pub mod sampling; pub mod sampling;
pub use arena::{Arena, Upload};
pub use error::FileLoc; pub use error::FileLoc;
pub use file::{read_float_file, resolve_filename}; pub use file::{read_float_file, resolve_filename};
pub use parameters::{ pub use parameters::{

View file

@ -1,30 +1,39 @@
use shared::Float; use shared::Float;
use shared::core::geometry::{Bounds2f, Point2f}; use shared::core::geometry::{Bounds2f, Point2f};
use shared::utils::Ptr; use shared::utils::DevicePtr;
use shared::utils::sampling::{ use shared::utils::sampling::{
AliasTable, PiecewiseConstant1D, PiecewiseConstant2D, PiecewiseLinear2D, AliasTable, DevicePiecewiseConstant1D, DevicePiecewiseConstant2D, PiecewiseLinear2D,
}; };
use std::sync::Arc; use std::sync::Arc;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct PiecewiseConstant1DHost { pub struct PiecewiseConstant1D {
pub view: PiecewiseConstant1D, pub func: Vec<Float>,
_func: Vec<Float>, pub cdf: Vec<Float>,
_cdf: Vec<Float>, pub func_integral: Float,
pub min: Float,
pub max: Float,
} }
impl std::ops::Deref for PiecewiseConstant1DHost { impl PiecewiseConstant1D {
type Target = PiecewiseConstant1D;
fn deref(&self) -> &Self::Target {
&self.view
}
}
impl PiecewiseConstant1DHost {
pub fn new(f: &[Float]) -> Self { pub fn new(f: &[Float]) -> Self {
Self::new_with_bounds(f, 0.0, 1.0) 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 { pub fn new_with_bounds(f: &[Float], min: Float, max: Float) -> Self {
let n = f.len(); let n = f.len();
@ -47,44 +56,31 @@ impl PiecewiseConstant1DHost {
} }
} }
let view = PiecewiseConstant1D { Self {
func: Ptr(func_vec.as_ptr()), func: func_vec,
cdf: Ptr(cdf_vec.as_ptr()), cdf: cdf_vec,
func_integral,
min, min,
max, max,
n: n as u32,
func_integral,
};
Self {
view,
_func: func_vec,
_cdf: cdf_vec,
} }
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct PiecewiseConstant2DHost { pub struct PiecewiseConstant2D {
pub view: PiecewiseConstant2D, pub domain: Bounds2f,
_p_conditional_v: Vec<PiecewiseConstant1D>, pub p_marginal: PiecewiseConstant1D,
pub p_conditionals: Vec<PiecewiseConstant1D>,
} }
impl std::ops::Deref for PiecewiseConstant2DHost { impl PiecewiseConstant2D {
type Target = PiecewiseConstant2D;
fn deref(&self) -> &Self::Target {
&self.view
}
}
impl PiecewiseConstant2DHost {
pub fn new(data: &Array2D<Float>, x_size: u32, y_size: u32, domain: Bounds2f) -> Self { pub fn new(data: &Array2D<Float>, x_size: u32, y_size: u32, domain: Bounds2f) -> Self {
let nu = x_size as usize; let nu = x_size as usize;
let nv = y_size as usize; let nv = y_size as usize;
let mut conditionals = Vec::with_capacity(nv); let mut conditionals = Vec::with_capacity(nv);
for v in 0..nv { for v in 0..nv {
let row = unsafe { core::slice::from_raw_parts(data.values.add(v * nu), nu) }; 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, row,
domain.p_min.x(), domain.p_min.x(),
domain.p_max.x(), domain.p_max.x(),
@ -92,24 +88,16 @@ impl PiecewiseConstant2DHost {
} }
let marginal_funcs: Vec<Float> = conditionals.iter().map(|c| c.func_integral).collect(); let marginal_funcs: Vec<Float> = conditionals.iter().map(|c| c.func_integral).collect();
let p_marginal = PiecewiseConstant1D::new_with_bounds( let p_marginal = DevicePiecewiseConstant1D::new_with_bounds(
&marginal_funcs, &marginal_funcs,
domain.p_min.y(), domain.p_min.y(),
domain.p_max.y(), domain.p_max.y(),
); );
let p_conditional_v = conditionals.as_mut_ptr(); Self {
std::mem::forget(conditionals);
let view = PiecewiseConstant2D {
domain, domain,
p_marginal, p_marginal,
n_conditionals: nv, p_conditionals: conditionals,
p_conditional_v: Ptr(p_conditional_v),
};
Self {
view,
_p_conditional_v: p_conditional_v,
} }
} }