summaryrefslogtreecommitdiff
path: root/racer-tracer
diff options
context:
space:
mode:
authorSakarias Johansson <sakarias.johansson@goodbyekansas.com>2023-01-12 22:07:57 +0100
committerSakarias Johansson <sakarias.johansson@goodbyekansas.com>2023-01-12 22:07:57 +0100
commit9d44f7ab04e6f6979e0eebc24f8fb439a23a3865 (patch)
tree5194f6bd792c8ccf7a164582a1ebb5dc51e3a98c /racer-tracer
parenta6302805d19273c95278c8d792ffbd9b2633fe20 (diff)
downloadracer-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')
-rw-r--r--racer-tracer/src/geometry.rs6
-rw-r--r--racer-tracer/src/geometry/sphere.rs4
-rw-r--r--racer-tracer/src/main.rs44
-rw-r--r--racer-tracer/src/material.rs2
-rw-r--r--racer-tracer/src/material/lambertian.rs7
-rw-r--r--racer-tracer/src/scene.rs4
-rw-r--r--racer-tracer/src/vec3.rs94
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::*;