pbrt_r3/samplers/
maxmin.rs1use crate::core::lowdiscrepancy::maxmin::*;
2use crate::core::prelude::*;
3
4use std::sync::Arc;
5use std::sync::RwLock;
6
7use log::*;
8
9#[derive(Debug, PartialEq, Default, Clone)]
10pub struct MaxMinDistSampler {
11 base: BasePixelSampler,
12 cpixel: [u32; 32],
13}
14
15impl MaxMinDistSampler {
16 pub fn new(samples_per_pixel: u32, n_sampled_dimensions: u32) -> Self {
17 let mut spp = samples_per_pixel;
18 let cindex = log2int(spp) as usize;
19 let maxminlen = CMAXMIN_DIST.len();
20 assert_eq!(maxminlen, 17);
21 if cindex >= maxminlen {
22 spp = 1 << (maxminlen - 1); warn!("No more than {} samples per pixel are supported with MaxMinDistSampler. Rounding down.", spp);
27 }
28 if !is_power_of_2(spp) {
29 spp = round_up_pow2(spp);
30
31 warn!(
33 "Non power-of-two sample count rounded up to {} for MaxMinDistSampler.",
34 spp
35 );
36 }
37 let cindex = log2int(spp) as usize;
38 assert!(cindex < maxminlen);
39 let cpixel = CMAXMIN_DIST[cindex];
40 MaxMinDistSampler {
41 base: BasePixelSampler::new(spp, n_sampled_dimensions),
42 cpixel,
43 }
44 }
45}
46
47impl Sampler for MaxMinDistSampler {
48 fn start_pixel(&mut self, p: &Point2i) {
49 let _p = ProfilePhase::new(Prof::StartPixel);
50
51 let samples_per_pixel = self.base.base.samples_per_pixel as usize;
52 let inv_spp = 1.0 / samples_per_pixel as Float;
53 for i in 0..samples_per_pixel {
54 self.base.samples2d[0][i] = Point2f::new(
55 (i as Float) * inv_spp,
56 sample_generator_matrix(&self.cpixel, i as u32, 0),
57 );
58 }
59 shuffle_array(
60 &mut self.base.samples2d[0],
61 samples_per_pixel,
62 1,
63 &mut self.base.rng,
64 );
65 for i in 0..self.base.samples1d.len() {
67 van_der_corput(
68 1,
69 samples_per_pixel as u32,
70 &mut self.base.samples1d[i],
71 &mut self.base.rng,
72 );
73 }
74
75 for i in 1..self.base.samples2d.len() {
76 sobol_2d(
77 1,
78 samples_per_pixel as u32,
79 &mut self.base.samples2d[i],
80 &mut self.base.rng,
81 );
82 }
83
84 for i in 0..self.base.base.samples1d_array_sizes.len() {
85 let count = self.base.base.samples1d_array_sizes[i];
86 van_der_corput(
87 count,
88 samples_per_pixel as u32,
89 &mut self.base.base.sample_array1d[i],
90 &mut self.base.rng,
91 );
92 }
93
94 for i in 0..self.base.base.samples2d_array_sizes.len() {
95 let count = self.base.base.samples2d_array_sizes[i];
96 sobol_2d(
97 count,
98 samples_per_pixel as u32,
99 &mut self.base.base.sample_array2d[i],
100 &mut self.base.rng,
101 );
102 }
103 self.base.start_pixel(p);
104 }
105
106 fn start_next_sample(&mut self) -> bool {
107 return self.base.start_next_sample();
108 }
109
110 fn set_sample_number(&mut self, sample_num: u32) -> bool {
111 return self.base.set_sample_number(sample_num);
112 }
113
114 fn get_1d(&mut self) -> Float {
115 return self.base.get_1d();
116 }
117
118 fn get_2d(&mut self) -> Vector2f {
119 return self.base.get_2d();
120 }
121
122 fn request_1d_array(&mut self, n: u32) {
123 self.base.base.request_1d_array(n);
124 }
125
126 fn request_2d_array(&mut self, n: u32) {
127 self.base.base.request_2d_array(n);
128 }
129
130 fn get_1d_array(&mut self, n: u32) -> Option<Vec<Float>> {
131 return self.base.base.get_1d_array(n);
132 }
133
134 fn get_2d_array(&mut self, n: u32) -> Option<Vec<Vector2f>> {
135 return self.base.base.get_2d_array(n);
136 }
137
138 fn round_count(&self, n: u32) -> u32 {
139 return round_up_pow2(n);
140 }
141
142 fn clone_with_seed(&self, seed: u32) -> Arc<RwLock<dyn Sampler>> {
143 let mut ss = self.clone();
144 ss.base.rng.set_sequence(seed as u64);
145 return Arc::new(RwLock::new(ss));
146 }
147
148 fn get_samples_per_pixel(&self) -> u32 {
149 return self.base.base.samples_per_pixel;
150 }
151}
152
153impl PixelSampler for MaxMinDistSampler {}
154
155pub fn create_maxmindist_sampler(params: &ParamSet) -> Result<Arc<RwLock<dyn Sampler>>, PbrtError> {
156 let mut nsamp = params.find_one_int("pixelsamples", 16) as u32;
157 let sd = params.find_one_int("dimensions", 4) as u32;
158 {
159 let options = PbrtOptions::get();
160 if options.quick_render {
161 nsamp = 1;
162 }
163 }
164 return Ok(Arc::new(RwLock::new(MaxMinDistSampler::new(nsamp, sd))));
165}