diff --git a/src/renderer.rs b/src/renderer.rs index d1177b4..295ef29 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -234,7 +234,7 @@ impl LightPath { pos, nor, local_space: _, - uv: _ } = isect { + closure } = isect { // Hit something! Do the stuff self.interaction = *isect; // Store interaction for use in next phase @@ -267,7 +267,7 @@ impl LightPath { // Calculate and store the light that will be contributed // to the film plane if the light is not in shadow. self.pending_color_addition = { - let material = LambertClosure::new(XYZ::new(0.8, 0.8, 0.8)); + let material = closure.as_surface_closure(); let la = material.evaluate(ray.dir, shadow_vec, nor, self.wavelength); light_color * la * self.light_attenuation / light_pdf }; @@ -307,10 +307,10 @@ impl LightPath { incoming, nor, local_space: _, - uv: _ } = self.interaction { + closure } = self.interaction { // Sample material let (dir, filter, pdf) = { - let material = LambertClosure::new(XYZ::new(0.8, 0.8, 0.8)); + let material = closure.as_surface_closure(); let u = self.next_lds_samp(); let v = self.next_lds_samp(); material.sample(incoming, nor, (u, v), self.wavelength) diff --git a/src/shading/surface_closure.rs b/src/shading/surface_closure.rs index 1ef4d80..ae995e1 100644 --- a/src/shading/surface_closure.rs +++ b/src/shading/surface_closure.rs @@ -4,8 +4,23 @@ use sampling::cosine_sample_hemisphere; use std::f32::consts::PI as PI_32; const INV_PI: f32 = 1.0 / PI_32; +#[derive(Debug, Copy, Clone)] +pub enum SurfaceClosureUnion { + EmitClosure(EmitClosure), + LambertClosure(LambertClosure), +} + +impl SurfaceClosureUnion { + pub fn as_surface_closure(&self) -> &SurfaceClosure { + match self { + &SurfaceClosureUnion::EmitClosure(ref closure) => closure as &SurfaceClosure, + &SurfaceClosureUnion::LambertClosure(ref closure) => closure as &SurfaceClosure, + } + } +} + /// Trait for surface closures. -pub trait SurfaceClosure: Copy { +pub trait SurfaceClosure { /// Returns whether the closure has a delta distribution or not. fn is_delta(&self) -> bool; diff --git a/src/surface/mod.rs b/src/surface/mod.rs index 561da71..cb1e1c0 100644 --- a/src/surface/mod.rs +++ b/src/surface/mod.rs @@ -4,6 +4,7 @@ use std::fmt::Debug; pub mod triangle_mesh; +use shading::surface_closure::SurfaceClosureUnion; use ray::{Ray, AccelRay}; use math::{Point, Vector, Normal, Matrix4x4}; use boundable::Boundable; @@ -19,7 +20,7 @@ pub enum SurfaceIntersection { incoming: Vector, nor: Normal, local_space: Matrix4x4, - uv: (f32, f32), + closure: SurfaceClosureUnion, }, } diff --git a/src/surface/triangle_mesh.rs b/src/surface/triangle_mesh.rs index 4f89b79..c5118c8 100644 --- a/src/surface/triangle_mesh.rs +++ b/src/surface/triangle_mesh.rs @@ -7,6 +7,8 @@ use triangle; use bbox::BBox; use boundable::Boundable; use bvh::BVH; +use shading::surface_closure::{SurfaceClosureUnion, LambertClosure}; +use color::XYZ; use super::{Surface, SurfaceIntersection}; @@ -76,7 +78,7 @@ impl Surface for TriangleMesh { let mat_space = lerp_slice(space, wr.time); let mat_inv = mat_space.inverse(); let tri = (tri.0 * mat_inv, tri.1 * mat_inv, tri.2 * mat_inv); - if let Some((t, tri_u, tri_v)) = triangle::intersect_ray(wr, tri) { + if let Some((t, _, _)) = triangle::intersect_ray(wr, tri) { if t < r.max_t { if r.is_occlusion() { isects[r.id as usize] = SurfaceIntersection::Occlude; @@ -88,7 +90,10 @@ impl Surface for TriangleMesh { incoming: wr.dir, nor: cross(tri.0 - tri.1, tri.0 - tri.2).into_normal(), local_space: mat_space, - uv: (tri_u, tri_v), + // TODO + closure: SurfaceClosureUnion::LambertClosure( + LambertClosure::new(XYZ::new(0.8, 0.8, 0.8)) + ), }; r.max_t = t; }