pbrt_r3/samplers/
stratified.rs

1use crate::core::prelude::*;
2
3use std::sync::Arc;
4use std::sync::RwLock;
5
6#[derive(Debug, PartialEq, Default, Clone)]
7pub struct StratifiedSampler {
8    base: BasePixelSampler,
9    x_pixel_samples: u32,
10    y_pixel_samples: u32,
11    jitter_samples: bool,
12}
13
14impl StratifiedSampler {
15    pub fn new(
16        x_pixel_samples: u32,
17        y_pixel_samples: u32,
18        jitter_samples: bool,
19        n_sampled_dimensions: u32,
20    ) -> Self {
21        let samples_per_pixel = x_pixel_samples * y_pixel_samples;
22        StratifiedSampler {
23            base: BasePixelSampler::new(samples_per_pixel, n_sampled_dimensions),
24            x_pixel_samples,
25            y_pixel_samples,
26            jitter_samples,
27        }
28    }
29}
30
31impl Sampler for StratifiedSampler {
32    fn start_pixel(&mut self, p: &Point2i) {
33        let _p = ProfilePhase::new(Prof::StartPixel);
34
35        // Generate single stratified samples for the pixel
36        let samples_per_pixel = (self.base.base.samples_per_pixel) as usize;
37        for i in 0..self.base.samples1d.len() {
38            stratified_sample_1d(
39                &mut self.base.samples1d[i],
40                samples_per_pixel,
41                &mut self.base.rng,
42                self.jitter_samples,
43            );
44            let count = self.base.samples1d[i].len();
45            shuffle_array(&mut self.base.samples1d[i], count, 1, &mut self.base.rng);
46        }
47        for i in 0..self.base.samples2d.len() {
48            stratified_sample_2d(
49                &mut self.base.samples2d[i],
50                self.x_pixel_samples as usize,
51                self.y_pixel_samples as usize,
52                &mut self.base.rng,
53                self.jitter_samples,
54            );
55            let count = self.base.samples2d[i].len();
56            shuffle_array(&mut self.base.samples2d[i], count, 1, &mut self.base.rng);
57        }
58
59        // Generate arrays of stratified samples for the pixel
60        for i in 0..self.base.base.samples1d_array_sizes.len() {
61            for j in 0..samples_per_pixel {
62                let count = self.base.base.samples1d_array_sizes[i] as usize;
63                let start = j * count;
64                stratified_sample_1d(
65                    &mut self.base.base.sample_array1d[i][start..],
66                    count,
67                    &mut self.base.rng,
68                    self.jitter_samples,
69                );
70                shuffle_array(
71                    &mut self.base.base.sample_array1d[i][start..],
72                    count,
73                    1,
74                    &mut self.base.rng,
75                );
76            }
77        }
78
79        for i in 0..self.base.base.samples2d_array_sizes.len() {
80            for j in 0..samples_per_pixel {
81                let count = self.base.base.samples2d_array_sizes[i] as usize;
82                let start = j * count;
83                latin_hypercube_2d(
84                    &mut self.base.base.sample_array2d[i][start..],
85                    count,
86                    &mut self.base.rng,
87                );
88            }
89        }
90        self.base.base.start_pixel(p);
91    }
92
93    fn start_next_sample(&mut self) -> bool {
94        return self.base.start_next_sample();
95    }
96
97    fn set_sample_number(&mut self, sample_num: u32) -> bool {
98        return self.base.set_sample_number(sample_num);
99    }
100
101    fn get_1d(&mut self) -> Float {
102        return self.base.get_1d();
103    }
104
105    fn get_2d(&mut self) -> Vector2f {
106        return self.base.get_2d();
107    }
108
109    fn request_1d_array(&mut self, n: u32) {
110        self.base.request_1d_array(n);
111    }
112    fn request_2d_array(&mut self, n: u32) {
113        self.base.request_2d_array(n);
114    }
115    fn get_1d_array(&mut self, n: u32) -> Option<Vec<Float>> {
116        return self.base.get_1d_array(n);
117    }
118    fn get_2d_array(&mut self, n: u32) -> Option<Vec<Vector2f>> {
119        return self.base.get_2d_array(n);
120    }
121
122    fn clone_with_seed(&self, seed: u32) -> Arc<RwLock<dyn Sampler>> {
123        let mut ss = self.clone();
124        ss.base.rng.set_sequence(seed as u64);
125        return Arc::new(RwLock::new(ss));
126    }
127
128    fn get_samples_per_pixel(&self) -> u32 {
129        return self.base.base.samples_per_pixel;
130    }
131}
132
133impl PixelSampler for StratifiedSampler {}
134
135pub fn create_stratified_sampler(params: &ParamSet) -> Result<Arc<RwLock<dyn Sampler>>, PbrtError> {
136    let jitter = params.find_one_bool("jitter", true);
137    let mut xsamp = params.find_one_int("xsamples", 4) as u32;
138    let mut ysamp = params.find_one_int("ysamples", 4) as u32;
139    let sd = params.find_one_int("dimensions", 4) as u32;
140    {
141        let options = PbrtOptions::get();
142        if options.quick_render {
143            xsamp = 1;
144            ysamp = 1;
145        }
146    }
147    return Ok(Arc::new(RwLock::new(StratifiedSampler::new(
148        xsamp, ysamp, jitter, sd,
149    ))));
150}