From 88cda66f0c8a6376ead672637ba92f18ee3e7040 Mon Sep 17 00:00:00 2001 From: Daniel Oom Date: Thu, 5 Sep 2024 21:25:59 +0200 Subject: [PATCH] Clean-up scene intersection lookup code --- kdtree-tester-cli/src/ray_bouncer.rs | 19 +++++++-------- scene/src/lib.rs | 36 +++++++++++++++------------- tracing/src/pathtracer.rs | 12 ++++------ 3 files changed, 32 insertions(+), 35 deletions(-) diff --git a/kdtree-tester-cli/src/ray_bouncer.rs b/kdtree-tester-cli/src/ray_bouncer.rs index 108b584..2268074 100644 --- a/kdtree-tester-cli/src/ray_bouncer.rs +++ b/kdtree-tester-cli/src/ray_bouncer.rs @@ -61,16 +61,17 @@ impl RayBouncer { if !intersection.is_valid() { return Some(intersection); }; - let intersection = intersection.reference?; - let intersection_index = intersection.index; - let intersection = intersection.inner; + let intersection = self + .scene + .lookup_intersection(intersection.reference.unwrap()); let wi = -ray.direction; - let n = self.scene.get_normal(intersection_index, &intersection); - let uv = self.scene.get_texcoord(intersection_index, &intersection); + let n = intersection.normal; + let uv = intersection.texcoord; + let material = intersection.material; // TODO: How to chose offset? let offset = 0.00001 * n; - let point = ray.param(intersection.t); + let point = ray.param(intersection.inner.inner.t); let point_above = point + offset; let point_below = point - offset; @@ -88,11 +89,7 @@ impl RayBouncer { return Some(checked.clone()); } - let sample = material_sample( - self.scene.get_material(intersection_index), - &IncomingRay { wi, n, uv }, - &mut rng, - ); + let sample = material_sample(material, &IncomingRay { wi, n, uv }, &mut rng); let next_ray = Ray::new( if sample.wo.dot(n) >= 0.0 { point_above diff --git a/scene/src/lib.rs b/scene/src/lib.rs index 33a4fbc..db3b3ed 100644 --- a/scene/src/lib.rs +++ b/scene/src/lib.rs @@ -1,4 +1,4 @@ -use geometry::{geometry::Geometry, intersection::RayIntersection, triangle::Triangle}; +use geometry::{geometry::Geometry, intersection::GeometryIntersection, triangle::Triangle}; use glam::{Vec2, Vec3}; use material::Material; use std::{collections::BTreeMap, fs::File, io::BufReader, path::Path}; @@ -108,6 +108,13 @@ fn collect_lights(mtl: &mtl::Mtl) -> Vec { .collect() } +pub struct SceneIntersection<'a> { + pub inner: GeometryIntersection, + pub material: &'a Material, + pub normal: Vec3, + pub texcoord: Vec2, +} + impl Scene { pub fn from_wavefront(image_directory: &Path, obj: &obj::Obj, mtl: &mtl::Mtl) -> Scene { let materials = materials_from_mtl(image_directory, mtl); @@ -203,21 +210,16 @@ impl Scene { } #[inline] - pub fn get_material(&self, index: u32) -> &Material { - &self.materials[self.properties[index as usize].material_index] - } - - #[inline] - pub fn get_normal(&self, index: u32, intersection: &RayIntersection) -> Vec3 { - self.properties[index as usize] - .normals - .lerp(intersection.u, intersection.v) - } - - #[inline] - pub fn get_texcoord(&self, index: u32, intersection: &RayIntersection) -> Vec2 { - self.properties[index as usize] - .texcoords - .lerp(intersection.u, intersection.v) + pub fn lookup_intersection(&self, inner: GeometryIntersection) -> SceneIntersection<'_> { + let properties = &self.properties[inner.index as usize]; + let normal = properties.normals.lerp(inner.inner.u, inner.inner.v); + let texcoord = properties.texcoords.lerp(inner.inner.u, inner.inner.v); + let material = &self.materials[properties.material_index]; + SceneIntersection { + inner, + material, + normal, + texcoord, + } } } diff --git a/tracing/src/pathtracer.rs b/tracing/src/pathtracer.rs index 136c433..0702007 100644 --- a/tracing/src/pathtracer.rs +++ b/tracing/src/pathtracer.rs @@ -41,20 +41,18 @@ impl Pathtracer { if intersection.is_none() { return accumulated_radiance + accumulated_transport * self.scene.environment(); } - let intersection = intersection.unwrap(); - let intersection_index = intersection.index; - let intersection = intersection.inner; + let intersection = self.scene.lookup_intersection(intersection.unwrap()); let wi = -ray.direction; - let n = self.scene.get_normal(intersection_index, &intersection); - let uv = self.scene.get_texcoord(intersection_index, &intersection); - let material = self.scene.get_material(intersection_index); + let n = intersection.normal; + let uv = intersection.texcoord; + let material = intersection.material; // TODO: How to chose offset? // In PBRT the offset is chosen based on the surface normal, surface intersection // calculation error, sampled incoming direction and then rounded up to the next float. let offset = 0.00001 * n; - let point = ray.param(intersection.t); + let point = ray.param(intersection.inner.inner.t); let point_above = point + offset; let point_below = point - offset;