aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian T <julian@jtle.dk>2021-02-07 00:37:58 +0100
committerJulian T <julian@jtle.dk>2021-02-07 00:37:58 +0100
commitf3f56ed5f183f8461cc91cb6430d97c725ba159c (patch)
tree32d07fc105185849b8bf6bfe1fd63bf85f976410
parentb64c7e972c52b7d015d661866f0cf902370343e5 (diff)
Move to double to avoid rounding error
This rounding errors seems to happen when adding floats very close to 1 to a relatively large number. 325.0 + 0.99999034 = 326.0 This is a problem as this sample should be counted at the 325 pixel. However this will be a lesser problem when filtering is implemented.
-rw-r--r--src/camera/film.rs9
-rw-r--r--src/core/vector2.rs10
-rw-r--r--src/lib.rs6
-rw-r--r--src/main.rs2
-rw-r--r--src/sample/mod.rs5
-rw-r--r--src/sample/uniform.rs5
6 files changed, 27 insertions, 10 deletions
diff --git a/src/camera/film.rs b/src/camera/film.rs
index 2ff7239..7a7f2dc 100644
--- a/src/camera/film.rs
+++ b/src/camera/film.rs
@@ -132,11 +132,14 @@ impl FilmTile {
pub fn add_sample(&mut self, inp: &Vector2f, c: Spectrum) {
let point = Vector2i::from(inp.floor());
// Subtract the offset
- let point = point - self.bounds.min;
+ let point = (point - self.bounds.min).cap(self.size.x-1, self.size.y-1);
let index = point.x + point.y * self.size.x;
- let pixel = self.pixels.get_mut(index as usize).unwrap();
- pixel.add(&c, 1.0);
+ if let Some(pixel) = self.pixels.get_mut(index as usize) {
+ pixel.add(&c, 1.0);
+ } else {
+ println!("Could not get pixel {} inp: {}, index: {}", point, inp, index);
+ }
}
}
diff --git a/src/core/vector2.rs b/src/core/vector2.rs
index 858068e..b3fa443 100644
--- a/src/core/vector2.rs
+++ b/src/core/vector2.rs
@@ -4,6 +4,7 @@
use crate::{Float, Number};
use std::ops::{Sub, Add};
use std::fmt;
+use std::cmp::min;
#[derive(Clone, Copy)]
pub struct Vector2<T: Number> {
@@ -84,6 +85,15 @@ impl From<Vector2f> for Vector2i {
}
}
+impl Vector2i {
+ pub fn cap(&self, x: i32, y: i32) -> Self {
+ Self::new_xy(
+ min(self.x, x),
+ min(self.y, y),
+ )
+ }
+}
+
#[cfg(test)]
mod tests {
diff --git a/src/lib.rs b/src/lib.rs
index 0ec6700..7da6627 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -8,6 +8,7 @@ pub mod sample;
use std::ops::{Add, Sub, Mul, DivAssign, Neg};
use std::cmp;
use std::fmt;
+use std::f64::consts::PI;
/// Trait used to implement generics
///
@@ -25,8 +26,11 @@ pub trait Number:
impl Number for i32 {}
impl Number for f32 {}
+impl Number for f64 {}
/// Used for representing floating point values throughout the program
///
/// A higher precision type will require more ram
-pub type Float = f32;
+pub type Float = f64;
+
+pub const M_PI: Float = PI;
diff --git a/src/main.rs b/src/main.rs
index c6bc14e..1604ae3 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -32,7 +32,7 @@ fn main() {
let mut film = Film::new(res);
let tile = film.get_tile(&film.frame);
- let mut task = RenderTask::new(Box::new(tile), 10);
+ let mut task = RenderTask::new(Box::new(tile), 100);
task.render(&ctx, &mut sampler);
film.commit_tile(&task.tile);
diff --git a/src/sample/mod.rs b/src/sample/mod.rs
index 84ac755..5095501 100644
--- a/src/sample/mod.rs
+++ b/src/sample/mod.rs
@@ -1,6 +1,5 @@
-use crate::Float;
+use crate::{M_PI, Float};
use crate::core::{Vector3f, Vector2f};
-use std::f32::consts::PI;
mod uniform;
@@ -20,7 +19,7 @@ pub trait Sampler {
fn get_unit_vector(&mut self) -> Vector3f {
let s2d = self.get_sample_2d();
- let lambda = distribute_between(s2d.x, -PI, PI);
+ let lambda = distribute_between(s2d.x, -M_PI, M_PI);
let costheta = 2.0 * s2d.y - 1.0;
let sintheta = costheta.acos().sin();
diff --git a/src/sample/uniform.rs b/src/sample/uniform.rs
index cc6825a..e2f0b7c 100644
--- a/src/sample/uniform.rs
+++ b/src/sample/uniform.rs
@@ -15,13 +15,14 @@ impl UniformSampler {
pub fn new() -> Self {
Self {
r: Pcg32::seed_from_u64(1),
- d: Uniform::from(0.0..1.0),
+ d: Uniform::new(0.0, 1.0),
}
}
}
impl Sampler for UniformSampler {
fn get_sample(&mut self) -> Float {
- self.d.sample(&mut self.r)
+ let sample = self.d.sample(&mut self.r);
+ sample
}
}