Cleaning up Sobol sampling code.

In particular, removing some things I tried when the golden ratio
sampling was causing problems, but that are now no longer needed.
This commit is contained in:
Nathan Vegdahl 2020-03-21 09:00:43 +09:00
parent 3916043f33
commit e46fc5a4d6
3 changed files with 26 additions and 1046 deletions

View File

@ -7,7 +7,7 @@ use std::{env, fs::File, io::Write, path::Path};
const NUM_DIMENSIONS: usize = 1024; const NUM_DIMENSIONS: usize = 1024;
/// What file to generate the numbers from. /// What file to generate the numbers from.
const DIRECTION_NUMBERS_TEXT: &str = include_str!("direction_numbers/joe-kuo-other-2.1024.txt"); const DIRECTION_NUMBERS_TEXT: &str = include_str!("direction_numbers/new-joe-kuo-5.1024.txt");
fn main() { fn main() {
let out_dir = env::var("OUT_DIR").unwrap(); let out_dir = env::var("OUT_DIR").unwrap();

File diff suppressed because it is too large Load Diff

View File

@ -54,24 +54,33 @@ pub fn sample_owen(dimension: u32, index: u32, scramble: u32) -> f32 {
u32_to_0_1_f32(owen_scramble_u32(sobol_u32(dimension, index), scramble)) u32_to_0_1_f32(owen_scramble_u32(sobol_u32(dimension, index), scramble))
} }
/// Same as `sample()` except applies both Owen scrambling and /// Same as `sample_owen()` except uses a slower more full version of
/// Cranley-Patterson rotation using the given scramble parameter. /// Owen scrambling.
/// ///
/// For the technically curious: this first does Owen scrambling, and then /// This is mainly intended to help validate the faster Owen scrambling,
/// Cranley-Patterson. If it were done the other way around it would /// and likely shouldn't be used for real things. It is significantly
/// invalidate the Owen scrambling. /// slower.
///
/// To get proper scrambling and rotation, you need to use a different scramble
/// value for each dimension, and those values should be generated more-or-less
/// randomly. For example, using a 32-bit hash of the dimension parameter
/// works well.
#[inline] #[inline]
pub fn sample_owen_cranley(dimension: u32, index: u32, scramble: u32) -> f32 { pub fn sample_owen_slow(dimension: u32, index: u32, scramble: u32) -> f32 {
// Reusing the same scramble parameter for both the Owen scrambling and let mut n = sobol_u32(dimension, index);
// the Cranely-Patterson rotation actually works fine, because the Owen n ^= scramble;
// scrambling is implemented as a sort of hash, so they don't end up being for i in 0..16 {
// correlated. let mask = (1 << (31 - i)) - 1;
u32_to_0_1_f32(owen_scramble_u32(sobol_u32(dimension, index), scramble).wrapping_add(scramble)) let hash = {
let mut hash = n & (!mask);
let seed = scramble + i;
let perms = [0x29aaaaa7, 0x736caf6f, 0x54aad35b, 0x2ab35aaa];
for p in perms.iter().cycle().take(6) {
hash = hash.wrapping_mul(*p);
hash ^= hash.wrapping_shr(16);
hash ^= seed;
}
hash
};
n ^= hash & mask;
}
u32_to_0_1_f32(n)
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------