Compare commits

..

1 commit

Author SHA1 Message Date
599683eaad More fixes to allow for spirv compilation 2026-02-20 21:10:36 +00:00
20 changed files with 127 additions and 163 deletions

View file

@ -2,6 +2,7 @@
use spirv_std::spirv; use spirv_std::spirv;
/// Core logic — testable on CPU
pub fn scale_kernel_logic(idx: usize, input: &[f32], output: &mut [f32], scale: f32) { pub fn scale_kernel_logic(idx: usize, input: &[f32], output: &mut [f32], scale: f32) {
if idx < input.len() { if idx < input.len() {
output[idx] = input[idx] * scale; output[idx] = input[idx] * scale;

View file

@ -5,5 +5,5 @@ mod spherical;
pub use orthographic::OrthographicCamera; pub use orthographic::OrthographicCamera;
pub use perspective::PerspectiveCamera; pub use perspective::PerspectiveCamera;
pub use realistic::{EXIT_PUPIL_SAMPLES, LensElementInterface, RealisticCamera}; pub use realistic::RealisticCamera;
pub use spherical::{Mapping, SphericalCamera}; pub use spherical::{Mapping, SphericalCamera};

View file

@ -31,7 +31,7 @@ pub struct ExitPupilSample {
pub pdf: Float, pub pdf: Float,
} }
pub const EXIT_PUPIL_SAMPLES: usize = 64; const EXIT_PUPIL_SAMPLES: usize = 64;
#[repr(C)] #[repr(C)]
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
@ -107,7 +107,7 @@ impl RealisticCamera {
Self::compute_exit_pupil_bounds(interface_array, film_x_0, film_x_1) Self::compute_exit_pupil_bounds(interface_array, film_x_0, film_x_1)
} }
pub fn compute_exit_pupil_bounds( fn compute_exit_pupil_bounds(
elements: &[LensElementInterface], elements: &[LensElementInterface],
film_x_0: Float, film_x_0: Float,
film_x_1: Float, film_x_1: Float,

View file

@ -344,7 +344,7 @@ impl SurfaceInteraction {
} }
} }
pub fn compute_bump_geom( fn compute_bump_geom(
&mut self, &mut self,
tex_eval: &UniversalTextureEvaluator, tex_eval: &UniversalTextureEvaluator,
displacement: Ptr<GPUFloatTexture>, displacement: Ptr<GPUFloatTexture>,

View file

@ -94,7 +94,7 @@ impl AtomicFloat {
} }
/// Atomically adds `val` to the current value. /// Atomically adds `val` to the current value.
/// Compare-And-Swap loop. /// Uses a Compare-And-Swap (CAS) loop.
pub fn add(&self, val: f32) { pub fn add(&self, val: f32) {
let mut current_bits = self.bits.load(Ordering::Relaxed); let mut current_bits = self.bits.load(Ordering::Relaxed);
loop { loop {
@ -128,3 +128,38 @@ pub fn gpu_array_from_fn<T, const N: usize>(mut f: impl FnMut(usize) -> T) -> [T
arr.assume_init() arr.assume_init()
} }
} }
// pub struct AtomicDouble {
// bits: AtomicU64,
// }
//
// impl AtomicDouble {
// pub fn new(val: f64) -> Self {
// Self {
// bits: AtomicU64::new(val.to_bits()),
// }
// }
//
// pub fn get(&self) -> f64 {
// f64::from_bits(self.bits.load(Ordering::Relaxed))
// }
//
// pub fn add(&self, val: f64) {
// let mut current_bits = self.bits.load(Ordering::Relaxed);
// loop {
// let current_val = f64::from_bits(current_bits);
// let new_val = current_val + val;
// let new_bits = new_val.to_bits();
//
// match self.bits.compare_exchange_weak(
// current_bits,
// new_bits,
// Ordering::Relaxed,
// Ordering::Relaxed,
// ) {
// Ok(_) => break,
// Err(x) => current_bits = x,
// }
// }
// }
// }

View file

@ -1,3 +1,3 @@
pub mod perspective; pub mod perspective;
pub mod realistic; pub mod realistic;
pub mod spherical; pub mod sherical;

View file

@ -1,28 +1,17 @@
use crate::core::image::Image; use ash::vk::Image;
use shared::cameras::{EXIT_PUPIL_SAMPLES, LensElementInterface, RealisticCamera}; use shared::cameras::{Mapping, RealisticCamera, realistic::LensElementInterface};
use shared::core::camera::CameraBase;
use shared::core::geometry::{Bounds2f, Point2f};
use shared::utils::math::square;
use shared::{Float, Ptr};
use std::sync::Arc;
#[derive(Clone)]
struct RealisticCameraData { struct RealisticCameraData {
aperture_image: Arc<Image>, aperture_image: Arc<Image>,
element_interfaces: Vec<LensElementInterface>, element_interfaces: Vec<LensElementInterface>,
} }
#[derive(Clone)]
pub struct RealisticCameraHost { pub struct RealisticCameraHost {
device: RealisticCamera, device: RealisticCamera,
data: RealisticCameraData, data: RealisticCameraData,
} }
impl RealisticCameraHost { impl RealisticCameraHost {
pub fn device(&self) -> RealisticCamera {
self.device
}
pub fn new( pub fn new(
base: CameraBase, base: CameraBase,
lens_params: &[Float], lens_params: &[Float],
@ -42,7 +31,7 @@ impl RealisticCameraHost {
let y = x * aspect; let y = x * aspect;
let physical_extent = let physical_extent =
Bounds2f::from_points(Point2f::new(-x / 2., -y / 2.), Point2f::new(x / 2., y / 2.)); Bounds2f::from_points(Point2f::new(-x / 2., -y / 2.), Point2f::new(x / 2., y / 2.));
let mut element_interfaces: Vec<LensElementInterface> = Vec::new(); let mut element_interface: Vec<LensElementInterface> = Vec::new();
for i in (0..lens_params.len()).step_by(4) { for i in (0..lens_params.len()).step_by(4) {
let curvature_radius = lens_params[i] / 1000.0; let curvature_radius = lens_params[i] / 1000.0;
@ -64,7 +53,7 @@ impl RealisticCameraHost {
eta, eta,
aperture_radius: aperture_diameter / 2.0, aperture_radius: aperture_diameter / 2.0,
}; };
element_interfaces.push(el_int); element_interface.push(el_int);
} }
let half_diag = film.diagonal() / 2.0; let half_diag = film.diagonal() / 2.0;
@ -73,25 +62,26 @@ impl RealisticCameraHost {
for i in 0..EXIT_PUPIL_SAMPLES { for i in 0..EXIT_PUPIL_SAMPLES {
let r0 = (i as Float / EXIT_PUPIL_SAMPLES as Float) * half_diag; let r0 = (i as Float / EXIT_PUPIL_SAMPLES as Float) * half_diag;
let r1 = ((i + 1) as Float / EXIT_PUPIL_SAMPLES as Float) * half_diag; let r1 = ((i + 1) as Float / EXIT_PUPIL_SAMPLES as Float) * half_diag;
exit_pupil_bounds[i] = exit_pupil_bounds[i] = Self::compute_exit_pupil_bounds(&element_interface, r0, r1);
RealisticCamera::compute_exit_pupil_bounds(&element_interfaces, r0, r1);
} }
let n_elements = element_interfaces.len(); let n_elements = element_interface.len();
let element_interfaces = element_interface.as_ptr();
std::mem::forget(element_interface);
let data = RealisticCameraData { let data = RealisticCameraData {
element_interfaces: element_interfaces.clone(), element_interfaces,
aperture_image: aperture_image.clone(), aperture_image,
}; };
let device = RealisticCamera { let device = RealisticCamera {
base, base,
focus_distance, focus_distance,
element_interfaces: Ptr::from(element_interfaces.as_ptr()), element_interfaces: Ptr::from(element_interfaces),
n_elements, n_elements,
physical_extent, physical_extent,
set_aperture_diameter, set_aperture_diameter,
aperture_image: Ptr::from(aperture_image.device()), aperture_image,
exit_pupil_bounds, exit_pupil_bounds,
}; };

View file

@ -1,7 +1,5 @@
use crate::cameras::realistic::RealisticCameraHost;
use crate::core::image::ImageMetadata; use crate::core::image::ImageMetadata;
use crate::core::image::{Image, ImageIO}; use crate::core::image::{Image, ImageIO};
use crate::globals::get_options;
use crate::utils::{Arena, FileLoc, ParameterDictionary}; use crate::utils::{Arena, FileLoc, ParameterDictionary};
use crate::utils::{Upload, read_float_file}; use crate::utils::{Upload, read_float_file};
use anyhow::{Result, anyhow}; use anyhow::{Result, anyhow};
@ -13,6 +11,7 @@ use shared::core::film::Film;
use shared::core::geometry::{Bounds2f, Point2f, Point2i, Vector2f, Vector3f}; use shared::core::geometry::{Bounds2f, Point2f, Point2i, Vector2f, Vector3f};
use shared::core::image::PixelFormat; use shared::core::image::PixelFormat;
use shared::core::medium::Medium; use shared::core::medium::Medium;
use shared::core::options::get_options;
use shared::utils::math::square; use shared::utils::math::square;
use shared::{Float, PI}; use shared::{Float, PI};
use std::path::Path; use std::path::Path;
@ -377,16 +376,16 @@ impl CameraFactory for Camera {
} }
} }
let camera = RealisticCameraHost::new( let camera = RealisticCamera::new(
base, base,
&lens_params, &lens_params,
focal_distance, focal_distance,
aperture_diameter, aperture_diameter,
Arc::from(aperture_image.unwrap()), aperture_image.upload(arena),
); );
// arena.alloc(camera); arena.alloc(camera);
Ok(Camera::Realistic(camera.device())) Ok(Camera::Realistic(camera))
} }
"spherical" => { "spherical" => {
let full_res = film.full_resolution(); let full_res = film.full_resolution();

View file

@ -3,7 +3,6 @@ use anyhow::{Result, anyhow};
use half::f16; use half::f16;
use rayon::prelude::{IndexedParallelIterator, ParallelIterator, ParallelSliceMut}; use rayon::prelude::{IndexedParallelIterator, ParallelIterator, ParallelSliceMut};
use shared::Float; use shared::Float;
use shared::Ptr;
use shared::core::color::{ColorEncoding, ColorEncodingTrait, LINEAR}; use shared::core::color::{ColorEncoding, ColorEncodingTrait, LINEAR};
use shared::core::geometry::{Bounds2f, Point2f, Point2i}; use shared::core::geometry::{Bounds2f, Point2f, Point2i};
use shared::core::image::{DeviceImage, ImageBase, PixelFormat, Pixels, WrapMode, WrapMode2D}; use shared::core::image::{DeviceImage, ImageBase, PixelFormat, Pixels, WrapMode, WrapMode2D};
@ -78,9 +77,9 @@ pub enum PixelStorage {
impl PixelStorage { impl PixelStorage {
pub fn as_pixels(&self) -> Pixels { pub fn as_pixels(&self) -> Pixels {
match self { match self {
PixelStorage::U8(vec) => Pixels::new_u8(Ptr::from_raw(vec.as_ptr())), PixelStorage::U8(data) => Pixels::U8(data.as_ptr().into()),
PixelStorage::F16(vec) => Pixels::new_f16(Ptr::from_raw(vec.as_ptr() as *const u16)), PixelStorage::F16(data) => Pixels::F16((data.as_ptr() as *const f16).into()),
PixelStorage::F32(vec) => Pixels::new_f32(Ptr::from_raw(vec.as_ptr())), PixelStorage::F32(data) => Pixels::F32(data.as_ptr().into()),
} }
} }
@ -566,9 +565,9 @@ impl Image {
pub fn update_view_pointers(&mut self) { pub fn update_view_pointers(&mut self) {
self.device.pixels = match &self.pixels { self.device.pixels = match &self.pixels {
PixelStorage::U8(vec) => Pixels::new_u8(Ptr::from_raw(vec.as_ptr())), PixelStorage::U8(vec) => Pixels::U8(vec.as_ptr().into()),
PixelStorage::F16(vec) => Pixels::new_f16(Ptr::from_raw(vec.as_ptr() as *const u16)), PixelStorage::F16(vec) => Pixels::F16((vec.as_ptr() as *const f16).into()),
PixelStorage::F32(vec) => Pixels::new_f32(Ptr::from_raw(vec.as_ptr())), PixelStorage::F32(vec) => Pixels::F32(vec.as_ptr().into()),
}; };
} }

View file

@ -1,35 +1,9 @@
use crate::globals::get_options; use crate::globals::get_options;
use shared::Ptr; use shared::core::interaction::{
use shared::bxdfs::DiffuseBxDF; InteractionBase, InteractionTrait, MediumInteraction, SimpleInteraction, SurfaceInteraction,
use shared::core::bsdf::BSDF; };
use shared::core::bssrdf::BSSRDF;
use shared::core::bxdf::BxDF;
use shared::core::camera::Camera;
use shared::core::geometry::Ray;
use shared::core::interaction::{MediumInteraction, SimpleInteraction, SurfaceInteraction};
use shared::core::material::{Material, MaterialEvalContext, MaterialTrait};
use shared::core::sampler::{Sampler, SamplerTrait};
use shared::core::texture::UniversalTextureEvaluator;
use shared::spectra::SampledWavelengths;
pub trait InteractionGetter { pub trait InteractionGetter {
fn get_bsdf(
&mut self,
r: &Ray,
lambda: &SampledWavelengths,
camera: &Camera,
sampler: &mut Sampler,
) -> Option<BSDF>;
fn get_bssrdf(
&self,
_ray: &Ray,
lambda: &SampledWavelengths,
_camera: &Camera,
) -> Option<BSSRDF>;
}
impl InteractionGetter for SurfaceInteraction {
fn get_bsdf( fn get_bsdf(
&mut self, &mut self,
r: &Ray, r: &Ray,
@ -38,29 +12,32 @@ impl InteractionGetter for SurfaceInteraction {
sampler: &mut Sampler, sampler: &mut Sampler,
) -> Option<BSDF> { ) -> Option<BSDF> {
self.compute_differentials(r, camera, sampler.samples_per_pixel() as i32); self.compute_differentials(r, camera, sampler.samples_per_pixel() as i32);
let material = { let material = {
let mut active_mat = unsafe { self.material.as_ref() }; let root_mat = self.material;
let mut active_mat: &Material = &*root_mat;
let tex_eval = UniversalTextureEvaluator; let tex_eval = UniversalTextureEvaluator;
while let Material::Mix(mix) = active_mat { while let Material::Mix(mix) = active_mat {
// We need a context to evaluate the 'amount' texture
let ctx = MaterialEvalContext::from(&*self); let ctx = MaterialEvalContext::from(&*self);
active_mat = mix.choose_material(&tex_eval, &ctx)?; active_mat = mix.choose_material(&tex_eval, &ctx)?;
} }
active_mat.clone() active_mat.clone()
}; };
let ctx = MaterialEvalContext::from(&*self); let ctx = MaterialEvalContext::from(&*self);
let tex_eval = UniversalTextureEvaluator; let tex_eval = UniversalTextureEvaluator;
let displacement = material.get_displacement(); let displacement = material.get_displacement();
let normal_map = material let normal_map = Ptr::from(material.get_normal_map().unwrap());
.get_normal_map()
.map(Ptr::from)
.unwrap_or(Ptr::null());
if !displacement.is_null() || !normal_map.is_null() { if !displacement.is_null() || !normal_map.is_null() {
// This calls the function defined above
self.compute_bump_geom(&tex_eval, displacement, normal_map); self.compute_bump_geom(&tex_eval, displacement, normal_map);
} }
let mut bsdf = material.get_bsdf(&tex_eval, &ctx, lambda); let mut bsdf = material.get_bsdf(&tex_eval, &ctx, lambda);
if get_options().force_diffuse { if get_options().force_diffuse {
let rho = bsdf.rho_wo(self.common.wo, &[sampler.get1d()], &[sampler.get2d()]); let r = bsdf.rho_wo(self.common.wo, &[sampler.get1d()], &[sampler.get2d()]);
let diff_bxdf = BxDF::Diffuse(DiffuseBxDF::new(rho)); let diff_bxdf = BxDF::Diffuse(DiffuseBxDF::new(r));
bsdf = BSDF::new(self.shading.n, self.shading.dpdu, Ptr::from(&diff_bxdf)); bsdf = BSDF::new(self.shading.n, self.shading.dpdu, Ptr::from(&diff_bxdf));
} }
Some(bsdf) Some(bsdf)
@ -72,56 +49,23 @@ impl InteractionGetter for SurfaceInteraction {
lambda: &SampledWavelengths, lambda: &SampledWavelengths,
_camera: &Camera, _camera: &Camera,
) -> Option<BSSRDF> { ) -> Option<BSSRDF> {
let mut active_mat = unsafe { self.material.as_ref() }; let material = {
let tex_eval = UniversalTextureEvaluator; let mut active_mat = unsafe { self.material.as_ref() };
while let Material::Mix(mix) = active_mat { let tex_eval = UniversalTextureEvaluator;
let ctx = MaterialEvalContext::from(self); while let Material::Mix(mix) = active_mat {
active_mat = mix.choose_material(&tex_eval, &ctx)?; // We need a context to evaluate the 'amount' texture
} let ctx = MaterialEvalContext::from(self);
let material = active_mat.clone(); active_mat = mix.choose_material(&tex_eval, &ctx)?;
}
active_mat.clone()
};
let ctx = MaterialEvalContext::from(self); let ctx = MaterialEvalContext::from(self);
let tex_eval = UniversalTextureEvaluator;
material.get_bssrdf(&tex_eval, &ctx, lambda) material.get_bssrdf(&tex_eval, &ctx, lambda)
} }
} }
impl InteractionGetter for MediumInteraction { impl InteractionGetter for SurfaceInteraction {}
fn get_bsdf( impl InteractionGetter for MediumInteraction {}
&mut self, impl InteractionGetter for SimpleInteraction {}
_r: &Ray,
_lambda: &SampledWavelengths,
_camera: &Camera,
_sampler: &mut Sampler,
) -> Option<BSDF> {
None
}
fn get_bssrdf(
&self,
_ray: &Ray,
_lambda: &SampledWavelengths,
_camera: &Camera,
) -> Option<BSSRDF> {
None
}
}
impl InteractionGetter for SimpleInteraction {
fn get_bsdf(
&mut self,
_r: &Ray,
_lambda: &SampledWavelengths,
_camera: &Camera,
_sampler: &mut Sampler,
) -> Option<BSDF> {
None
}
fn get_bssrdf(
&self,
_ray: &Ray,
_lambda: &SampledWavelengths,
_camera: &Camera,
) -> Option<BSSRDF> {
None
}
}

View file

@ -9,8 +9,8 @@ use crate::utils::parser::{ParserError, ParserTarget};
use shared::Float; use shared::Float;
use shared::core::camera::CameraTransform; use shared::core::camera::CameraTransform;
use shared::core::geometry::Vector3f; use shared::core::geometry::Vector3f;
use shared::core::options::RenderingCoordinateSystem;
use shared::spectra::RGBColorSpace; use shared::spectra::RGBColorSpace;
use shared::utils::options::RenderingCoordinateSystem;
use shared::utils::transform; use shared::utils::transform;
use shared::utils::transform::{AnimatedTransform, Transform}; use shared::utils::transform::{AnimatedTransform, Transform};
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
@ -215,10 +215,10 @@ impl ParserTarget for BasicSceneBuilder {
fn color_space(&mut self, name: &str, loc: FileLoc) -> Result<(), ParserError> { fn color_space(&mut self, name: &str, loc: FileLoc) -> Result<(), ParserError> {
let stdcs = get_colorspace_device(); let stdcs = get_colorspace_device();
let _ = match stdcs.get_named(name) { let _ = match stdcs.get_named(name) {
Some(cs) => { Ok(cs) => {
self.graphics_state.color_space = unsafe { Some(Arc::new(*cs.as_ref())) }; self.graphics_state.color_space = unsafe { Some(Arc::new(*cs.as_ref())) };
} }
None => { Err(_) => {
eprintln!("Error: Color space '{}' unknown at {}", name, loc); eprintln!("Error: Color space '{}' unknown at {}", name, loc);
} }
}; };
@ -276,11 +276,11 @@ impl ParserTarget for BasicSceneBuilder {
) -> Result<(), ParserError> { ) -> Result<(), ParserError> {
let result = transform::look_at((ex, ey, ez), (lx, ly, lz), (ux, uy, uz)); let result = transform::look_at((ex, ey, ez), (lx, ly, lz), (ux, uy, uz));
match result { match result {
Some(t) => { Ok(t) => {
self.for_active_transforms(|cur| cur * &t); self.for_active_transforms(|cur| cur * &t);
} }
None => { Err(e) => {
eprintln!("Error: Could not invert transform at {}", loc); eprintln!("Error: {} at {}", e, loc);
} }
} }
Ok(()) Ok(())
@ -289,11 +289,11 @@ impl ParserTarget for BasicSceneBuilder {
fn concat_transform(&mut self, m: &[Float; 16], loc: FileLoc) -> Result<(), ParserError> { fn concat_transform(&mut self, m: &[Float; 16], loc: FileLoc) -> Result<(), ParserError> {
let result = Transform::from_flat(m); let result = Transform::from_flat(m);
match result { match result {
Some(t) => { Ok(t) => {
self.for_active_transforms(|cur| cur * &t); self.for_active_transforms(|cur| cur * &t);
} }
None => { Err(e) => {
eprintln!("Error: Could not invert transform at {}", loc); eprintln!("Error: {} at {}", e, loc);
} }
} }
Ok(()) Ok(())
@ -302,11 +302,11 @@ impl ParserTarget for BasicSceneBuilder {
fn transform(&mut self, m: &[Float; 16], loc: FileLoc) -> Result<(), ParserError> { fn transform(&mut self, m: &[Float; 16], loc: FileLoc) -> Result<(), ParserError> {
let result = Transform::from_flat(m); let result = Transform::from_flat(m);
match result { match result {
Some(t) => { Ok(t) => {
self.for_active_transforms(|_| t); self.for_active_transforms(|_| t);
} }
None => { Err(e) => {
eprintln!("Error: Could not invert transform at {}", loc); eprintln!("Error: {} at {}", e, loc);
} }
} }
Ok(()) Ok(())

View file

@ -1,10 +1,9 @@
use crate::core::filter::CreateFilterSampler; use crate::core::filter::CreateFilterSampler;
use rand::Rng;
use shared::Float; use shared::Float;
use shared::core::filter::FilterSampler; use shared::core::filter::FilterSampler;
use shared::core::geometry::{Point2f, Vector2f}; use shared::core::geometry::{Point2f, Vector2f};
use shared::filters::LanczosSincFilter; use shared::filters::LanczosSincFilter;
use shared::utils::math::{lerp, windowed_sinc}; use shared::utils::math::windowed_sinc;
pub trait LanczosFilterCreator { pub trait LanczosFilterCreator {
fn new(radius: Vector2f, tau: Float) -> Self; fn new(radius: Vector2f, tau: Float) -> Self;
@ -12,14 +11,13 @@ pub trait LanczosFilterCreator {
impl LanczosFilterCreator for LanczosSincFilter { impl LanczosFilterCreator for LanczosSincFilter {
fn new(radius: Vector2f, tau: Float) -> Self { fn new(radius: Vector2f, tau: Float) -> Self {
let evaluate = |p: Point2f| -> Float { let sampler = FilterSampler::new(radius, move |p: Point2f| {
windowed_sinc(p.x(), radius.x(), tau) * windowed_sinc(p.y(), radius.y(), tau) windowed_sinc(p.x(), radius.x(), tau) * windowed_sinc(p.y(), radius.y(), tau)
}; });
let sampler = FilterSampler::new(radius, evaluate);
let sqrt_samples = 64; let sqrt_samples = 64;
let n_samples = sqrt_samples * sqrt_samples; let n_samples = sqrt_samples * sqrt_samples;
let area = (2.0 * radius.x()) * (2.0 * radius.y()); let area = (2.0 * self.radius.x()) * (2.0 * self.radius.y());
let mut sum = 0.0; let mut sum = 0.0;
let mut rng = rand::rng(); let mut rng = rand::rng();
@ -30,10 +28,10 @@ impl LanczosFilterCreator for LanczosSincFilter {
(y as Float + rng.random::<Float>()) / sqrt_samples as Float, (y as Float + rng.random::<Float>()) / sqrt_samples as Float,
); );
let p = Point2f::new( let p = Point2f::new(
lerp(u.x(), -radius.x(), radius.x()), lerp(u.x(), -self.radius.x(), self.radius.x()),
lerp(u.y(), -radius.y(), radius.y()), lerp(u.y(), -self.radius.y(), self.radius.y()),
); );
sum += evaluate(p); sum += self.evaluate(p);
} }
} }
let integral = sum / n_samples as Float * area; let integral = sum / n_samples as Float * area;

View file

@ -1,10 +1,9 @@
use super::RayIntegratorTrait;
use super::base::IntegratorBase; use super::base::IntegratorBase;
use super::constants::*; use super::constants::*;
use super::state::PathState; use super::state::PathState;
use super::RayIntegratorTrait;
use crate::core::interaction::InteractionGetter;
use crate::Arena; use crate::Arena;
use shared::core::bsdf::{BSDFSample, BSDF}; use shared::core::bsdf::{BSDF, BSDFSample};
use shared::core::bxdf::{BxDFFlags, FArgs, TransportMode}; use shared::core::bxdf::{BxDFFlags, FArgs, TransportMode};
use shared::core::camera::Camera; use shared::core::camera::Camera;
use shared::core::film::VisibleSurface; use shared::core::film::VisibleSurface;

View file

@ -4,13 +4,13 @@ use crate::Arena;
use crate::core::camera::InitMetadata; use crate::core::camera::InitMetadata;
use crate::core::film::FilmTrait; use crate::core::film::FilmTrait;
use crate::core::image::{Image, ImageIO, ImageMetadata}; use crate::core::image::{Image, ImageIO, ImageMetadata};
use crate::globals::get_options;
use crate::spectra::get_spectra_context; use crate::spectra::get_spectra_context;
use indicatif::{ProgressBar, ProgressStyle}; use indicatif::{ProgressBar, ProgressStyle};
use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use shared::Float; use shared::Float;
use shared::core::camera::{Camera, CameraTrait}; use shared::core::camera::{Camera, CameraTrait};
use shared::core::geometry::{Bounds2i, Point2i, VectorLike}; use shared::core::geometry::{Bounds2i, Point2i, VectorLike};
use shared::core::options::get_options;
use shared::core::sampler::get_camera_sample; use shared::core::sampler::get_camera_sample;
use shared::core::sampler::{Sampler, SamplerTrait}; use shared::core::sampler::{Sampler, SamplerTrait};
use shared::spectra::SampledSpectrum; use shared::spectra::SampledSpectrum;
@ -199,9 +199,11 @@ pub fn render<T>(
camera.init_metadata(&mut metadata); camera.init_metadata(&mut metadata);
if let Some(out_path) = &options.mse_reference_output { if let Some(out_path) = &options.mse_reference_output {
camera camera.get_film().write_image(
.get_film() &metadata,
.write_image(&metadata, 1.0 / wave_start as Float, out_path); 1.0 / wave_start as Float,
out_path.as_str(),
);
} }
} }

View file

@ -1,7 +1,6 @@
use crate::core::image::Image; use crate::core::image::Image;
use crate::core::material::CreateMaterial; use crate::core::material::CreateMaterial;
use crate::core::texture::SpectrumTexture; use crate::core::texture::SpectrumTexture;
use crate::globals::get_options;
use crate::spectra::data::get_named_spectrum; use crate::spectra::data::get_named_spectrum;
use crate::utils::{Arena, FileLoc, TextureParameterDictionary, Upload}; use crate::utils::{Arena, FileLoc, TextureParameterDictionary, Upload};
use anyhow::{Result, bail}; use anyhow::{Result, bail};
@ -67,7 +66,6 @@ impl CreateMaterial for CoatedDiffuseMaterial {
remap_roughness, remap_roughness,
max_depth as u32, max_depth as u32,
n_samples as u32, n_samples as u32,
get_options().seed,
); );
Ok(Material::CoatedDiffuse(specific)) Ok(Material::CoatedDiffuse(specific))
@ -169,7 +167,6 @@ impl CreateMaterial for CoatedConductorMaterial {
max_depth as u32, max_depth as u32,
n_samples as u32, n_samples as u32,
remap_roughness, remap_roughness,
get_options().seed,
); );
arena.alloc(material); arena.alloc(material);
Ok(Material::CoatedConductor(material)) Ok(Material::CoatedConductor(material))

View file

@ -1,8 +1,8 @@
use super::*; use super::*;
use crate::globals::get_options;
use crate::utils::math::compute_radical_inverse_permutations; use crate::utils::math::compute_radical_inverse_permutations;
use anyhow::{Result, anyhow}; use anyhow::{Result, anyhow};
use shared::core::geometry::Point2i; use shared::core::geometry::Point2i;
use shared::core::options::get_options;
use shared::core::sampler::{HaltonSampler, MAX_HALTON_RESOLUTION, RandomizeStrategy}; use shared::core::sampler::{HaltonSampler, MAX_HALTON_RESOLUTION, RandomizeStrategy};
pub trait CreateHaltonSampler { pub trait CreateHaltonSampler {

View file

@ -1,6 +1,6 @@
use super::*; use super::*;
use crate::globals::get_options;
use anyhow::Result; use anyhow::Result;
use shared::core::options::get_options;
use shared::core::sampler::IndependentSampler; use shared::core::sampler::IndependentSampler;
impl CreateSampler for IndependentSampler { impl CreateSampler for IndependentSampler {

View file

@ -1,7 +1,7 @@
use super::*; use super::*;
use crate::globals::get_options;
use anyhow::{Result, anyhow}; use anyhow::{Result, anyhow};
use shared::core::geometry::Point2i; use shared::core::geometry::Point2i;
use shared::core::options::get_options;
use shared::core::sampler::{PaddedSobolSampler, RandomizeStrategy, SobolSampler, ZSobolSampler}; use shared::core::sampler::{PaddedSobolSampler, RandomizeStrategy, SobolSampler, ZSobolSampler};
impl CreateSampler for SobolSampler { impl CreateSampler for SobolSampler {

View file

@ -1,6 +1,6 @@
use super::*; use super::*;
use crate::globals::get_options;
use anyhow::Result; use anyhow::Result;
use shared::core::options::get_options;
use shared::core::sampler::StratifiedSampler; use shared::core::sampler::StratifiedSampler;
impl CreateSampler for StratifiedSampler { impl CreateSampler for StratifiedSampler {

View file

@ -7,7 +7,7 @@ use shared::utils::math::{
#[inline(always)] #[inline(always)]
pub fn f16_to_f32(bits: u16) -> f32 { pub fn f16_to_f32(bits: u16) -> f32 {
#[cfg(feature = "cuda")] #[cfg(target_os = "cuda")]
{ {
// Use hardware intrinsic on CUDA // Use hardware intrinsic on CUDA
// Cast bits to cuda_f16, then cast to f32 // Cast bits to cuda_f16, then cast to f32
@ -15,7 +15,7 @@ pub fn f16_to_f32(bits: u16) -> f32 {
half_val.to_f32() half_val.to_f32()
} }
#[cfg(feature = "vulkan")] #[cfg(target_arch = "spirv")]
{ {
// Use shared logic or spirv-std intrinsics if available. // Use shared logic or spirv-std intrinsics if available.
// Sadly, f16 support in rust-gpu is still maturing. // Sadly, f16 support in rust-gpu is still maturing.
@ -23,7 +23,7 @@ pub fn f16_to_f32(bits: u16) -> f32 {
f16_to_f32_software(bits) f16_to_f32_software(bits)
} }
#[cfg(not(any(feature = "cuda", feature = "vulkan")))] #[cfg(not(any(target_os = "cuda", target_arch = "spirv")))]
{ {
f16::from_bits(bits).to_f32() f16::from_bits(bits).to_f32()
} }