From 5f9eb2ab295e83e171ce356c73ece612cee7e1b1 Mon Sep 17 00:00:00 2001 From: Christopher Biscardi Date: Sun, 27 Aug 2023 14:17:51 -0700 Subject: [PATCH] diffuse materials --- Cargo.lock | 3 +++ Cargo.toml | 2 +- src/main.rs | 55 +++++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6c0c44e..c7a5724 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -49,6 +49,9 @@ name = "glam" version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42218cb640844e3872cc3c153dc975229e080a6c4733b34709ef445610550226" +dependencies = [ + "rand", +] [[package]] name = "indicatif" diff --git a/Cargo.toml b/Cargo.toml index ee0b397..640a47b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -glam = "0.24.1" +glam = { version = "0.24.1", features = ["rand"] } indicatif = "0.17.6" itertools = "0.11.0" rand = "0.8.5" diff --git a/src/main.rs b/src/main.rs index efdb2b0..485b36d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ use glam::DVec3; use indicatif::ProgressIterator; use itertools::Itertools; -use rand::prelude::*; +use rand::{distributions::Uniform, prelude::*}; use std::{fs, io, ops::Range}; fn main() -> io::Result<()> { @@ -33,6 +33,7 @@ struct Camera { // viewport_upper_left: DVec3, pixel00_loc: DVec3, samples_per_pixel: u32, + max_depth: u32, } impl Camera { fn new(image_width: u32, aspect_ratio: f64) -> Self { @@ -76,6 +77,7 @@ impl Camera { // viewport_upper_left, pixel00_loc, samples_per_pixel: 100, + max_depth: 50, } } fn get_ray(&self, i: i32, j: i32) -> Ray { @@ -123,7 +125,10 @@ impl Camera { .into_iter() .map(|_| { self.get_ray(x as i32, y as i32) - .color(&world) + .color( + self.max_depth as i32, + &world, + ) * 255.0 * scale_factor }) @@ -161,15 +166,23 @@ impl Ray { fn at(&self, t: f64) -> DVec3 { self.origin + t * self.direction } - fn color(&self, world: &T) -> DVec3 + fn color(&self, depth: i32, world: &T) -> DVec3 where T: Hittable, { + if depth <= 0 { + return DVec3::new(0., 0., 0.); + } if let Some(rec) = - world.hit(&self, (0.)..f64::INFINITY) + world.hit(&self, (0.001)..f64::INFINITY) { - return 0.5 - * (rec.normal + DVec3::new(1., 1., 1.)); + let direction: DVec3 = + random_on_hemisphere(&rec.normal); + let ray = Ray { + origin: rec.point, + direction, + }; + return 0.5 * ray.color(depth - 1, world); } let unit_direction: DVec3 = @@ -343,3 +356,33 @@ impl Hittable for HittableList { hit_record } } + +fn random_in_unit_sphere() -> DVec3 { + let mut rng = rand::thread_rng(); + loop { + let vec = DVec3::new( + rng.gen_range(-1.0..1.), + rng.gen_range(-1.0..1.), + rng.gen_range(-1.0..1.), + ); + + if vec.length_squared() < 1. { + break vec; + } + } +} + +fn random_unit_vector() -> DVec3 { + return random_in_unit_sphere().normalize(); +} + +fn random_on_hemisphere(normal: &DVec3) -> DVec3 { + let on_unit_sphere = random_unit_vector(); + if on_unit_sphere.dot(*normal) > 0.0 + // In the same hemisphere as the normal + { + on_unit_sphere + } else { + -on_unit_sphere + } +}