pbrt_r3/samplers/
stratified.rs1use 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 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 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}