Compare commits

...

3 Commits

Author SHA1 Message Date
Matthew Gordon d43cf2feeb Fix typo in test 2025-03-21 20:59:35 -03:00
Matthew Gordon 406f347971 Fix floating-point precision issue in accumulation_buffer
Fixed an issue that prevented the image from converging.

(Technically, the convergence was happening and the issue was the final
calculation of the displayed colours, but the visual effect was the same as
failure to converge.)
2025-03-21 20:52:23 -03:00
Matthew Gordon 07651817dc Implement divide-by-scalar for Vec3 2025-03-21 20:51:50 -03:00
3 changed files with 36 additions and 4 deletions

View File

@ -56,7 +56,7 @@ impl AccumulationBuffer {
let colour_sum_t = buffer_colour_sum.values + colour_sum_y;
buffer_colour_bias.values = (colour_sum_t - buffer_colour_sum.values) - colour_sum_y;
buffer_colour_sum.values = colour_sum_t;
buffer_colour.values = buffer_colour_sum.values * (1.0 / *buffer_weight);
buffer_colour.values = buffer_colour_sum.values / *buffer_weight;
}
pub fn merge_tile(&mut self, tile: &Tile, src: &AccumulationBuffer) {

View File

@ -175,10 +175,10 @@ mod tests {
};
let expected_x: f64 =
ImageSampler::scale(200, 800, target.film_width) - target.film_width * 0.5;
assert!((point_on_film_plane.x() - expected_x).abs() < 0.5 / 200.0);
assert!((point_on_film_plane.x() - expected_x).abs() < 0.5 / 800.0);
let expected_y =
-ImageSampler::scale(100, 600, target.film_height) + target.film_height * 0.5;
assert!((point_on_film_plane.y() - expected_y).abs() < 0.5 / 800.0);
assert!((point_on_film_plane.y() - expected_y).abs() < 0.5 / 600.0);
}
}
}

View File

@ -2,7 +2,7 @@ use super::Mat3;
use itertools::izip;
use std::ops::{Add, AddAssign, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign};
use std::ops::{Add, AddAssign, Div, Index, IndexMut, Mul, MulAssign, Neg, Sub, SubAssign};
#[derive(Copy, Clone, PartialEq, Debug, Default)]
pub struct Vec3 {
@ -316,6 +316,30 @@ impl Mul<&Vec3> for f64 {
}
}
impl Div<f64> for &Vec3 {
type Output = Vec3;
fn div(self, rhs: f64) -> Vec3 {
let mut coords = [0.0; 3];
for (r, a) in coords.iter_mut().zip(self.coords.iter()) {
*r = a / rhs;
}
Vec3 { coords }
}
}
impl Div<f64> for Vec3 {
type Output = Vec3;
fn div(self, rhs: f64) -> Vec3 {
let mut coords = [0.0; 3];
for (r, a) in coords.iter_mut().zip(self.coords.iter()) {
*r = a / rhs;
}
Vec3 { coords }
}
}
#[cfg(test)]
mod tests {
use super::*;
@ -459,6 +483,14 @@ mod tests {
assert!(a * b == c);
}
#[test]
fn div_by_scalar_returns_correct_result() {
let a = Vec3::new(1.0, 2.0, 3.0);
let b = 2.0;
let c = Vec3::new(0.5, 1.0, 1.5);
assert!(dbg!(a / b) == dbg!(c));
}
#[test]
fn mul_assign_by_scalar_returns_correct_result() {
let mut a = Vec3::new(1.0, 2.0, 3.0);