Implement screen-space blue-noise sampling properly.
This commit is contained in:
parent
83b48f722d
commit
ec9a121e72
|
@ -17,8 +17,10 @@ use crate::{
|
||||||
image::Image,
|
image::Image,
|
||||||
math::{probit, upper_power_of_two, Float4},
|
math::{probit, upper_power_of_two, Float4},
|
||||||
mis::power_heuristic,
|
mis::power_heuristic,
|
||||||
|
morton,
|
||||||
ray::{Ray, RayBatch},
|
ray::{Ray, RayBatch},
|
||||||
scene::{Scene, SceneLightSample},
|
scene::{Scene, SceneLightSample},
|
||||||
|
scramble::z_scramble,
|
||||||
surface,
|
surface,
|
||||||
timer::Timer,
|
timer::Timer,
|
||||||
tracer::Tracer,
|
tracer::Tracer,
|
||||||
|
@ -246,8 +248,8 @@ impl<'a> Renderer<'a> {
|
||||||
// to work well with golden-ratio sampling. Since we only use sobol
|
// 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
|
// and golden ratio sampling, we do this up-front here rather than in
|
||||||
// the samplers themselves.
|
// the samplers themselves.
|
||||||
let si_offset = crate::scramble::owen(hilbert::xy2i(x, y), self.seed)
|
let si_offset =
|
||||||
.wrapping_mul(self.spp as u32);
|
z_scramble(morton::xy2i(x, y), self.seed).wrapping_mul(self.spp as u32);
|
||||||
for si in 0..self.spp {
|
for si in 0..self.spp {
|
||||||
let si = (si as u32).wrapping_add(si_offset);
|
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 {
|
pub fn owen(n: u32, seed: u32) -> u32 {
|
||||||
let mut result = n;
|
let mut result = n;
|
||||||
|
|
||||||
for b in 0..31 {
|
for i in 0..32 {
|
||||||
let mask = (!0) << (b + 1);
|
let mask = if i < 31 { (!0) << (i + 1) } else { 0 };
|
||||||
result ^= hash_u32(n & mask, seed) & (1 << b);
|
result ^= hash_u32(n & mask, seed) & (1 << i);
|
||||||
}
|
}
|
||||||
result ^= hash_u32(0, seed) & (1 << 31); // Handle highest bit.
|
|
||||||
|
|
||||||
result
|
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