diff --git a/src/renderer.rs b/src/renderer.rs index 6fc18d4..5123670 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -232,15 +232,18 @@ impl<'a> Renderer<'a> { // to work well with golden-ratio sampling. Since we only use sobol // and golden ratio sampling, we do this up-front here rather than in // the samplers themselves. - let si_offset = - owen4_fast(morton::encode(x, y), self.seed).wrapping_mul(self.spp as u32); + let pixel_offset = owen4_fast(morton::encode(x, y), self.seed); + let si_offset = pixel_offset.wrapping_mul(self.spp as u32); for si in 0..(self.spp as u32) { - let mut sample_gen = SampleGen::new(si_offset + si, self.seed); + let sii = si_offset.wrapping_add(si); + let mut sample_gen = SampleGen::new(sii, self.seed); // Raw sample numbers. - let d0 = golden_ratio_sample(si.wrapping_add(si_offset)); - let [d1, d2, d3, _] = sample_gen.next_dims(); + let d0 = golden_ratio_sample( + sii.wrapping_add(rrand::mix32_seed(self.seed, 1111)), + ); + let [d1, d2, d3, _] = sample_gen.next_dims_no_owen(); sample_gen.inc_padding(); let [d4, d5, _, _] = sample_gen.next_dims(); sample_gen.inc_padding(); @@ -582,9 +585,20 @@ impl SampleGen { sobol_owen_int.to_f32_norm() } + + /// Gets the next four dimensions of the current sample, without Owen + /// scrambling of the spatial coordinates. + pub fn next_dims_no_owen(&mut self) -> [f32; 4] { + use sobol_burley::parts::sobol_4d_rev; + + let sobol_int_rev = sobol_4d_rev(self.sample_i_shuffled_rev, self.dimension_i); + self.dimension_i += 1; + + sobol_int_rev.reverse_bits().to_f32_norm() + } } -/// Golden ratio sampler. +/// The golden ratio sequence. /// // NOTE: use this for the wavelength dimension, because // due to the nature of hero wavelength sampling this ends up