Skip to content

Commit

Permalink
Stratified sampler
Browse files Browse the repository at this point in the history
  • Loading branch information
AdrienVannson committed Mar 19, 2024
1 parent 1b17616 commit 15d5513
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 6 deletions.
5 changes: 3 additions & 2 deletions src/renderers/monte_carlo_renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ fn color<S: Sampler>(
let mut sum = (0., 0., 0.);

for _ in 0..nb_samples {
sampler.new_sample();
let color = one_color(ray, scene, sampler.next2d(), ambient_occlusion);

sum.0 += color.red;
Expand Down Expand Up @@ -183,7 +184,7 @@ impl<S: Sampler + 'static> Renderer for MonteCarloRenderer<S> {
let mut tx_workers = Vec::new();
let mut handles = Vec::new();

let workers_count = 32;
let workers_count = 4; // TODO choose wisely

for worker_id in 0..workers_count {
let scene = Arc::clone(&scene);
Expand All @@ -196,7 +197,7 @@ impl<S: Sampler + 'static> Renderer for MonteCarloRenderer<S> {

handles.push(thread::spawn(move || {
while let Some(request) = rx_worker.recv().unwrap() {
sampler.prepare(1, 1, iterations_per_pixel as usize);
sampler.prepare(0, 1, iterations_per_pixel as usize);

let (x, y) = (request.x, request.y);

Expand Down
3 changes: 0 additions & 3 deletions src/sampler.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
pub trait Sampler: Send {
/// Create a new instance of the sampler.
fn new(seed: u64) -> Self;

/// Initializes the sampler. It will need to generate a fixed number of samples.
/// Each sample will be composed of at most a fixed number of unique random values and a fixed
/// number of couples of random values.
Expand Down
4 changes: 3 additions & 1 deletion src/samplers/independent_sampler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ pub struct IndependentSampler {
rng: Rng,
}

impl Sampler for IndependentSampler {
impl IndependentSampler {
fn new(seed: u64) -> Self {
IndependentSampler {
rng: fastrand::Rng::with_seed(seed),
}
}
}

impl Sampler for IndependentSampler {
fn prepare(&mut self, nb_1d: usize, nb_2d: usize, nb_samples: usize) {}

fn new_sample(&mut self) {}
Expand Down
1 change: 1 addition & 0 deletions src/samplers/mod.rs
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
pub mod independent_sampler;
pub mod stratified_sampler;
83 changes: 83 additions & 0 deletions src/samplers/stratified_sampler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use crate::sampler::Sampler;
use fastrand::Rng;

pub struct StratifiedSampler {
rng: Rng,
with_jittering: bool,
samples_2d: Vec<Vec<[f64; 2]>>, // (nb_samples, nb_2d)
current_sample: usize,
current_2d_dim: usize,
}

impl StratifiedSampler {
fn new(seed: u64) -> Self {
StratifiedSampler {
rng: fastrand::Rng::with_seed(seed),
with_jittering: true,
samples_2d: Vec::new(),
current_sample: 0,
current_2d_dim: 0,
}
}

fn new_without_jittering(seed: u64) -> Self {
StratifiedSampler {
rng: fastrand::Rng::with_seed(seed),
with_jittering: false,
samples_2d: Vec::new(),
current_sample: 0,
current_2d_dim: 0,
}
}
}

impl Sampler for StratifiedSampler {
fn prepare(&mut self, nb_1d: usize, nb_2d: usize, nb_samples: usize) {
// TODO 1D
// TODO several 2d dimensions
assert_eq!(nb_2d, 1);

let root = (nb_samples as f64).sqrt() as usize;
assert_eq!(root * root, nb_samples);

let mut samples_2d = Vec::new();

for i in 0..root {
for j in 0..root {
// Not 0.5 to prevent rays from being parallel to the walls
// TODO 0.5
let (dx, dy) = if self.with_jittering {
(self.rng.f64(), self.rng.f64())
} else {
(0.501, 0.501)
};

samples_2d.push(vec![[
(i as f64 + dx) / root as f64,
(j as f64 + dy) / root as f64,
]]);
}
}

self.samples_2d = samples_2d;
self.current_sample = 0;
self.current_2d_dim = 0;
}

fn new_sample(&mut self) {
if self.current_2d_dim != 0 {
// TODO and 1D dimension
self.current_sample += 1;
self.current_2d_dim = 0;
}
}

fn next1d(&mut self) -> f64 {
unimplemented!();
}

fn next2d(&mut self) -> [f64; 2] {
self.current_2d_dim += 1;
self.samples_2d[self.current_sample][self.current_2d_dim - 1]
}
}

0 comments on commit 15d5513

Please sign in to comment.