aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/ray.rs7
-rw-r--r--src/lib.rs1
-rw-r--r--src/main.rs5
-rw-r--r--src/render.rs14
-rw-r--r--src/scene/scene.rs2
-rw-r--r--src/scene/shapes/mod.rs8
-rw-r--r--src/scene/shapes/sphere.rs6
-rw-r--r--src/trace/mod.rs30
8 files changed, 60 insertions, 13 deletions
diff --git a/src/core/ray.rs b/src/core/ray.rs
index 2368315..f5517ce 100644
--- a/src/core/ray.rs
+++ b/src/core/ray.rs
@@ -1,8 +1,15 @@
//! The ray class used when probing the 3d scene
use crate::core::Vector3f;
+use crate::Float;
pub struct Ray {
pub origin: Vector3f,
pub direction: Vector3f,
}
+impl Ray {
+ pub fn at(&self, t: Float) -> Vector3f {
+ self.origin + self.direction * t
+ }
+}
+
diff --git a/src/lib.rs b/src/lib.rs
index 50d0435..555bd89 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,6 +2,7 @@ pub mod core;
pub mod camera;
pub mod render;
pub mod scene;
+pub mod trace;
use std::ops::{Add, Sub, Mul, DivAssign};
use std::cmp;
diff --git a/src/main.rs b/src/main.rs
index 05d6617..9985a80 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,5 +1,6 @@
use pathtrace::camera::{Camera, Film};
use pathtrace::scene::Scene;
+use pathtrace::trace::Tracer;
use pathtrace::scene::shapes::Sphere;
use pathtrace::core::{Vector2i, Vector3f};
use pathtrace::render::{RenderContext, RenderTask};
@@ -19,7 +20,9 @@ fn main() {
Box::new(Sphere::new(4.0, Vector3f::new(0.0))),
);
- let ctx = RenderContext { cam: &cam, scn: &scn };
+ let tracer = Tracer::new();
+
+ let ctx = RenderContext { cam: &cam, scn: &scn, trc: &tracer };
let mut film = Film::new(res);
let tile = film.get_tile(&film.frame);
diff --git a/src/render.rs b/src/render.rs
index dcda672..7d05aba 100644
--- a/src/render.rs
+++ b/src/render.rs
@@ -4,12 +4,11 @@
use crate::camera::film::FilmTile;
use crate::camera::Camera;
use crate::scene::Scene;
+use crate::trace::Tracer;
-use crate::core::{Vector2f, Spectrum};
+use crate::core::{Vector2f, Vector3f, Spectrum};
use crate::Float;
-const HALF_PIXEL: Vector2f = Vector2f {x: 0.5, y: 0.5 };
-
pub struct RenderTask {
pub tile: Box<FilmTile>,
samples: u32,
@@ -18,6 +17,7 @@ pub struct RenderTask {
pub struct RenderContext<'a> {
pub scn: &'a Scene,
pub cam: &'a Camera,
+ pub trc: &'a Tracer,
}
impl RenderTask {
@@ -29,13 +29,7 @@ impl RenderTask {
// Create a ray
let (r, _) = ctx.cam.generate_ray(&Vector2f::new_xy(x as Float, y as Float));
- // Trace ray
- if let Some(_) = ctx.scn.intersect(r) {
- return Spectrum::new_rgb(0.5, 0.5, 0.0);
- }
-
- Spectrum::new_rgb(0.0, 0.0, 0.0)
-
+ ctx.trc.trace(ctx.scn, &r)
}
pub fn render(&mut self, ctx: &RenderContext) {
diff --git a/src/scene/scene.rs b/src/scene/scene.rs
index a2f5b88..33a7613 100644
--- a/src/scene/scene.rs
+++ b/src/scene/scene.rs
@@ -22,7 +22,7 @@ impl Scene {
self.shps.push(shp);
}
- pub fn intersect(&self, ray: Ray) -> Option<Intersection> {
+ pub fn intersect(&self, ray: &Ray) -> Option<Intersection> {
for shp in self.shps.iter() {
if let Some(t) = shp.intersect(&ray) {
return Some(Intersection {
diff --git a/src/scene/shapes/mod.rs b/src/scene/shapes/mod.rs
index 7fbb8db..9b6bdfd 100644
--- a/src/scene/shapes/mod.rs
+++ b/src/scene/shapes/mod.rs
@@ -2,9 +2,15 @@ mod sphere;
pub use sphere::Sphere;
-use crate::core::Ray;
+use crate::core::{Vector3f, Ray};
use crate::Float;
pub trait Shape {
fn intersect(&self, ray: &Ray) -> Option<Float>;
+
+ /// Calculates the normal at point
+ ///
+ /// Point is assumed to be on the circle.
+ /// The resulting vector is assumed to be normalized.
+ fn norm_at(&self, point: &Vector3f) -> Vector3f;
}
diff --git a/src/scene/shapes/sphere.rs b/src/scene/shapes/sphere.rs
index e30c1ec..da7f321 100644
--- a/src/scene/shapes/sphere.rs
+++ b/src/scene/shapes/sphere.rs
@@ -35,6 +35,12 @@ impl Shape for Sphere {
}
}
+
+ fn norm_at(&self, point: &Vector3f) -> Vector3f {
+ let mut v = *point - self.center;
+ v /= self.radius;
+ v
+ }
}
#[cfg(test)]
diff --git a/src/trace/mod.rs b/src/trace/mod.rs
new file mode 100644
index 0000000..90f12da
--- /dev/null
+++ b/src/trace/mod.rs
@@ -0,0 +1,30 @@
+use crate::scene::Scene;
+use crate::core::{Spectrum, Ray, Vector3f};
+
+/// Simple surface normal tracer
+///
+/// This ray tracer bases color values on the hit surface normals
+pub struct NormTracer {}
+
+/// Alias for chosen trace implementation.
+///
+/// This is swiched at compile time to save alot of time.
+pub type Tracer = NormTracer;
+
+impl NormTracer {
+ pub fn new() -> NormTracer {
+ NormTracer {}
+ }
+
+ pub fn trace(&self, scn: &Scene, ray: &Ray) -> Spectrum {
+ // Trace ray
+ if let Some(i) = scn.intersect(ray) {
+ let p = ray.at(i.t);
+ let norm = i.shp.norm_at(&p) * 0.5 + Vector3f::new(0.5);
+
+ return Spectrum::new_rgb(norm.x, norm.y, norm.z);
+ }
+
+ Spectrum::new_rgb(0.0, 0.0, 0.0)
+ }
+}