Implement screen-space blue-noise sampling properly.
This commit is contained in:
parent
83b48f722d
commit
ec9a121e72
|
@ -17,8 +17,10 @@ use crate::{
|
|||
image::Image,
|
||||
math::{probit, upper_power_of_two, Float4},
|
||||
mis::power_heuristic,
|
||||
morton,
|
||||
ray::{Ray, RayBatch},
|
||||
scene::{Scene, SceneLightSample},
|
||||
scramble::z_scramble,
|
||||
surface,
|
||||
timer::Timer,
|
||||
tracer::Tracer,
|
||||
|
@ -246,8 +248,8 @@ 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 = crate::scramble::owen(hilbert::xy2i(x, y), self.seed)
|
||||
.wrapping_mul(self.spp as u32);
|
||||
let si_offset =
|
||||
z_scramble(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);
|
||||
|
||||
|
|
|
@ -4,11 +4,54 @@ use crate::hash::hash_u32;
|
|||
pub fn owen(n: u32, seed: u32) -> u32 {
|
||||
let mut result = n;
|
||||
|
||||
for b in 0..31 {
|
||||
let mask = (!0) << (b + 1);
|
||||
result ^= hash_u32(n & mask, seed) & (1 << b);
|
||||
for i in 0..32 {
|
||||
let mask = if i < 31 { (!0) << (i + 1) } else { 0 };
|
||||
result ^= hash_u32(n & mask, seed) & (1 << i);
|
||||
}
|
||||
result ^= hash_u32(0, seed) & (1 << 31); // Handle highest bit.
|
||||
|
||||
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 {
|
||||
let mut result = 0;
|
||||
|
||||
for i in 0..16 {
|
||||
let mask = if i < 15 { (!0) << ((i + 1) * 2) } else { 0 };
|
||||
let entry = (hash_u32(n & mask, seed) % 24) as usize;
|
||||
let cell = ((n >> (i * 2)) & 0b11) as usize;
|
||||
result |= (Z_TABLE[entry][cell] as u32) << (i * 2);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
const Z_TABLE: &[[u8; 4]; 24] = &[
|
||||
[0, 1, 2, 3],
|
||||
[0, 1, 3, 2],
|
||||
[0, 2, 1, 3],
|
||||
[0, 2, 3, 1],
|
||||
[0, 3, 1, 2],
|
||||
[0, 3, 2, 1],
|
||||
[1, 0, 2, 3],
|
||||
[1, 0, 3, 2],
|
||||
[1, 2, 0, 3],
|
||||
[1, 2, 3, 0],
|
||||
[1, 3, 0, 2],
|
||||
[1, 3, 2, 0],
|
||||
[2, 0, 1, 3],
|
||||
[2, 0, 3, 1],
|
||||
[2, 1, 0, 3],
|
||||
[2, 1, 3, 0],
|
||||
[2, 3, 0, 1],
|
||||
[2, 3, 1, 0],
|
||||
[3, 0, 1, 2],
|
||||
[3, 0, 2, 1],
|
||||
[3, 1, 0, 2],
|
||||
[3, 1, 2, 0],
|
||||
[3, 2, 0, 1],
|
||||
[3, 2, 1, 0],
|
||||
];
|
||||
|
|
Loading…
Reference in New Issue
Block a user