diff --git a/ray-tracing-image/src/main.rs b/ray-tracing-image/src/main.rs index 22b8283..9526157 100644 --- a/ray-tracing-image/src/main.rs +++ b/ray-tracing-image/src/main.rs @@ -7,7 +7,7 @@ use ray_tracing_core::{ scene::Scene, }; use ray_tracing_renderer::path_tracer_importance::PathTracerImportance; -use ray_tracing_scene::examples::basic_cornel; +use ray_tracing_scene::examples::basic_cornell; use rayon::prelude::*; use std::path::Path; @@ -45,7 +45,7 @@ fn render_image< fn main() -> ImageResult<()> { // let s = BasicScene::new(); - let s = basic_cornel(); + let s = basic_cornell(); let c = BasicCamera::new( 400, diff --git a/ray-tracing-renderer/src/depth_renderer.rs b/ray-tracing-renderer/src/depth_renderer.rs index 7342f7c..5d2c49d 100644 --- a/ray-tracing-renderer/src/depth_renderer.rs +++ b/ray-tracing-renderer/src/depth_renderer.rs @@ -33,10 +33,10 @@ where let r = camera.forward(x, y, rng); if let Some(i) = scene.intersect(r, 0.0, Float::INFINITY) { - Color::gray(1.0 / i.t()) - // let c = 0.5 * (i.normal() + Dir3::new(1.0, 1.0, 1.0)); + // Color::gray(1.0 / i.t()) + let c = 0.5 * (i.normal() + Dir3::new(1.0, 1.0, 1.0)); // let c = i.normal(); - // Color::new(c.x(), c.y(), c.z()) + Color::new(c.x(), c.y(), c.z()) } else { Color::black() } diff --git a/ray-tracing-scene/obj/cornell_box.mtl b/ray-tracing-scene/obj/cornell_box.mtl index e3a444a..8abac6d 100644 --- a/ray-tracing-scene/obj/cornell_box.mtl +++ b/ray-tracing-scene/obj/cornell_box.mtl @@ -23,5 +23,5 @@ Ka 20 20 20 Kd 1 1 1 Ks 0 0 0 -newmtl glass +newmtl mirror type glass diff --git a/ray-tracing-scene/obj/cornell_box.obj b/ray-tracing-scene/obj/cornell_box.obj index ccb1eb1..eea2d8d 100644 --- a/ray-tracing-scene/obj/cornell_box.obj +++ b/ray-tracing-scene/obj/cornell_box.obj @@ -29,7 +29,7 @@ v 343.0 548.0 227.0 v 343.0 548.0 332.0 v 213.0 548.0 332.0 v 213.0 548.0 227.0 -#f -4 -3 -2 -1 +f -4 -3 -2 -1 o ceiling usemtl white @@ -72,7 +72,7 @@ v 556.0 548.8 0.0 f -4 -3 -2 -1 o short_block -usemtl glass +usemtl mirror v 130.0 165.0 65.0 v 82.0 165.0 225.0 diff --git a/ray-tracing-scene/src/examples.rs b/ray-tracing-scene/src/examples.rs index a5036fc..11b4400 100644 --- a/ray-tracing-scene/src/examples.rs +++ b/ray-tracing-scene/src/examples.rs @@ -1,8 +1,11 @@ +use crate::{ + parse_obj::ObjData, + triangle_bvh::{BVHMaterial, Triangle, TriangleBVH}, +}; use ray_tracing_core::{light::AreaLight, prelude::*}; use ray_tracing_material::{diffuse::DiffuseMaterial, mirror::Mirror}; use std::collections::HashMap; - -use crate::triangle_bvh::{BVHMaterial, Triangle, TriangleBVH}; +use std::fmt::Debug; pub struct ExampleScene { pub scene: TriangleBVH, @@ -12,18 +15,47 @@ pub struct ExampleScene { pub horizontal_fov: Float, } -pub fn example_scenes() -> HashMap<&'static str, fn() -> ExampleScene> { +pub fn example_scenes() -> HashMap<&'static str, fn() -> ExampleScene> { let mut map: HashMap<&str, fn() -> ExampleScene> = HashMap::new(); - map.insert("basic_cornel", basic_cornel::); - // map.insert("cornel2", cornel2::); + map.insert("basic_cornel", basic_cornell::); + map.insert("cornel2", cornell2::); map } -pub fn cornel2() -> ExampleScene { - todo!() +pub fn cornell2() -> ExampleScene { + let obj = ObjData::new("ray-tracing-scene/obj/cornell_box.obj").unwrap(); + + let triangles = obj + .triangle_faces() + .map(|t| Triangle::new(t.v, t.mat.unwrap())) + .collect(); + + let materials = obj + .materials() + .iter() + .map(|m| match m.name.as_str() { + "white" => BVHMaterial::new_material(DiffuseMaterial::new(Color::white())), + "light" => BVHMaterial::new_light(AreaLight::new(Color::white() * 100.0)), + "blue" => BVHMaterial::new_material(DiffuseMaterial::new(Color::new(0.0, 0.0, 1.0))), + "red" => BVHMaterial::new_material(DiffuseMaterial::new(Color::new(1.0, 0.0, 0.0))), + "green" => BVHMaterial::new_material(DiffuseMaterial::new(Color::new(0.0, 1.0, 0.0))), + "mirror" => BVHMaterial::new_material(Mirror::new(Color::white())), + _ => unreachable!(), + }) + .collect(); + + let scene = dbg!(TriangleBVH::new(obj.vertices, triangles, materials)); + + ExampleScene { + scene, + camera_pos: Pos3::new(275.0, 275.0, -800.0), + camera_dir: Dir3::new(0.0, 0.0, 1.0), + camera_up: Dir3::up(), + horizontal_fov: 90.0_f32.to_radians(), + } } -pub fn basic_cornel() -> ExampleScene { +pub fn basic_cornell() -> ExampleScene { let side_length = 1.5; let light_size = 0.5; let light_offset = 0.01; diff --git a/ray-tracing-scene/src/parse_obj.rs b/ray-tracing-scene/src/parse_obj.rs index 0908955..718e147 100644 --- a/ray-tracing-scene/src/parse_obj.rs +++ b/ray-tracing-scene/src/parse_obj.rs @@ -22,8 +22,8 @@ pub struct ObjData { #[derive(Debug)] pub struct ObjMaterial { - name: String, - map: HashMap, + pub name: String, + pub map: HashMap, } #[derive(Debug)] @@ -34,6 +34,13 @@ pub struct Face { pub mat: Option, } +pub struct TriangleFace { + pub v: [u32; 3], + pub t: Option<[u32; 3]>, + pub n: Option<[u32; 3]>, + pub mat: Option, +} + #[derive(Debug)] pub struct RelativeFace { pub v: Vec, @@ -400,4 +407,27 @@ impl ObjData { materials, }) } + + pub fn vertices(&self) -> &Vec { + &self.vertices + } + + pub fn faces(&self) -> &Vec { + &self.faces + } + + pub fn triangle_faces(&self) -> impl Iterator + '_ { + self.faces.iter().flat_map(|f| { + (1..f.v.len() - 1).map(|i| TriangleFace { + v: [f.v[0], f.v[i], f.v[i + 1]], + t: f.t.as_ref().map(|t| [t[0], t[i], t[i + 1]]), + n: f.n.as_ref().map(|n| [n[0], n[i], n[i + 1]]), + mat: f.mat, + }) + }) + } + + pub fn materials(&self) -> &Vec { + &self.materials + } } diff --git a/ray-tracing-scene/src/triangle_bvh.rs b/ray-tracing-scene/src/triangle_bvh.rs index e70129d..60178e0 100644 --- a/ray-tracing-scene/src/triangle_bvh.rs +++ b/ray-tracing-scene/src/triangle_bvh.rs @@ -19,6 +19,39 @@ pub struct BVHMaterial { pub light: Option>>, } +impl BVHMaterial { + pub fn new_material + 'static>(material: M) -> Self { + Self { + material: Some(Box::new(material)), + light: None, + } + } + + pub fn new_light + 'static>(light: L) -> Self { + Self { + material: None, + light: Some(Box::new(light)), + } + } + + pub fn new_material_light + 'static, L: Light + 'static>( + material: M, + light: L, + ) -> Self { + Self { + material: Some(Box::new(material)), + light: Some(Box::new(light)), + } + } + + pub fn new_empty() -> Self { + Self { + material: None, + light: None, + } + } +} + #[derive(Debug, Clone, Copy)] enum Node { Inner { diff --git a/ray-tracing-tev/src/main.rs b/ray-tracing-tev/src/main.rs index 57fec0e..c425637 100644 --- a/ray-tracing-tev/src/main.rs +++ b/ray-tracing-tev/src/main.rs @@ -9,7 +9,8 @@ use ray_tracing_renderer::{ depth_renderer::DepthRenderer, path_tracer::PathTracer, path_tracer_importance::PathTracerImportance, }; -use ray_tracing_scene::{examples::basic_cornel, triangle_bvh::TriangleBVH}; +use ray_tracing_scene::examples::cornell2; +use ray_tracing_scene::triangle_bvh::TriangleBVH; use rayon::prelude::*; use std::net::TcpStream; use tev_client::{PacketCreateImage, PacketUpdateImage, TevClient, TevError}; @@ -69,7 +70,7 @@ fn render_image< } fn get_scene() -> (TriangleBVH, BasicCamera) { - let s = basic_cornel(); + let s = cornell2(); let c = BasicCamera::new( 400,