diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/camera/film.rs | 92 | ||||
-rw-r--r-- | src/camera/mod.rs | 2 | ||||
-rw-r--r-- | src/core/bound.rs (renamed from src/bound.rs) | 16 | ||||
-rw-r--r-- | src/core/mod.rs | 11 | ||||
-rw-r--r-- | src/core/ray.rs | 6 | ||||
-rw-r--r-- | src/core/spectrum.rs | 35 | ||||
-rw-r--r-- | src/core/vector2.rs (renamed from src/vector.rs) | 0 | ||||
-rw-r--r-- | src/core/vector3.rs | 47 | ||||
-rw-r--r-- | src/lib.rs | 5 | ||||
-rw-r--r-- | src/main.rs | 10 | ||||
-rw-r--r-- | src/scene/mod.rs | 3 | ||||
-rw-r--r-- | src/scene/shapes/mod.rs | 12 | ||||
-rw-r--r-- | src/scene/shapes/sphere.rs | 16 | ||||
-rw-r--r-- | src/spectrum.rs | 13 |
14 files changed, 210 insertions, 58 deletions
diff --git a/src/camera/film.rs b/src/camera/film.rs index 6661529..1d87399 100644 --- a/src/camera/film.rs +++ b/src/camera/film.rs @@ -1,67 +1,101 @@ -use crate::vector::*; +use crate::core::*; use crate::Float; -use crate::bound; -use crate::spectrum::Spectrum; - -use bound::{Bound2i, Bound2f}; -use super::filter::Filter; -use std::rc::Rc; #[derive(Clone)] pub struct Pixel { - pub rgb: [Float; 3], + rgb: Spectrum, + samples: u32, } pub struct Film { - pub resolution: Vector2i, + size: Vector2i, drawingBound: Bound2i, pixels: Vec<Pixel>, - filter: Rc<Filter>, } pub struct FilmTile { - pub bounds: Bound2i, - filter: Rc<Filter>, + bounds: Bound2i, + size: Vector2i, + + pixels: Vec<Pixel>, } +//const HalfPixel = Vector2f::new(0.5); + impl Pixel { fn new() -> Pixel { - Pixel { rgb: [0.0, 0.0, 0.0] } + Pixel { + rgb: Default::default(), + samples: 0, + } + } + + fn add(&mut self, c: &Spectrum, weight: Float) { + self.rgb += &(c * weight); + self.samples += 1; + } +} + +impl std::ops::AddAssign<&Self> for Pixel { + fn add_assign(&mut self, op: &Self) { + self.rgb += &op.rgb; + self.samples += op.samples; } } impl Film { - pub fn new(resolution: Vector2i, filter: Rc<Filter>) -> Film { - let area = resolution.x * resolution.y; + pub fn new(size: Vector2i) -> Film { + let area = size.x * size.y; Film { - resolution, - drawingBound: Bound2i::new(&Vector2::new(0), &resolution), + size, + drawingBound: Bound2i::new(&Vector2i::new(0), &size), pixels: vec![Pixel::new(); area as usize], - filter, } } pub fn get_tile(&self, bound: &Bound2i) -> FilmTile { - // Used to calculate descrete coordinates into continues - let halfpixel = Vector2f::new_xy(0.5, 0.5); - let fbound = Bound2f::from(bound); + FilmTile::new( + bound, + ) + + } - let p0 = Vector2i::from((fbound.min - halfpixel - self.filter.radius).ceil()); - let p1 = Vector2i::from((fbound.min - halfpixel + self.filter.radius).floor()); + pub fn commit_tile(&mut self, tile: &FilmTile) { + let offset = tile.bounds.min; - let tilebound = bound::intersect(&Bound2i::new(&p0, &p1), &self.drawingBound); + for y in 0 ..= tile.size.y { + let rowindex = (offset.y + y) * self.size.x; + let prowindex = y * tile.size.x; - FilmTile { - bounds: tilebound, - filter: self.filter.clone(), + for x in 0 ..= tile.size.x { + let index = offset.x + x + rowindex; + let pindex: i32 = x + prowindex; + + self.pixels[index as usize] += &tile.pixels[pindex as usize]; + } } } } impl FilmTile { - fn add_sample(point: &Vector2f, c: Spectrum) { - + fn new(bounds: &Bound2i) -> FilmTile { + FilmTile { + bounds: bounds.clone(), + pixels: vec![Pixel::new(); bounds.area() as usize], + size: bounds.diagonal(), + } + } + + pub fn add_sample(&mut self, point: &Vector2f, c: Spectrum) { + let point = Vector2i::from(point.floor()); + // Subtract the offset + let point = point - self.bounds.min; + + let index = point.x + point.y * self.size.x; + + let pixel = self.pixels.get_mut(index as usize).unwrap(); + pixel.add(&c, 1.0); } } diff --git a/src/camera/mod.rs b/src/camera/mod.rs index 8aed4bf..42de3b3 100644 --- a/src/camera/mod.rs +++ b/src/camera/mod.rs @@ -1,2 +1,2 @@ pub mod film; -pub mod filter; +//pub mod filter; diff --git a/src/bound.rs b/src/core/bound.rs index ab0e703..ea9d990 100644 --- a/src/bound.rs +++ b/src/core/bound.rs @@ -1,6 +1,8 @@ use crate::{Number, Float}; -use crate::vector::*; +use super::vector2::Vector2; +use crate::core; +#[derive(Clone)] pub struct Bound2<T: Number> { pub min: Vector2<T>, pub max: Vector2<T> @@ -46,13 +48,17 @@ impl<T: Number> Bound2<T> { let diag = self.diagonal(); return diag.x * diag.y; } + + pub fn width(&self) -> T { + self.diagonal().x + } } impl From<&Bound2i> for Bound2f { fn from(b: &Bound2i) -> Self { Self { - min: Vector2f::from(b.min), - max: Vector2f::from(b.max), + min: core::Vector2f::from(b.min), + max: core::Vector2f::from(b.max), } } } @@ -60,8 +66,8 @@ impl From<&Bound2i> for Bound2f { impl From<&Bound2f> for Bound2i { fn from(b: &Bound2f) -> Self { Self { - min: Vector2i::from(b.min), - max: Vector2i::from(b.max), + min: core::Vector2i::from(b.min), + max: core::Vector2i::from(b.max), } } } diff --git a/src/core/mod.rs b/src/core/mod.rs new file mode 100644 index 0000000..938a16e --- /dev/null +++ b/src/core/mod.rs @@ -0,0 +1,11 @@ +pub mod vector2; +pub mod vector3; +pub mod bound; +pub mod spectrum; +mod ray; + +pub use vector2::{Vector2i, Vector2f}; +pub use vector3::Vector3f; +pub use bound::{Bound2i, Bound2f}; +pub use spectrum::Spectrum; +pub use ray::Ray; diff --git a/src/core/ray.rs b/src/core/ray.rs new file mode 100644 index 0000000..7d73b93 --- /dev/null +++ b/src/core/ray.rs @@ -0,0 +1,6 @@ +use crate::core::Vector3f; + +pub struct Ray { + origin: Vector3f, + direction: Vector3f, +} diff --git a/src/core/spectrum.rs b/src/core/spectrum.rs new file mode 100644 index 0000000..604c8c0 --- /dev/null +++ b/src/core/spectrum.rs @@ -0,0 +1,35 @@ +use crate::Float; +use std::ops; + +// TODO implement SampledSpectrum instead for nicer images + +#[derive(Clone, Default)] +pub struct Spectrum { + c: [Float; 3], +} + +impl Spectrum { + fn new_rgb(r: Float, g: Float, b: Float) -> Spectrum { + Spectrum { c: [r, g, b] } + } +} + +impl std::ops::Mul<Float> for &Spectrum { + type Output = Spectrum; + + fn mul(self, op: Float) -> Self::Output { + Self::Output::new_rgb( + self.c[0] * op, + self.c[1] * op, + self.c[2] * op, + ) + } +} + +impl std::ops::AddAssign<&Self> for Spectrum { + fn add_assign(&mut self, op: &Self) { + self.c[0] += op.c[0]; + self.c[1] += op.c[1]; + self.c[2] += op.c[2]; + } +} diff --git a/src/vector.rs b/src/core/vector2.rs index ac70947..ac70947 100644 --- a/src/vector.rs +++ b/src/core/vector2.rs diff --git a/src/core/vector3.rs b/src/core/vector3.rs new file mode 100644 index 0000000..da09ceb --- /dev/null +++ b/src/core/vector3.rs @@ -0,0 +1,47 @@ +use crate::{Float, Number}; +use std::ops::{Sub, Add}; + +#[derive(Clone, Copy)] +pub struct Vector3<T: Number> { + pub x: T, + pub y: T, + pub z: T, +} + +pub type Vector3f = Vector3<Float>; + +impl<T: Number> Vector3<T> { + pub fn new(initial: T) -> Vector3<T> { + Vector3 { + x: initial, + y: initial, + z: initial, + } + } + + pub fn new_xy(x: T, y: T, z: T) -> Vector3<T> { + Vector3 { x, y, z} + } +} + +impl<T: Number> Sub for Vector3<T> { + type Output = Self; + fn sub(self, op: Self) -> Self::Output { + Self::new_xy( + self.x - op.x, + self.y - op.y, + self.z - op.z, + ) + } +} + +impl<T: Number> Add for Vector3<T> { + type Output = Self; + fn add(self, op: Self) -> Self::Output { + Self::new_xy( + self.x + op.x, + self.y + op.y, + self.z + op.z, + ) + } +} @@ -1,7 +1,6 @@ -pub mod vector; -pub mod bound; +pub mod core; pub mod camera; -mod spectrum; +mod scene; use std::ops::{Add, Sub, Mul}; use std::cmp; diff --git a/src/main.rs b/src/main.rs index 0ac71df..c984176 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,12 @@ -use pathtrace::camera::filter::Filter; use pathtrace::camera::film::Film; -use pathtrace::vector::{Vector2i, Vector2f}; +use pathtrace::vector::{Vector2i}; use pathtrace::bound::Bound2i; -use std::rc::Rc; fn main() { - let filter = Rc::new(Filter::new_box(Vector2f::new(2.5))); - - let film = Film::new(Vector2i::new(100), filter.clone()); + let film = Film::new(Vector2i::new(100)); let tile = film.get_tile(&Bound2i::new_xyxy(10, 10, 100, 100)); - println!("Yo {}", tile.bounds.min.x); + //println!("Yo {}", tile.bounds.min.x); } diff --git a/src/scene/mod.rs b/src/scene/mod.rs new file mode 100644 index 0000000..3482bb6 --- /dev/null +++ b/src/scene/mod.rs @@ -0,0 +1,3 @@ +mod shapes; + + diff --git a/src/scene/shapes/mod.rs b/src/scene/shapes/mod.rs new file mode 100644 index 0000000..76fb6f2 --- /dev/null +++ b/src/scene/shapes/mod.rs @@ -0,0 +1,12 @@ +mod sphere; + +pub use sphere::Sphere; + +use crate::core::Ray; +use crate::Float; + +trait Shape { + // + fn intersect(ray: Ray) -> Float; + fn intersect_ +} diff --git a/src/scene/shapes/sphere.rs b/src/scene/shapes/sphere.rs new file mode 100644 index 0000000..9598422 --- /dev/null +++ b/src/scene/shapes/sphere.rs @@ -0,0 +1,16 @@ +use crate::Float; +use crate::core::{Ray, Vector3f}; + +pub struct Sphere { + radius: Float, + center: Vector3f, +} + +impl Sphere { + pub fn new(radius: Float, center: Vector3f) -> Sphere { + Sphere { + radius, + center, + } + } +} diff --git a/src/spectrum.rs b/src/spectrum.rs deleted file mode 100644 index aa37056..0000000 --- a/src/spectrum.rs +++ /dev/null @@ -1,13 +0,0 @@ -use crate::Float; - -// TODO implement SampledSpectrum instead for nicer images - -pub struct Spectrum { - c: [Float; 3], -} - -impl Spectrum { - fn from_rgb(r: Float, g: Float, b: Float) -> Spectrum { - Spectrum { c: [r, g, b] } - } -} |