Add implementing better normals

This commit is contained in:
Jonathan Flueren 2022-07-26 18:16:08 +02:00
parent ff6b6191a4
commit b37f8e3144
4 changed files with 18667 additions and 28 deletions

2580
obj/suzanne.obj Normal file

File diff suppressed because it is too large Load diff

16053
obj/viking_room.obj Normal file

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,7 @@ pub struct Triangle {
a: Point3, a: Point3,
b: Point3, b: Point3,
c: Point3, c: Point3,
normal: Vec3,
pub mat_ptr: Arc<dyn Material>, pub mat_ptr: Arc<dyn Material>,
} }
@ -27,7 +28,7 @@ pub trait Hittable: Sync + Send {
impl HitRecord { impl HitRecord {
fn set_face_normal(&mut self, r: &Ray, outward_normal: Vec3) { fn set_face_normal(&mut self, r: &Ray, outward_normal: Vec3) {
self.front_face = Vec3::dot(r.direction(), outward_normal) < 0.0; self.front_face = true;//Vec3::dot(r.direction(), outward_normal) < 0.0;
if self.front_face { if self.front_face {
self.normal = outward_normal; self.normal = outward_normal;
} else { } else {
@ -101,11 +102,12 @@ impl Hittable for Sphere {
} }
impl Triangle { impl Triangle {
pub fn new(a: Point3, b: Point3, c: Point3, m: Arc<dyn Material>) -> Self { pub fn new(a: Point3, b: Point3, c: Point3, normal: Vec3, m: Arc<dyn Material>) -> Self {
Triangle { Triangle {
a, a,
b, b,
c, c,
normal,
mat_ptr: m, mat_ptr: m,
} }
} }
@ -160,6 +162,9 @@ impl Hittable for Triangle {
rec.mat_ptr = self.mat_ptr.clone(); rec.mat_ptr = self.mat_ptr.clone();
// triangle normal alg from https://stackoverflow.com/questions/19350792/calculate-normal-of-a-single-triangle-in-3d-space // triangle normal alg from https://stackoverflow.com/questions/19350792/calculate-normal-of-a-single-triangle-in-3d-space
rec.normal = self.normal;
return true;
let normal_to_camera = Vec3::new( let normal_to_camera = Vec3::new(
a_to_b.y() * a_to_c.z() - a_to_b.z() * a_to_c.y(), a_to_b.y() * a_to_c.z() - a_to_b.z() * a_to_c.y(),
a_to_b.z() * a_to_c.x() - a_to_b.x() * a_to_c.z(), a_to_b.z() * a_to_c.x() - a_to_b.x() * a_to_c.z(),

View file

@ -46,6 +46,9 @@ fn ray_color(r: &Ray, world: &HittableList, depth: u32) -> Color {
//let target = rec.p + rec.normal + Vec3::random_unit_vector(); // rec.p + rec.normal.random_in_hemisphere(); //let target = rec.p + rec.normal + Vec3::random_unit_vector(); // rec.p + rec.normal.random_in_hemisphere();
//return 0.5 * ray_color(&Ray::new(rec.p, target - rec.p), world, depth - 1); //return 0.5 * ray_color(&Ray::new(rec.p, target - rec.p), world, depth - 1);
} }
// return Color::new(1.0, 1.0, 1.0);
let unit_direction = r.direction(); let unit_direction = r.direction();
let t = 0.5 * (unit_direction.y() + 1.0); let t = 0.5 * (unit_direction.y() + 1.0);
return (1.0 - t) * Color::new(1.0, 1.0, 1.0) + t * Color::new(0.5, 0.7, 1.0); return (1.0 - t) * Color::new(1.0, 1.0, 1.0) + t * Color::new(0.5, 0.7, 1.0);
@ -173,33 +176,29 @@ fn random_world() -> HittableList {
fn from_obj(path: &str) -> HittableList { fn from_obj(path: &str) -> HittableList {
let mut world = HittableList::new(); let mut world = HittableList::new();
let material_ground = Arc::new(Lambertian::new(&Color::new(0.2, 0.2, 0.2))); let material = Arc::new(Lambertian::new(&Color::new(0.6, 0.2, 0.3)));
world.add(Box::<Sphere>::new(Sphere::new(
Point3::new(0.0, -50000.0, 0.0),
50000.0,
material_ground.clone(),
)));
/*
if let Ok(lines) = read_lines(path) {
for line in lines {
if let Ok(text) = line {
dbg!(text);
}
}
}*/
let material = Arc::new(Lambertian::new(&Color::new(0.4, 0.2, 0.3)));
//let material = Arc::new(Dielectric::new(2.0)); //let material = Arc::new(Dielectric::new(2.0));
//let material = Arc::new(Metal::new(&Color::new(0.9, 0.9, 0.7), 0.0)); //let material = Arc::new(Metal::new(&Color::new(0.9, 0.9, 0.7), 0.5));
let cornell_box = tobj::load_obj(path, &tobj::GPU_LOAD_OPTIONS); let cornell_box = tobj::load_obj(path, &tobj::OFFLINE_RENDERING_LOAD_OPTIONS);
let (models, materials) = cornell_box.expect("Failed to load OBJ file"); let (models, materials) = cornell_box.expect("Failed to load OBJ file");
let materials = materials.expect("Failed to load MTL file"); let materials = materials.expect("Failed to load MTL file");
for (i, m) in models.iter().enumerate() { for (i, m) in models.iter().enumerate() {
let mesh = &m.mesh; let mesh = &m.mesh;
println!("positions: {}", mesh.positions.len());
println!("vertex_color: {}", mesh.vertex_color.len());
println!("normals: {}", mesh.normals.len());
println!("texcoords: {}", mesh.texcoords.len());
println!("indices: {}", mesh.indices.len());
println!("face_arities: {}", mesh.face_arities.len());
println!("texcoord_indices: {}", mesh.texcoord_indices.len());
println!("normal_indices: {}", mesh.normal_indices.len());
return world;
let mut next_face = 0; let mut next_face = 0;
for f in 0..mesh.face_arities.len() { for f in 0..mesh.face_arities.len() {
let end = next_face + mesh.face_arities[f] as usize; let end = next_face + mesh.face_arities[f] as usize;
@ -212,6 +211,7 @@ fn from_obj(path: &str) -> HittableList {
let index_a = mesh.indices[3 * v] as usize; let index_a = mesh.indices[3 * v] as usize;
let index_b = mesh.indices[3 * v + 1] as usize; let index_b = mesh.indices[3 * v + 1] as usize;
let index_c = mesh.indices[3 * v + 2] as usize; let index_c = mesh.indices[3 * v + 2] as usize;
let index_normal = mesh.normal_indices[]
world.add(Box::<Triangle>::new(Triangle::new( world.add(Box::<Triangle>::new(Triangle::new(
Point3::new( Point3::new(
@ -229,6 +229,7 @@ fn from_obj(path: &str) -> HittableList {
mesh.positions[3 * index_c + 1] as f64, mesh.positions[3 * index_c + 1] as f64,
mesh.positions[3 * index_c + 2] as f64, mesh.positions[3 * index_c + 2] as f64,
), ),
mesh.
material.clone(), material.clone(),
))); )));
} }
@ -266,16 +267,16 @@ fn main() {
// Image // Image
let aspect_ratio = 16.0 / 9.0; let aspect_ratio = 16.0 / 9.0;
let image_width = 700; let image_width = 600;
let image_height = (image_width as f64 / aspect_ratio) as u32; let image_height = (image_width as f64 / aspect_ratio) as u32;
let samples_per_pixel = 1_u32; let samples_per_pixel = 1_u32;
let max_depth = 25; let max_depth = 50;
let vfov = 60.0; let vfov = 40.0;
let lookfrom = Point3::new(500.0, 500.0, 200.0); let lookfrom = Point3::new(2.0, 0.5, 3.0);
let lookat = Point3::new(0.0, 100.0, 0.0); let lookat = Point3::new(0.0, 0.0, 0.0);
let vup = Vec3::new(0.0, 1.0, 0.0); let vup = Vec3::new(0.0, 1.0, 0.0);
let dist_to_focus = 300.0; let dist_to_focus = 3.0;
let aperture = 0.1; let aperture = 0.1;
// limit rayon multithreading thread count // limit rayon multithreading thread count
@ -284,7 +285,7 @@ fn main() {
env::set_var("RAYON_NUM_THREADS", thread_count.to_string()); env::set_var("RAYON_NUM_THREADS", thread_count.to_string());
} }
let world = from_obj("obj/cat.obj"); let world = from_obj("obj/suzanne.obj");
// World // World
// let world = random_world(); // let world = random_world();