Reworked Sobol sampler implementation.
This produces identical results, but generates the direction vectors from the original sources at build time. This makes the source code quite a bit leaner, and will also make it easier to play with other direction vectors in the future if the opportunity arises.
This commit is contained in:
parent
42a6c1e9cd
commit
047e66d9aa
|
@ -704,10 +704,10 @@ fn get_sample(dimension: u32, i: u32, pixel_co: (u32, u32), seed: u32) -> f32 {
|
|||
let n = i.wrapping_add(scramble).wrapping_mul(2654435769);
|
||||
n as f32 * (1.0 / (1u64 << 32) as f32)
|
||||
}
|
||||
n if (n - 1) < sobol::NUM_DIMENSIONS as u32 => {
|
||||
n if (n - 1) < sobol::MAX_DIMENSION as u32 => {
|
||||
// Sobol sampling.
|
||||
let scramble = hash_u32(pixel_id, seed);
|
||||
sobol::sample_owen_scramble(dimension - 1, i, hash_u32(dimension, scramble))
|
||||
sobol::sample_owen(dimension - 1, i, hash_u32(dimension, scramble))
|
||||
}
|
||||
_ => {
|
||||
// Random sampling.
|
||||
|
|
|
@ -4,6 +4,7 @@ version = "0.1.0"
|
|||
authors = ["Nathan Vegdahl <cessen@cessen.com>"]
|
||||
edition = "2018"
|
||||
license = "MIT"
|
||||
build = "build.rs"
|
||||
|
||||
[lib]
|
||||
name = "sobol"
|
||||
|
|
1157
sub_crates/sobol/build.rs
Normal file
1157
sub_crates/sobol/build.rs
Normal file
File diff suppressed because it is too large
Load Diff
|
@ -1,30 +1,10 @@
|
|||
// Copyright (c) 2012 Leonhard Gruenschloss (leonhard@gruenschloss.org)
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights to
|
||||
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
// of the Software, and to permit persons to whom the Software is furnished to do
|
||||
// so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
/// An implementation of the Sobol low discrepancy sequence.
|
||||
///
|
||||
/// Includes variants with random digit scrambling and Owen scrambling.
|
||||
|
||||
// Adapted to Rust by Nathan Vegdahl (2017).
|
||||
// Owen scrambling implementation also by Nathan Vegdahl (2020).
|
||||
|
||||
mod matrices;
|
||||
|
||||
pub use crate::matrices::NUM_DIMENSIONS;
|
||||
use crate::matrices::{MATRICES, SIZE};
|
||||
// The following `include` provides `MAX_DIMENSION` and `VECTORS`.
|
||||
// See the build.rs file for how this included file is generated.
|
||||
include!(concat!(env!("OUT_DIR"), "/vectors.inc"));
|
||||
|
||||
/// Compute one component of one sample from the Sobol'-sequence, where
|
||||
/// `dimension` specifies the component and `index` specifies the sample
|
||||
|
@ -42,7 +22,7 @@ pub fn sample(dimension: u32, index: u32) -> f32 {
|
|||
/// randomly. For example, using a 32-bit hash of the dimension parameter
|
||||
/// works well.
|
||||
#[inline]
|
||||
pub fn sample_rd_scramble(dimension: u32, index: u32, scramble: u32) -> f32 {
|
||||
pub fn sample_rd(dimension: u32, index: u32, scramble: u32) -> f32 {
|
||||
u32_to_0_1_f32(sobol_u32(dimension, index) ^ scramble)
|
||||
}
|
||||
|
||||
|
@ -54,7 +34,7 @@ pub fn sample_rd_scramble(dimension: u32, index: u32, scramble: u32) -> f32 {
|
|||
/// randomly. For example, using a 32-bit hash of the dimension parameter
|
||||
/// works well.
|
||||
#[inline]
|
||||
pub fn sample_owen_scramble(dimension: u32, index: u32, scramble: u32) -> f32 {
|
||||
pub fn sample_owen(dimension: u32, index: u32, scramble: u32) -> f32 {
|
||||
// Get the sobol point.
|
||||
let mut n = sobol_u32(dimension, index);
|
||||
|
||||
|
@ -95,13 +75,14 @@ pub fn sample_owen_scramble(dimension: u32, index: u32, scramble: u32) -> f32 {
|
|||
/// The actual core Sobol samplng code. Used by the other functions.
|
||||
#[inline(always)]
|
||||
fn sobol_u32(dimension: u32, mut index: u32) -> u32 {
|
||||
assert!((dimension as usize) < NUM_DIMENSIONS);
|
||||
assert!(dimension < MAX_DIMENSION);
|
||||
let vecs = &VECTORS[dimension as usize];
|
||||
|
||||
let mut result = 0;
|
||||
let mut i = dimension * SIZE as u32;
|
||||
let mut i = 0;
|
||||
while index != 0 {
|
||||
let j = index.trailing_zeros();
|
||||
result ^= MATRICES[(i + j) as usize];
|
||||
result ^= vecs[(i + j) as usize];
|
||||
i += j + 1;
|
||||
index >>= j + 1;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user