Compare commits
1 commit
0c04eeb0f9
...
599683eaad
| Author | SHA1 | Date | |
|---|---|---|---|
| 599683eaad |
20 changed files with 127 additions and 163 deletions
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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};
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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>,
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
pub mod perspective;
|
pub mod perspective;
|
||||||
pub mod realistic;
|
pub mod realistic;
|
||||||
pub mod spherical;
|
pub mod sherical;
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
|
|
@ -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()),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -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(())
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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(),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue