diff options
author | Julian T <julian@jtle.dk> | 2021-02-06 23:43:06 +0100 |
---|---|---|
committer | Julian T <julian@jtle.dk> | 2021-02-06 23:43:06 +0100 |
commit | b64c7e972c52b7d015d661866f0cf902370343e5 (patch) | |
tree | 8d3dc9a8ae6b491b9f8f639f2d0bad6387d59069 /src/trace | |
parent | 0d5e6bd9363d5ed5c4f28174819fc0f5fd9aa586 (diff) |
Implement pathtracing
Diffstat (limited to 'src/trace')
-rw-r--r-- | src/trace/mod.rs | 26 | ||||
-rw-r--r-- | src/trace/pathtrace.rs | 41 |
2 files changed, 60 insertions, 7 deletions
diff --git a/src/trace/mod.rs b/src/trace/mod.rs index 9c8b0b8..7f02f6f 100644 --- a/src/trace/mod.rs +++ b/src/trace/mod.rs @@ -1,24 +1,36 @@ use crate::scene::Scene; use crate::core::{Spectrum, Ray, Vector3f}; +use crate::sample::Sampler; + +mod pathtrace; +pub use pathtrace::PathTracer; /// Simple surface normal tracer /// /// This ray tracer bases color values on the hit surface normals -pub struct NormTracer {} +pub struct NormTracer<'a> { + scn: &'a Scene, +} /// Alias for chosen trace implementation. /// /// This is swiched at compile time to save alot of time. -pub type Tracer = NormTracer; +pub type DefaultTracer<'a> = PathTracer<'a>; -impl NormTracer { - pub fn new() -> NormTracer { - NormTracer {} +pub trait Tracer { + fn trace(&self, sampler: &mut dyn Sampler, ray: &Ray) -> Spectrum; +} + +impl NormTracer<'_> { + pub fn new(scn: &Scene) -> NormTracer { + NormTracer {scn} } +} - pub fn trace(&self, scn: &Scene, ray: &Ray) -> Spectrum { +impl Tracer for NormTracer<'_> { + fn trace(&self, sampler: &mut dyn Sampler, ray: &Ray) -> Spectrum { // Trace ray - if let Some(i) = scn.intersect(ray) { + if let Some(i) = self.scn.intersect(ray) { let norm = i.n * 0.5 + Vector3f::new(0.5); return Spectrum::new_rgb(norm.x, norm.y, norm.z); diff --git a/src/trace/pathtrace.rs b/src/trace/pathtrace.rs new file mode 100644 index 0000000..32a8e15 --- /dev/null +++ b/src/trace/pathtrace.rs @@ -0,0 +1,41 @@ +use crate::scene::Scene; +use crate::core::{Ray, Spectrum}; +use crate::sample::Sampler; +use super::Tracer; + +pub struct PathTracer<'a> { + depth: i32, + scn: &'a Scene, +} + +impl PathTracer<'_> { + pub fn new(scn: &Scene, depth: Option<i32>) -> PathTracer { + let depth = depth.unwrap_or(-1); + + PathTracer { + depth, + scn, + } + } + + pub fn trace_recur(&self, sampler: &mut dyn Sampler, ray: &Ray) -> Spectrum { + + if let Some(i) = self.scn.intersect(ray) { + // Get a random direction in the hemisphere a i.p + // This is Lambertian reflection + let target = i.p + i.n + sampler.get_unit_vector(); + return self.trace_recur(sampler, &Ray::new_to(i.p, target)) * 0.5; + } + + // Simulates a sky + let t = (ray.direction.norm().y + 1.0) * 0.5; + Spectrum::new_rgb(1.0, 1.0, 1.0) * (1.0-t) + Spectrum::new_rgb(0.5, 0.7, 1.0) * t + + } +} + +impl Tracer for PathTracer<'_> { + fn trace(&self, sampler: &mut dyn Sampler, ray: &Ray) -> Spectrum { + self.trace_recur(sampler, ray) + } +} |