From a8756debb884ed4ba6e0db271344e22d40f7bfc5 Mon Sep 17 00:00:00 2001 From: Bill Thiede Date: Sun, 15 Jan 2023 15:29:52 -0800 Subject: [PATCH] rtiow: precache some things in Triangles. --- rtiow/renderer/src/scenes/stltest.rs | 7 +++-- rtiow/renderer/src/triangles.rs | 47 ++++++++++++++++------------ 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/rtiow/renderer/src/scenes/stltest.rs b/rtiow/renderer/src/scenes/stltest.rs index a334fca..c8a981d 100644 --- a/rtiow/renderer/src/scenes/stltest.rs +++ b/rtiow/renderer/src/scenes/stltest.rs @@ -16,7 +16,7 @@ use crate::{ }; pub fn new(opt: &Opt) -> Scene { - let lookfrom = Vec3::new(200., 200., 200.); + let lookfrom = Vec3::new(100., 200., 200.); let lookat = Vec3::new(0., 1., 0.); let dist_to_focus = 10.0; let aperture = 0.0; @@ -48,9 +48,10 @@ pub fn new(opt: &Opt) -> Scene { let light_height = 200.; let tri_mesh = Triangles::new( &stl_cube, - Lambertian::new(ConstantTexture::new(Vec3::new(1., 0., 0.))), + Lambertian::new(ConstantTexture::new(Vec3::new(1., 0.1, 0.1))), + 1., ); - dbg!(&tri_mesh); + dbg!(tri_mesh.triangles.len(), tri_mesh.bbox); let objects: Vec> = vec![ // Light from above Box::new(XZRect::new( diff --git a/rtiow/renderer/src/triangles.rs b/rtiow/renderer/src/triangles.rs index 9cbc2e8..17efbb5 100644 --- a/rtiow/renderer/src/triangles.rs +++ b/rtiow/renderer/src/triangles.rs @@ -10,9 +10,14 @@ use crate::{ #[derive(Debug)] pub struct Triangle { - pub normal: Vec3, + normal: Vec3, + verts: [Vec3; 3], + // Precomputed data // TODO(wathiede): precompute `d` on load. - pub verts: [Vec3; 3], + d: f32, + edge0: Vec3, + edge1: Vec3, + edge2: Vec3, } #[derive(Debug)] @@ -20,8 +25,8 @@ pub struct Triangles where M: Material, { - triangles: Vec, - bbox: AABB, + pub triangles: Vec, + pub bbox: AABB, material: M, } @@ -29,13 +34,22 @@ impl Triangles where M: Material, { - pub fn new(stl: &STL, material: M) -> Triangles { + pub fn new(stl: &STL, material: M, scale_factor: f32) -> Triangles { let triangles: Vec<_> = stl .triangles .iter() - .map(|t| Triangle { - normal: t.normal, - verts: t.verts, + .map(|t| { + let v0 = t.verts[0] * scale_factor; + let v1 = t.verts[1] * scale_factor; + let v2 = t.verts[2] * scale_factor; + Triangle { + normal: t.normal, + verts: [v0, v1, v2], + d: -dot(t.normal, t.verts[0]), + edge0: v1 - v0, + edge1: v2 - v1, + edge2: v0 - v2, + } }) .collect(); let (min, max) = triangles.iter().fold( @@ -68,11 +82,8 @@ where M: Material, { // Based on https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/ray-triangle-intersection-geometric-solution.html - fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option { + fn hit(&self, r: Ray, _t_min: f32, _t_max: f32) -> Option { for tri in &self.triangles { - let v0 = tri.verts[0]; - let v1 = tri.verts[1]; - let v2 = tri.verts[2]; let n = tri.normal; // close enough to parallel, won't hit @@ -83,8 +94,7 @@ where continue; } - let d = -dot(n, tri.verts[0]); - let t = -(dot(n, r.origin) + d) / n_dot_dir; + let t = -(dot(n, r.origin) + tri.d) / n_dot_dir; // check if the triangle is behind the ray if t < 0. { continue; @@ -95,23 +105,20 @@ where let v1 = tri.verts[1]; let v2 = tri.verts[2]; - let edge0 = v1 - v0; let vp0 = p - v0; - let c = cross(edge0, vp0); + let c = cross(tri.edge0, vp0); if dot(n, c) < 0. { continue; } - let edge1 = v2 - v1; let vp1 = p - v1; - let c = cross(edge1, vp1); + let c = cross(tri.edge1, vp1); if dot(n, c) < 0. { continue; } - let edge2 = v0 - v2; let vp2 = p - v2; - let c = cross(edge2, vp2); + let c = cross(tri.edge2, vp2); if dot(n, c) < 0. { continue; }