Improve Owen scrambling by seeding with add instead of xor.
Also removed some unnecessary complexity from the implementation, and use different constants.
This commit is contained in:
parent
8deb305850
commit
c4e1bedd43
|
@ -111,14 +111,6 @@ fn sobol_u32(dimension: u32, index: u32) -> u32 {
|
||||||
/// Scrambles `n` using Owen scrambling and the given scramble parameter.
|
/// Scrambles `n` using Owen scrambling and the given scramble parameter.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn owen_scramble_u32(mut n: u32, scramble: u32) -> u32 {
|
fn owen_scramble_u32(mut n: u32, scramble: u32) -> u32 {
|
||||||
// The lower 16 bits aren't generated by our sobol sampler anyway,
|
|
||||||
// and shifting them out allows the seed to better affect the mixing
|
|
||||||
// of the higher bits in a more randomized way, which improves the
|
|
||||||
// scrambling.
|
|
||||||
n >>= 16;
|
|
||||||
|
|
||||||
// Do Owen scrambling.
|
|
||||||
//
|
|
||||||
// This uses the technique presented in the paper "Stratified Sampling for
|
// This uses the technique presented in the paper "Stratified Sampling for
|
||||||
// Stochastic Transparency" by Laine and Karras.
|
// Stochastic Transparency" by Laine and Karras.
|
||||||
// The basic idea is that we're running a special kind of hash function
|
// The basic idea is that we're running a special kind of hash function
|
||||||
|
@ -132,23 +124,23 @@ fn owen_scramble_u32(mut n: u32, scramble: u32) -> u32 {
|
||||||
// But in this case that only-downward behavior is exactly what we want,
|
// But in this case that only-downward behavior is exactly what we want,
|
||||||
// because it ends up being equivalent to Owen scrambling.
|
// because it ends up being equivalent to Owen scrambling.
|
||||||
//
|
//
|
||||||
// Note that the application of the scramble parameter here is equivalent
|
// Note that the application of the scramble parameter here via addition
|
||||||
// to doing random digit scrambling. This is valid because random digit
|
// does not invalidate the Owen scramble as long as it is done after the
|
||||||
// scrambling is a strict subset of Owen scrambling, and therefore does
|
// bit the reversal.
|
||||||
// not invalidate the Owen scrambling itself.
|
|
||||||
//
|
//
|
||||||
// The permutation constants here were selected through an optimization
|
// The permutation constants here were selected through an optimization
|
||||||
// process to maximize low-bias avalanche between bits.
|
// process to maximize low-bias avalanche between bits.
|
||||||
|
|
||||||
n = n.reverse_bits();
|
n = n.reverse_bits();
|
||||||
n ^= scramble;
|
n = n.wrapping_add(scramble);
|
||||||
let perms = [0x1313e844, 0xa14a177e, 0x18c8e432];
|
let perms = [0x97b756bc, 0x4b0a8a12, 0x75c77e36];
|
||||||
for p in perms.iter() {
|
for &p in perms.iter() {
|
||||||
n ^= n.wrapping_mul(*p);
|
n ^= n.wrapping_mul(p);
|
||||||
}
|
}
|
||||||
n = n.reverse_bits();
|
n = n.reverse_bits();
|
||||||
|
|
||||||
// Return the scrambled value, shifted back into place.
|
// Return the scrambled value.
|
||||||
n << 16
|
n
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
|
Loading…
Reference in New Issue
Block a user