pbrt_r3/samplers/
maxmin.rs

1use 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; //original code
23            spp = 1 << (maxminlen - 1); //pbrt-r3 patched
24
25            //Warning
26            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            //Warning
32            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        // Generate remaining samples for _MaxMinDistSampler_
66        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}