Properly hash all four scramble values in the 4d Sobol sampler.

This commit is contained in:
Nathan Vegdahl 2020-04-25 18:12:35 +09:00
parent 72adbedbb4
commit 1f75e7854e
2 changed files with 32 additions and 7 deletions

View File

@ -99,13 +99,7 @@ fn lk_scramble(mut n: u32, scramble: u32) -> u32 {
/// with SIMD.
#[inline(always)]
fn lk_int4_scramble(mut n: Int4, scramble: u32) -> Int4 {
n += {
let a = hash(scramble, 2);
let b = a ^ 0x174f18ab;
let c = a ^ 0x691e72ca;
let d = a ^ 0xb40cc1b8;
[a, b, c, d].into()
};
n += hash_4d([scramble; 4].into(), 2);
n ^= [0xdc967795; 4].into();
n *= [0x97b754b7; 4].into();
@ -144,3 +138,16 @@ fn hash(n: u32, rounds: u32) -> u32 {
}
hash
}
/// A simple 32-bit hash function. Its quality can be tuned with
/// the number of rounds used.
#[inline(always)]
fn hash_4d(n: Int4, rounds: u32) -> Int4 {
let mut hash = n;
hash ^= [0x912f69ba, 0x174f18ab, 0x691e72ca, 0xb40cc1b8].into();
for _ in 0..rounds {
hash *= [0x736caf6f; 4].into();
hash ^= hash.shr16();
}
hash
}

View File

@ -112,6 +112,13 @@ pub(crate) mod sse {
Int4 { v: n }
}
}
#[inline(always)]
pub(crate) fn shr16(self) -> Int4 {
Int4 {
v: unsafe { _mm_srli_epi32(self.v, 16) },
}
}
}
impl std::ops::MulAssign for Int4 {
@ -190,6 +197,17 @@ pub(crate) mod fallback {
],
}
}
pub(crate) fn shr16(self) -> Int4 {
Int4 {
v: [
self.v[0] >> 16,
self.v[1] >> 16,
self.v[2] >> 16,
self.v[3] >> 16,
],
}
}
}
impl std::ops::MulAssign for Int4 {