From f0e5d538b778fd50bee176210892b7c9ef1c433c Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Tue, 16 Aug 2022 23:38:52 -0700 Subject: [PATCH] Use non-Owen-scrambled samples for motion blur and DoF. This gives notably better results because it avoids what I'm calling "sample overlap", which is an issue with jittering approaches like Owen scrambling. In general, of course, Owen scrambling improves things. But particularly for motion blur it seems to cause issues. --- src/renderer.rs | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) 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