diff options
| author | Sakarias Johansson <sakarias.johansson@goodbyekansas.com> | 2023-01-12 22:07:57 +0100 |
|---|---|---|
| committer | Sakarias Johansson <sakarias.johansson@goodbyekansas.com> | 2023-01-12 22:07:57 +0100 |
| commit | 9d44f7ab04e6f6979e0eebc24f8fb439a23a3865 (patch) | |
| tree | 5194f6bd792c8ccf7a164582a1ebb5dc51e3a98c /racer-tracer/src | |
| parent | a6302805d19273c95278c8d792ffbd9b2633fe20 (diff) | |
| download | racer-tracer-9d44f7ab04e6f6979e0eebc24f8fb439a23a3865.tar.gz racer-tracer-9d44f7ab04e6f6979e0eebc24f8fb439a23a3865.tar.xz racer-tracer-9d44f7ab04e6f6979e0eebc24f8fb439a23a3865.zip | |
🧹 Minor cleanup
- Made the traits into supertraits so we don't have to mention Send and
Sync everywhere.
- Add methods for Vec3 that modifies the existing Vector. Can be used
to make less copies.
Diffstat (limited to 'racer-tracer/src')
| -rw-r--r-- | racer-tracer/src/geometry.rs | 6 | ||||
| -rw-r--r-- | racer-tracer/src/geometry/sphere.rs | 4 | ||||
| -rw-r--r-- | racer-tracer/src/main.rs | 44 | ||||
| -rw-r--r-- | racer-tracer/src/material.rs | 2 | ||||
| -rw-r--r-- | racer-tracer/src/material/lambertian.rs | 7 | ||||
| -rw-r--r-- | racer-tracer/src/scene.rs | 4 | ||||
| -rw-r--r-- | racer-tracer/src/vec3.rs | 94 |
7 files changed, 90 insertions, 71 deletions
diff --git a/racer-tracer/src/geometry.rs b/racer-tracer/src/geometry.rs index 1cc7e28..78e0259 100644 --- a/racer-tracer/src/geometry.rs +++ b/racer-tracer/src/geometry.rs @@ -11,11 +11,11 @@ pub struct HitRecord { pub normal: Vec3, pub t: f64, pub front_face: bool, - pub material: Arc<Box<dyn Material + Send + Sync>>, + pub material: Arc<Box<dyn Material>>, } impl HitRecord { - fn new(point: Vec3, t: f64, material: Arc<Box<dyn Material + Send + Sync>>) -> Self { + fn new(point: Vec3, t: f64, material: Arc<Box<dyn Material>>) -> Self { Self { point, normal: Vec3::default(), @@ -35,7 +35,7 @@ impl HitRecord { } } -pub trait Hittable { +pub trait Hittable: Send + Sync { //pub trait Hittable { fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord>; } diff --git a/racer-tracer/src/geometry/sphere.rs b/racer-tracer/src/geometry/sphere.rs index 256abec..81b621c 100644 --- a/racer-tracer/src/geometry/sphere.rs +++ b/racer-tracer/src/geometry/sphere.rs @@ -9,11 +9,11 @@ use crate::vec3::Vec3; pub struct Sphere { pos: Vec3, radius: f64, - material: Arc<Box<dyn Material + Sync + Send>>, // Just a color for now. + material: Arc<Box<dyn Material>>, } impl Sphere { - pub fn new(pos: Vec3, radius: f64, material: Arc<Box<dyn Material + Sync + Send>>) -> Self { + pub fn new(pos: Vec3, radius: f64, material: Arc<Box<dyn Material>>) -> Self { Self { pos, radius, diff --git a/racer-tracer/src/main.rs b/racer-tracer/src/main.rs index 508c22a..ef2cb4a 100644 --- a/racer-tracer/src/main.rs +++ b/racer-tracer/src/main.rs @@ -22,16 +22,8 @@ use rayon::prelude::*; use vec3::Color; use crate::{ - camera::Camera, - error::TracerError, - geometry::sphere::Sphere, - geometry::Hittable, - image::Image, - ray::Ray, - scene::Scene, - util::random_double, - vec3::Vec3, - vec3::{random_in_hemisphere, random_unit_vector}, + camera::Camera, error::TracerError, geometry::sphere::Sphere, geometry::Hittable, image::Image, + ray::Ray, scene::Scene, util::random_double, vec3::Vec3, }; fn ray_color(scene: &dyn Hittable, ray: &Ray, depth: usize) -> Vec3 { @@ -93,7 +85,7 @@ fn raytrace( for _ in 0..image.samples_per_pixel { let u: f64 = (i as f64 + random_double()) / (image.width - 1) as f64; let v: f64 = (row as f64 + random_double()) / (image.height - 1) as f64; - colors[i] += ray_color(scene, &camera.get_ray(u, v), max_depth); + colors[i].add(ray_color(scene, &camera.get_ray(u, v), max_depth)); } // Update the screen buffer every now and again. @@ -130,10 +122,10 @@ fn render( buffer: Arc<RwLock<Vec<u32>>>, camera: Arc<Camera>, image: Arc<Image>, - scene: Box<dyn Hittable + std::marker::Sync>, + scene: Box<dyn Hittable>, max_depth: usize, ) { - let scene: &(dyn Hittable + Sync) = scene.borrow(); + let scene: &(dyn Hittable) = scene.borrow(); let v: Vec<Data> = (0..image.height) .map(|row| { ( @@ -150,7 +142,7 @@ fn render( }); } -type SharedMaterial = Arc<Box<dyn Material + Send + Sync>>; +type SharedMaterial = Arc<Box<dyn Material>>; fn create_scene() -> Scene { let mut scene = Scene::new(); let material_ground: SharedMaterial = @@ -183,20 +175,6 @@ fn create_scene() -> Scene { Arc::clone(&material_right), ))); scene - // Materials - /* let red: Arc<Box<dyn Material + Send + Sync>> = - Arc::new(Box::new(Lambertian::new(Color::new(1.0, 0.0, 0.0)))); - let green: Arc<Box<dyn Material + Send + Sync>> = - Arc::new(Box::new(Lambertian::new(Color::new(0.0, 1.0, 0.0)))); - let metal_red: Arc<Box<dyn Material + Send + Sync>> = - Arc::new(Box::new(Metal::new(Color::new(1.0, 0.0, 0.0)))); - - // Geometry - let sphere1 = Sphere::new(Vec3::new(0.0, 0.0, -1.0), 0.5, Arc::clone(&metal_red)); - let sphere2 = Sphere::new(Vec3::new(0.0, -100.5, -1.0), 100.0, Arc::clone(&green)); - scene.add(Box::new(sphere1)); - scene.add(Box::new(sphere2)); - scene*/ } fn run( @@ -207,7 +185,7 @@ fn run( ) -> Result<(), TracerError> { let image = Arc::new(image::Image::new(aspect_ratio, screen_width, samples)); let camera = Arc::new(camera::Camera::new(&image, 2.0, 1.0)); - let scene: Box<dyn Hittable + Sync + Send> = Box::new(create_scene()); + let scene: Box<dyn Hittable> = Box::new(create_scene()); let screen_buffer: Arc<RwLock<Vec<u32>>> = Arc::new(RwLock::new(vec![0; image.width * image.height])); @@ -215,13 +193,19 @@ fn run( rayon::scope(|s| { s.spawn(|_| { + let render_time = Instant::now(); render( Arc::clone(&screen_buffer), camera, Arc::clone(&image), scene, max_depth, - ) + ); + + println!( + "It took {} seconds to render the image.", + Instant::now().duration_since(render_time).as_secs() + ); }); s.spawn(|_| { let result = Window::new( diff --git a/racer-tracer/src/material.rs b/racer-tracer/src/material.rs index 13c29d7..b6ce418 100644 --- a/racer-tracer/src/material.rs +++ b/racer-tracer/src/material.rs @@ -5,6 +5,6 @@ use crate::geometry::HitRecord; use crate::ray::Ray; use crate::vec3::Color; -pub trait Material { +pub trait Material: Send + Sync { fn scatter(&self, ray: &Ray, hit_record: &HitRecord) -> Option<(Ray, Color)>; } diff --git a/racer-tracer/src/material/lambertian.rs b/racer-tracer/src/material/lambertian.rs index 8356685..d31e3e2 100644 --- a/racer-tracer/src/material/lambertian.rs +++ b/racer-tracer/src/material/lambertian.rs @@ -1,7 +1,7 @@ use crate::{ material::Material, ray::Ray, - vec3::{random_unit_vector, Color, Vec3}, + vec3::{random_unit_vector, Color}, }; pub struct Lambertian { @@ -17,7 +17,7 @@ impl Lambertian { impl Material for Lambertian { fn scatter( &self, - ray: &crate::ray::Ray, + _ray: &crate::ray::Ray, rec: &crate::geometry::HitRecord, ) -> Option<(Ray, Color)> { let mut scatter_direction = rec.normal + random_unit_vector(); @@ -27,7 +27,6 @@ impl Material for Lambertian { scatter_direction = rec.normal; } - let scattered = Ray::new(rec.point, scatter_direction); - Some((scattered, self.color)) + Some((Ray::new(rec.point, scatter_direction), self.color)) } } diff --git a/racer-tracer/src/scene.rs b/racer-tracer/src/scene.rs index 672b39b..c5e76da 100644 --- a/racer-tracer/src/scene.rs +++ b/racer-tracer/src/scene.rs @@ -1,7 +1,7 @@ use crate::geometry::Hittable; pub struct Scene { - objects: Vec<Box<dyn Hittable + Sync + Send>>, + objects: Vec<Box<dyn Hittable>>, } impl Scene { @@ -11,7 +11,7 @@ impl Scene { } } - pub fn add(&mut self, hittable: Box<dyn Hittable + Sync + Send>) { + pub fn add(&mut self, hittable: Box<dyn Hittable>) { self.objects.push(hittable); } } diff --git a/racer-tracer/src/vec3.rs b/racer-tracer/src/vec3.rs index e092754..659d3ed 100644 --- a/racer-tracer/src/vec3.rs +++ b/racer-tracer/src/vec3.rs @@ -26,6 +26,44 @@ impl Vec3 { &self.data[2] } + pub fn add(&mut self, v: Vec3) { + self.data[0] += v.data[0]; + self.data[1] += v.data[1]; + self.data[2] += v.data[2]; + } + + pub fn sub(&mut self, v: Vec3) { + self.data[0] -= v.data[0]; + self.data[1] -= v.data[1]; + self.data[2] -= v.data[2]; + } + + pub fn div(&mut self, v: f64) { + self.data[0] /= v; + self.data[1] /= v; + self.data[2] /= v; + } + + pub fn mul(&mut self, v: f64) { + self.data[0] *= v; + self.data[1] *= v; + self.data[2] *= v; + } + + pub fn reflect(&mut self, mut v: Vec3) { + let double_dot = 2.0 * self.dot(&v); + v.mul(double_dot); + self.sub(v); + } + + pub fn unit_vector(mut self) -> Vec3 { + let len = self.length(); + self.data[0] /= len; + self.data[1] /= len; + self.data[2] /= len; + self + } + pub fn length(&self) -> f64 { f64::sqrt(self.length_squared()) } @@ -42,10 +80,6 @@ impl Vec3 { cross(self, v) } - pub fn unit_vector(&self) -> Vec3 { - unit_vector(self) - } - pub fn as_color(&self) -> u32 { let red: u32 = (self.data[0] * 255.0) as u32; let green: u32 = (self.data[1] * 255.0) as u32; @@ -83,31 +117,6 @@ impl Vec3 { } } -pub fn reflect(v1: &Vec3, v2: &Vec3) -> Vec3 { - v1 - 2.0 * v1.dot(v2) * v2 -} - -pub fn random_in_unit_sphere() -> Vec3 { - let mut v = Vec3::random_range(-1.0, 1.0); - while v.length_squared() >= 1.0 { - v = Vec3::random_range(-1.0, 1.0); - } - v -} - -pub fn random_in_hemisphere(normal: &Vec3) -> Vec3 { - let unit_sphere = random_in_unit_sphere(); - if unit_sphere.dot(normal) > 0.0 { - unit_sphere - } else { - -unit_sphere - } -} - -pub fn random_unit_vector() -> Vec3 { - random_in_unit_sphere().unit_vector() -} - pub fn dot(v1: &Vec3, v2: &Vec3) -> f64 { v1.data[0] * v2.data[0] + v1.data[1] * v2.data[1] + v1.data[2] * v2.data[2] } @@ -120,6 +129,7 @@ pub fn cross(v1: &Vec3, v2: &Vec3) -> Vec3 { ) } +#[allow(dead_code)] pub fn unit_vector(v: &Vec3) -> Vec3 { v / v.length() } @@ -291,6 +301,32 @@ impl std::fmt::Debug for Vec3 { } } +pub fn reflect(v1: &Vec3, v2: &Vec3) -> Vec3 { + v1 - 2.0 * v1.dot(v2) * v2 +} + +pub fn random_in_unit_sphere() -> Vec3 { + let mut v = Vec3::random_range(-1.0, 1.0); + while v.length_squared() >= 1.0 { + v = Vec3::random_range(-1.0, 1.0); + } + v +} + +#[allow(dead_code)] +pub fn random_in_hemisphere(normal: &Vec3) -> Vec3 { + let unit_sphere = random_in_unit_sphere(); + if unit_sphere.dot(normal) > 0.0 { + unit_sphere + } else { + -unit_sphere + } +} + +pub fn random_unit_vector() -> Vec3 { + random_in_unit_sphere().unit_vector() +} + #[cfg(test)] mod tests { use super::*; |
