Fixing logic bugs in Sampling, texture loading. Moving on to issues with ImageTexture, the long dreaded dive

This commit is contained in:
Wito Wiala 2026-06-06 17:13:52 +01:00
parent 63c10c6573
commit 853e980e83
8 changed files with 34 additions and 32 deletions

1
.gitignore vendored
View file

@ -18,3 +18,4 @@ output/
*.md *.md
!README.md !README.md
!INSTALL.md !INSTALL.md
docs/

View file

@ -7,6 +7,7 @@ use core::hash;
use core::ops::{Deref, DerefMut}; use core::ops::{Deref, DerefMut};
use num_traits::Float as NumFloat; use num_traits::Float as NumFloat;
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum WrapMode { pub enum WrapMode {
Black, Black,
@ -225,6 +226,7 @@ pub struct ImageBase {
pub n_channels: i32, pub n_channels: i32,
} }
#[repr(C)]
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Image { pub struct Image {
pub format: PixelFormat, pub format: PixelFormat,

View file

@ -727,33 +727,13 @@ impl Default for MediumInterface {
} }
} }
impl From<Medium> for MediumInterface {
fn from(p: Ptr<Medium>) -> Self {
Self {
inside: p,
outside: p,
}
}
}
// 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: Ptr<Medium>, outside: Ptr<Medium>) -> Self {
Self { Self { inside, outside }
inside: Ptr::from(inside),
outside: Ptr::from(outside),
}
} }
pub fn empty() -> Self { pub fn empty() -> Self {
Self::default() Self::default()
} }
pub fn is_medium_transition(&self) -> bool { pub fn is_medium_transition(&self) -> bool {
self.inside != self.outside self.inside != self.outside
} }

View file

@ -5,8 +5,7 @@ use crate::utils::math::{
clamp, encode_morton_2, inverse_radical_inverse, lerp, log2_int, clamp, encode_morton_2, inverse_radical_inverse, lerp, log2_int,
owen_scrambled_radical_inverse, permutation_element, radical_inverse, round_up_pow2, owen_scrambled_radical_inverse, permutation_element, radical_inverse, round_up_pow2,
scrambled_radical_inverse, sobol_interval_to_index, sobol_sample, BinaryPermuteScrambler, scrambled_radical_inverse, sobol_interval_to_index, sobol_sample, BinaryPermuteScrambler,
DigitPermutation, FastOwenScrambler, NoRandomizer, OwenScrambler, Scrambler, DigitPermutation, FastOwenScrambler, NoRandomizer, OwenScrambler, Scrambler, PRIME_TABLE_SIZE,
PRIME_TABLE_SIZE,
}; };
use crate::utils::rng::Rng; use crate::utils::rng::Rng;
use crate::utils::sobol::N_SOBOL_DIMENSIONS; use crate::utils::sobol::N_SOBOL_DIMENSIONS;
@ -193,9 +192,10 @@ impl SamplerTrait for HaltonSampler {
} }
fn get1d(&mut self) -> Float { 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 = 2;
} }
self.dim += 1;
self.sample_dimension(self.dim) self.sample_dimension(self.dim)
} }
@ -211,7 +211,7 @@ impl SamplerTrait for HaltonSampler {
fn get_pixel2d(&mut self) -> Point2f { fn get_pixel2d(&mut self) -> Point2f {
Point2f::new( Point2f::new(
radical_inverse(0, self.halton_index >> self.base_exponents[0]), 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]),
) )
} }
} }

View file

@ -111,7 +111,7 @@ impl DiskShape {
let p_error = Vector3f::zero(); let p_error = Vector3f::zero();
let flip_normal = self.reverse_orientation ^ self.transform_swap_handedness; let flip_normal = self.reverse_orientation ^ self.transform_swap_handedness;
let wo_object = self.object_from_render.apply_to_vector(wo); 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), Point3fi::new_with_error(p_hit, p_error),
Point2f::new(u, v), Point2f::new(u, v),
wo_object, wo_object,
@ -121,7 +121,15 @@ impl DiskShape {
dndv, dndv,
time, time,
flip_normal, 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(); 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() { if ss.pdf.is_infinite() {
return None; return None;
} }

View file

@ -81,7 +81,7 @@ impl TriangleShape {
fn get_uvs(&self) -> Option<[Point2f; 3]> { fn get_uvs(&self) -> Option<[Point2f; 3]> {
let mesh = self.mesh(); let mesh = self.mesh();
if mesh.s.is_empty() { if mesh.uv.is_empty() {
return None; return None;
} }
let [v0, v1, v2] = self.get_vertex_indices(); let [v0, v1, v2] = self.get_vertex_indices();

View file

@ -1,5 +1,5 @@
use crate::Float;
use crate::core::color::{RGB, XYZ}; use crate::core::color::{RGB, XYZ};
use crate::core::image::Image;
use crate::core::spectrum::SpectrumTrait; use crate::core::spectrum::SpectrumTrait;
use crate::core::texture::{SpectrumType, TextureEvalContext, TextureMapping2D}; use crate::core::texture::{SpectrumType, TextureEvalContext, TextureMapping2D};
use crate::spectra::{ use crate::spectra::{
@ -7,6 +7,7 @@ use crate::spectra::{
SampledWavelengths, SampledWavelengths,
}; };
use crate::utils::Ptr; use crate::utils::Ptr;
use crate::Float;
/* GPU heavy code, dont know if this will ever work the way Im doing things. /* GPU heavy code, dont know if this will ever work the way Im doing things.
* Leaving it here isolated, for careful handling */ * Leaving it here isolated, for careful handling */
@ -15,6 +16,7 @@ use crate::utils::Ptr;
pub struct GPUSpectrumImageTexture { pub struct GPUSpectrumImageTexture {
pub mapping: TextureMapping2D, pub mapping: TextureMapping2D,
pub tex_obj: u64, pub tex_obj: u64,
pub image: Ptr<Image>,
pub scale: Float, pub scale: Float,
pub invert: bool, pub invert: bool,
pub is_single_channel: bool, pub is_single_channel: bool,

View file

@ -374,6 +374,9 @@ impl CpuWavefrontRenderer {
} else { } else {
&self.basic_eval_material_queue &self.basic_eval_material_queue
}; };
if self.regularize {
eprintln!("regularize=true");
}
let n = queue.size(); let n = queue.size();
let next = ((depth + 1) % 2) as usize; let next = ((depth + 1) % 2) as usize;
@ -451,8 +454,14 @@ impl CpuWavefrontRenderer {
eta_scale *= square(bs.eta); 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(); 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); let q = (1.0 - rr_beta).max(0.0_f32);
if rs.indirect.rr < q { if rs.indirect.rr < q {
beta = SampledSpectrum::new(0.0); beta = SampledSpectrum::new(0.0);