Update Owen scramble hash to the latest.
From https://psychopath.io/post/2021_01_30_building_a_better_lk_hash
This commit is contained in:
parent
b337e2cb20
commit
70fba19361
|
@ -1,9 +1,10 @@
|
||||||
//! A seedable, Owen-scrambled Sobol sequence.
|
//! A seedable, Owen-scrambled Sobol sequence.
|
||||||
//!
|
//!
|
||||||
//! This is based on the paper "Practical Hash-based Owen Scrambling"
|
//! This is based on the paper "Practical Hash-based Owen Scrambling"
|
||||||
//! by Brent Burley, but with a novel scramble function in place of the
|
//! by Brent Burley, but using the scramble function from
|
||||||
//! Laine-Karras function used in the paper, and with a larger set of direction
|
//! https://psychopath.io/post/2021_01_30_building_a_better_lk_hash
|
||||||
//! numbers due to Kuo et al.
|
//! in place of the Laine-Karras function used in the paper, and with a
|
||||||
|
//! larger set of direction numbers due to Kuo et al.
|
||||||
//!
|
//!
|
||||||
//! This implementation is limited to `2^16` samples, and will loop back
|
//! This implementation is limited to `2^16` samples, and will loop back
|
||||||
//! to the start of the sequence after that limit.
|
//! to the start of the sequence after that limit.
|
||||||
|
@ -36,7 +37,7 @@ pub fn sample_4d(sample_index: u32, dimension_set: u32, seed: u32) -> [f32; 4] {
|
||||||
|
|
||||||
// Shuffle the index using the given seed to produce a unique statistically
|
// Shuffle the index using the given seed to produce a unique statistically
|
||||||
// independent Sobol sequence.
|
// independent Sobol sequence.
|
||||||
let shuffled_rev_index = lk_scramble(sample_index.reverse_bits(), seed);
|
let shuffled_rev_index = scramble(sample_index.reverse_bits(), seed);
|
||||||
|
|
||||||
// Compute the Sobol sample with reversed bits.
|
// Compute the Sobol sample with reversed bits.
|
||||||
let mut sobol_rev = Int4::zero();
|
let mut sobol_rev = Int4::zero();
|
||||||
|
@ -51,7 +52,7 @@ pub fn sample_4d(sample_index: u32, dimension_set: u32, seed: u32) -> [f32; 4] {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do Owen scrambling on the reversed-bits Sobol sample.
|
// Do Owen scrambling on the reversed-bits Sobol sample.
|
||||||
let sobol_owen_rev = lk_scramble_int4(sobol_rev, dimension_set ^ seed);
|
let sobol_owen_rev = scramble_int4(sobol_rev, dimension_set ^ seed);
|
||||||
|
|
||||||
// Un-reverse the bits and convert to floating point in [0, 1).
|
// Un-reverse the bits and convert to floating point in [0, 1).
|
||||||
sobol_owen_rev.reverse_bits().to_norm_floats()
|
sobol_owen_rev.reverse_bits().to_norm_floats()
|
||||||
|
@ -59,30 +60,33 @@ pub fn sample_4d(sample_index: u32, dimension_set: u32, seed: u32) -> [f32; 4] {
|
||||||
|
|
||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
|
|
||||||
/// Scrambles `n` using a novel variation on the Laine-Karras hash.
|
/// Scrambles `n` using the hash function from
|
||||||
|
/// https://psychopath.io/post/2021_01_30_building_a_better_lk_hash
|
||||||
///
|
///
|
||||||
/// This is equivalent to Owen scrambling, but on reversed bits.
|
/// This is equivalent to Owen scrambling, but on reversed bits.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn lk_scramble(mut n: u32, scramble: u32) -> u32 {
|
fn scramble(mut n: u32, scramble: u32) -> u32 {
|
||||||
let scramble = hash(scramble);
|
let scramble = hash(scramble);
|
||||||
|
|
||||||
n = n.wrapping_add(n << 2);
|
n ^= n.wrapping_mul(0x3d20adea);
|
||||||
n ^= n.wrapping_mul(0xfe9b5742);
|
|
||||||
n = n.wrapping_add(scramble);
|
n = n.wrapping_add(scramble);
|
||||||
n = n.wrapping_mul((scramble >> 16) | 1);
|
n = n.wrapping_mul((scramble >> 16) | 1);
|
||||||
|
n ^= n.wrapping_mul(0x05526c56);
|
||||||
|
n ^= n.wrapping_mul(0x53a22864);
|
||||||
|
|
||||||
n
|
n
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Same as `lk_scramble()`, except does it on 4 integers at a time.
|
/// Same as `scramble()`, except does it on 4 integers at a time.
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn lk_scramble_int4(mut n: Int4, scramble: u32) -> Int4 {
|
fn scramble_int4(mut n: Int4, scramble: u32) -> Int4 {
|
||||||
let scramble = hash_int4([scramble; 4].into());
|
let scramble = hash_int4([scramble; 4].into());
|
||||||
|
|
||||||
n += n << 2;
|
n ^= n * [0x3d20adea; 4].into();
|
||||||
n ^= n * [0xfe9b5742; 4].into();
|
|
||||||
n += scramble;
|
n += scramble;
|
||||||
n *= (scramble >> 16) | [1; 4].into();
|
n *= (scramble >> 16) | [1; 4].into();
|
||||||
|
n ^= n * [0x05526c56; 4].into();
|
||||||
|
n ^= n * [0x53a22864; 4].into();
|
||||||
|
|
||||||
n
|
n
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user