From 0d71ae86db3dfb8f06a5a9a174a0b9ad5b23b16a Mon Sep 17 00:00:00 2001 From: Nathan Vegdahl Date: Thu, 21 Jul 2022 04:40:26 -0700 Subject: [PATCH] Noticed that z-scrambling is actually just base-4 Owen scrambling. Updated function name and comments to reflect that. --- src/renderer.rs | 4 ++-- src/scramble.rs | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/renderer.rs b/src/renderer.rs index 65755f1..7666ea9 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -20,7 +20,7 @@ use crate::{ morton, ray::{Ray, RayBatch}, scene::{Scene, SceneLightSample}, - scramble::z_scramble, + scramble::owen4, surface, timer::Timer, tracer::Tracer, @@ -249,7 +249,7 @@ impl<'a> Renderer<'a> { // and golden ratio sampling, we do this up-front here rather than in // the samplers themselves. let si_offset = - z_scramble(morton::xy2i(x, y), self.seed).wrapping_mul(self.spp as u32); + owen4(morton::xy2i(x, y), self.seed).wrapping_mul(self.spp as u32); for si in 0..self.spp { let si = (si as u32).wrapping_add(si_offset); diff --git a/src/scramble.rs b/src/scramble.rs index cc3b5c1..1ce3cd9 100644 --- a/src/scramble.rs +++ b/src/scramble.rs @@ -1,7 +1,7 @@ use crate::hash::hash_u32; /// Performs a base-2 Owen scramble on an integer. -pub fn owen(n: u32, seed: u32) -> u32 { +pub fn owen2(n: u32, seed: u32) -> u32 { let mut result = n; for i in 0..32 { @@ -12,11 +12,19 @@ pub fn owen(n: u32, seed: u32) -> u32 { result } -/// Performs z-scrambling from the paper "Screen-Space Blue-Noise -/// Diffusion of Monte Carlo Sampling Error via Hierarchical Ordering -/// of Pixels" by Ahmed et al., except using a more complete and -/// efficient algorithm based on the Owen scrambling function above. -pub fn z_scramble(n: u32, seed: u32) -> u32 { +/// Performs a base-4 Owen scramble on an integer. +/// +/// This is motivated by z-scrambling from the paper "Screen-Space +/// Blue-Noise Diffusion of Monte Carlo Sampling Error via Hierarchical +/// Ordering of Pixels" by Ahmed et al. Their scrambling function is +/// actually just Owen scrambling in base 4, but their attempt at +/// implementing that function isn't great, both in terms of memory +/// usage and scramble quality. (The paper itself is otherwise +/// fantastic, though.) +/// +/// The implementation below is a full proper base-4 Owen scramble, +/// requiring only a 24-byte lookup table. +pub fn owen4(n: u32, seed: u32) -> u32 { const PERM_TABLE: [u8; 24] = [ 0 | (1 << 2) | (2 << 4) | (3 << 6), // [0, 1, 2, 3], 0 | (1 << 2) | (3 << 4) | (2 << 6), // [0, 1, 3, 2],