Skip to content

Commit

Permalink
finalized adaptive sampling
Browse files Browse the repository at this point in the history
  • Loading branch information
scott223 committed Dec 5, 2023
1 parent a45e6c2 commit 5ca8b57
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 32 deletions.
2 changes: 2 additions & 0 deletions benches/default_benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
sky_color: Color::new(0.5, 0.5, 0.5),
pixel_radius: 2.0,
bvh_split_method: Some(BVHSplitMethod::Mid),
gamma_correction: 2.2,
};

let config_sah: Config = Config {
Expand All @@ -108,6 +109,7 @@ pub fn criterion_benchmark(c: &mut Criterion) {
sky_color: Color::new(0.5, 0.5, 0.5),
pixel_radius: 2.0,
bvh_split_method: Some(BVHSplitMethod::SAH),
gamma_correction: 2.2,
};

let mut r_mid = RenderIntegrator::new(json_scene.clone(), config_mid);
Expand Down
9 changes: 5 additions & 4 deletions input/config.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
{
"img_width": 600.0,
"img_height": 600.0,
"sample_batch_size": 16,
"max_sample_batches": 12,
"min_sample_batches": 2,
"sample_batch_size": 64,
"max_sample_batches": 120,
"min_sample_batches": 10,
"max_depth": 6,
"sky_color": {
"r": 0.3,
"g": 0.5,
"b": 0.9
},
"pixel_radius": 2.0,
"bvh_split_method": "SAH"
"bvh_split_method": "SAH",
"gamma_correction": 2.2
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ mod tests {
sky_color: Color::new(0.5, 0.5, 0.5),
pixel_radius: 2.0,
bvh_split_method: Some(BVHSplitMethod::Mid),
gamma_correction: 2.2,
};
let json_camera: JSONCamera = JSONCamera {
camera_center: Vec3::new(278., 278., -800.),
Expand Down
1 change: 1 addition & 0 deletions src/render/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ mod tests {
sky_color: Color::new(3.0 / 255.0, 165.0 / 255.0, 252.0 / 255.0),
pixel_radius: 2.0,
bvh_split_method: Some(crate::bvh::BVHSplitMethod::Mid),
gamma_correction: 2.2,
};

// TODO
Expand Down
3 changes: 2 additions & 1 deletion src/render/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ impl Color {

#[inline(always)]
pub fn illuminance(&self) -> f64 {
0.2126 * self.r + 0.7152 * self.g+ 0.0722 * self.b
let c = self.clamp();
0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/render/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub struct Config {
pub sky_color: Color,
pub pixel_radius: f64,
pub bvh_split_method: Option<BVHSplitMethod>,
pub gamma_correction: f64,
}

impl Default for Config {
Expand All @@ -40,6 +41,7 @@ impl Default for Config {
sky_color,
bvh_split_method: Some(bvh_split_method),
pixel_radius: 2.0,
gamma_correction: 2.2,
}
}
}
Expand Down
34 changes: 7 additions & 27 deletions src/render/integrator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::{

use sobol_burley::sample;

use super::filter::{Filter, MitchellNetravali};
use super::{filter::{Filter, MitchellNetravali}, Stats};

#[derive(Debug, Clone)]
pub struct RenderIntegrator {
Expand Down Expand Up @@ -267,18 +267,14 @@ impl RenderIntegrator {

for (x, band_item) in band.iter_mut().enumerate() {
// start with black color
let mut color: Color = Color::new(0.0, 0.0, 0.0);
//let mut previous_color: Color = Color::new(0.0, 0.0, 0.0);

let mut actual_samples: usize = 0;
let mut sum_sample_weight: f64 = 0.0;

// sets a pixel to follow and print detailed logs
let _follow_coords: [usize; 2] = [40, 120];
let pixel_num: usize = x * y;

let mut colors: Vec<Color> = Vec::with_capacity(config.max_sample_batches);
let mut weights: Vec<f64> = Vec::with_capacity(config.max_sample_batches);
let mut stats = Stats::new(max_samples);

'batch: for b in 0..config.max_sample_batches {
let mut batch_color: Color = Color::new(0.0, 0.0, 0.0);
Expand Down Expand Up @@ -319,35 +315,19 @@ impl RenderIntegrator {
actual_samples += 1;
}

colors.push(batch_color);
weights.push(batch_sum_sample_weight);



//color += batch_color;
//sum_sample_weight += batch_sum_sample_weight;


stats.push(batch_color, batch_sum_sample_weight);

if b > config.min_sample_batches {
if (true)
{
//log::info!("var {}, check {}", stats.interval(), 0.05 * stats.mean().illuminance());

if stats.interval() < 0.05 * stats.mean().illuminance() {
break 'batch;
}
}
}

let sum_color: Color = colors.iter()
.zip(weights.iter())
.map(|(c, w)| *c * *w)
.sum();

let sum_weights: f64 = weights.iter().sum();

// set pixel color, but first divide by the number of samples to get the average and return
*band_item = (sum_color / sum_weights)
.clamp()
.linear_to_gamma(2.5);
*band_item = (stats.mean()).clamp().linear_to_gamma(config.gamma_correction);

let factor: f64 =
(actual_samples - config.min_sample_batches * config.sample_batch_size) as f64
Expand Down
52 changes: 52 additions & 0 deletions src/render/stats.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use super::Color;

pub struct Stats {
colors: Vec<Color>,
weights: Vec<f64>
}

impl Stats {
pub fn new(capacity: usize) -> Self {
Stats {
colors: Vec::with_capacity(capacity),
weights: Vec::with_capacity(capacity),
}
}

pub fn push(&mut self, color: Color, weight: f64) {
self.colors.push(color);
self.weights.push(weight);
}

pub fn mean(&self) -> Color {
let color: Color = self.colors.iter()
.zip(self.weights.iter())
.map(|(c, w)| *c * *w)
.sum();

let weight: f64 = self.weights.iter().sum();

color / weight
}

pub fn variance(&self) -> f64 {
if self.colors.len() == 1 {
0.0
} else {
let mean: f64 = self.mean().illuminance();
let nominator: f64 = self.weights.iter()
.zip(self.colors.iter())
.map(|(w, c)| *w * (c.illuminance() - mean).powf(2.0))
.sum();

let sum_of_weights: f64 = self.weights.iter().sum();
let denominator: f64 = (sum_of_weights * (self.colors.len() - 1) as f64) / (self.colors.len() as f64);

nominator / denominator
}
}

pub fn interval(&self) -> f64 {
1.96 * (self.variance().sqrt() / (self.colors.len() as f64).sqrt())
}
}

0 comments on commit 5ca8b57

Please sign in to comment.