diff --git a/.gitignore b/.gitignore index 9aff772..e2b964b 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ output/ *.md !README.md !INSTALL.md +docs/ diff --git a/shared/src/core/image.rs b/shared/src/core/image.rs index 4b00969..efaacc2 100644 --- a/shared/src/core/image.rs +++ b/shared/src/core/image.rs @@ -7,6 +7,7 @@ use core::hash; use core::ops::{Deref, DerefMut}; use num_traits::Float as NumFloat; +#[repr(C)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum WrapMode { Black, @@ -225,6 +226,7 @@ pub struct ImageBase { pub n_channels: i32, } +#[repr(C)] #[derive(Clone, Debug)] pub struct Image { pub format: PixelFormat, diff --git a/shared/src/core/medium.rs b/shared/src/core/medium.rs index f9ab279..1c6a832 100644 --- a/shared/src/core/medium.rs +++ b/shared/src/core/medium.rs @@ -727,33 +727,13 @@ impl Default for MediumInterface { } } -impl From for MediumInterface { - fn from(p: Ptr) -> Self { - Self { - inside: p, - outside: p, - } - } -} - -// impl From<&Medium> for MediumInterface { -// fn from(medium: &Medium) -> Self { -// Self::from(medium.clone()) -// } -// } -// impl MediumInterface { - pub fn new(inside: &Medium, outside: &Medium) -> Self { - Self { - inside: Ptr::from(inside), - outside: Ptr::from(outside), - } + pub fn new(inside: Ptr, outside: Ptr) -> Self { + Self { inside, outside } } - pub fn empty() -> Self { Self::default() } - pub fn is_medium_transition(&self) -> bool { self.inside != self.outside } diff --git a/shared/src/core/sampler.rs b/shared/src/core/sampler.rs index a388de4..293aeff 100644 --- a/shared/src/core/sampler.rs +++ b/shared/src/core/sampler.rs @@ -5,8 +5,7 @@ use crate::utils::math::{ clamp, encode_morton_2, inverse_radical_inverse, lerp, log2_int, owen_scrambled_radical_inverse, permutation_element, radical_inverse, round_up_pow2, scrambled_radical_inverse, sobol_interval_to_index, sobol_sample, BinaryPermuteScrambler, - DigitPermutation, FastOwenScrambler, NoRandomizer, OwenScrambler, Scrambler, - PRIME_TABLE_SIZE, + DigitPermutation, FastOwenScrambler, NoRandomizer, OwenScrambler, Scrambler, PRIME_TABLE_SIZE, }; use crate::utils::rng::Rng; use crate::utils::sobol::N_SOBOL_DIMENSIONS; @@ -193,9 +192,10 @@ impl SamplerTrait for HaltonSampler { } fn get1d(&mut self) -> Float { - if self.dim >= PRIME_TABLE_SIZE as u32 { + if self.dim + 1 >= PRIME_TABLE_SIZE as u32 { self.dim = 2; } + self.dim += 1; self.sample_dimension(self.dim) } @@ -211,7 +211,7 @@ impl SamplerTrait for HaltonSampler { fn get_pixel2d(&mut self) -> Point2f { Point2f::new( radical_inverse(0, self.halton_index >> self.base_exponents[0]), - radical_inverse(1, self.halton_index >> self.base_exponents[1]), + radical_inverse(1, self.halton_index / self.base_scales[1]), ) } } diff --git a/shared/src/shapes/disk.rs b/shared/src/shapes/disk.rs index 588a639..e681842 100644 --- a/shared/src/shapes/disk.rs +++ b/shared/src/shapes/disk.rs @@ -111,7 +111,7 @@ impl DiskShape { let p_error = Vector3f::zero(); let flip_normal = self.reverse_orientation ^ self.transform_swap_handedness; let wo_object = self.object_from_render.apply_to_vector(wo); - SurfaceInteraction::new( + let intr = SurfaceInteraction::new( Point3fi::new_with_error(p_hit, p_error), Point2f::new(u, v), wo_object, @@ -121,7 +121,15 @@ impl DiskShape { dndv, time, flip_normal, - ) + ); + + match self + .render_from_object + .apply_to_interaction(&Interaction::Surface(intr)) + { + Interaction::Surface(si) => si, + _ => unreachable!("Only surfaces need apply"), + } } } @@ -203,7 +211,7 @@ impl ShapeTrait for DiskShape { } wi = wi.normalize(); - ss.pdf = Vector3f::from(ss.intr.n()).dot(-wi).abs() / ctx.p().distance_squared(ss.intr.p()); + ss.pdf /= Vector3f::from(ss.intr.n()).abs_dot(-wi) / ctx.p().distance_squared(ss.intr.p()); if ss.pdf.is_infinite() { return None; } diff --git a/shared/src/shapes/triangle.rs b/shared/src/shapes/triangle.rs index 4c139e4..6c8484e 100644 --- a/shared/src/shapes/triangle.rs +++ b/shared/src/shapes/triangle.rs @@ -81,7 +81,7 @@ impl TriangleShape { fn get_uvs(&self) -> Option<[Point2f; 3]> { let mesh = self.mesh(); - if mesh.s.is_empty() { + if mesh.uv.is_empty() { return None; } let [v0, v1, v2] = self.get_vertex_indices(); diff --git a/shared/src/textures/image.rs b/shared/src/textures/image.rs index 1a4099b..32e44e2 100644 --- a/shared/src/textures/image.rs +++ b/shared/src/textures/image.rs @@ -1,5 +1,5 @@ -use crate::Float; use crate::core::color::{RGB, XYZ}; +use crate::core::image::Image; use crate::core::spectrum::SpectrumTrait; use crate::core::texture::{SpectrumType, TextureEvalContext, TextureMapping2D}; use crate::spectra::{ @@ -7,6 +7,7 @@ use crate::spectra::{ SampledWavelengths, }; use crate::utils::Ptr; +use crate::Float; /* GPU heavy code, dont know if this will ever work the way Im doing things. * Leaving it here isolated, for careful handling */ @@ -15,6 +16,7 @@ use crate::utils::Ptr; pub struct GPUSpectrumImageTexture { pub mapping: TextureMapping2D, pub tex_obj: u64, + pub image: Ptr, pub scale: Float, pub invert: bool, pub is_single_channel: bool, diff --git a/src/wavefront/integrator.rs b/src/wavefront/integrator.rs index c84d5c7..9116998 100644 --- a/src/wavefront/integrator.rs +++ b/src/wavefront/integrator.rs @@ -374,6 +374,9 @@ impl CpuWavefrontRenderer { } else { &self.basic_eval_material_queue }; + if self.regularize { + eprintln!("regularize=true"); + } let n = queue.size(); let next = ((depth + 1) % 2) as usize; @@ -451,8 +454,14 @@ impl CpuWavefrontRenderer { eta_scale *= square(bs.eta); } + if material.is_conductor() { + if bs.is_specular() { + eprintln!("NON SPECULAR"); + } + } + let rr_beta = (beta * eta_scale / r_u.average()).max_component_value(); - if rr_beta < 1.0 && w.depth > 1 { + if rr_beta < 1.0 && w.depth >= 1 { let q = (1.0 - rr_beta).max(0.0_f32); if rs.indirect.rr < q { beta = SampledSpectrum::new(0.0);