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.
|
||||
#[inline(always)]
|
||||
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
|
||||
// Stochastic Transparency" by Laine and Karras.
|
||||
// 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,
|
||||
// because it ends up being equivalent to Owen scrambling.
|
||||
//
|
||||
// Note that the application of the scramble parameter here is equivalent
|
||||
// to doing random digit scrambling. This is valid because random digit
|
||||
// scrambling is a strict subset of Owen scrambling, and therefore does
|
||||
// not invalidate the Owen scrambling itself.
|
||||
// Note that the application of the scramble parameter here via addition
|
||||
// does not invalidate the Owen scramble as long as it is done after the
|
||||
// bit the reversal.
|
||||
//
|
||||
// The permutation constants here were selected through an optimization
|
||||
// process to maximize low-bias avalanche between bits.
|
||||
|
||||
n = n.reverse_bits();
|
||||
n ^= scramble;
|
||||
let perms = [0x1313e844, 0xa14a177e, 0x18c8e432];
|
||||
for p in perms.iter() {
|
||||
n ^= n.wrapping_mul(*p);
|
||||
n = n.wrapping_add(scramble);
|
||||
let perms = [0x97b756bc, 0x4b0a8a12, 0x75c77e36];
|
||||
for &p in perms.iter() {
|
||||
n ^= n.wrapping_mul(p);
|
||||
}
|
||||
n = n.reverse_bits();
|
||||
|
||||
// Return the scrambled value, shifted back into place.
|
||||
n << 16
|
||||
// Return the scrambled value.
|
||||
n
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
|
|
Loading…
Reference in New Issue
Block a user