diff --git a/README.md b/README.md index c9a5011..88e1bff 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,4 @@ ![Build](https://git.veltko.de/plexx-dev/raychel-rs/actions/workflows/build.yml/badge.svg?branch=main&event=push&style=flat-square) ### quick and dirty multithreaded raymarcher using the awesome [_Ray Tracing in One Weekend_](https://raytracing.github.io/books/RayTracingInOneWeekend.html) Book Series ![Example Scene](example.png) +![Example Dark Scene](example_dark.png) \ No newline at end of file diff --git a/example_dark.png b/example_dark.png new file mode 100644 index 0000000..e32e123 Binary files /dev/null and b/example_dark.png differ diff --git a/src/camera.rs b/src/camera.rs index 50e3ab6..4130a51 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -73,21 +73,24 @@ impl Camera { } if let Some(rec) = world.hit(&r, 0.001, f64::INFINITY) { + let emitted = rec.material.emitted(); let mut scattered = Ray::new_empty(); let mut attenuation = Color::new_empty(); if rec .material - .scatter(r, rec, &mut attenuation, &mut scattered) + .scatter(r, rec.clone(), &mut attenuation, &mut scattered) { - return attenuation * Self::ray_color(&self, scattered, world, depth - 1); + return emitted + attenuation * self.ray_color(scattered, world, depth - 1); + } else { + return emitted; } - return Color::new_empty(); } - let unit_direction: Vec3 = r.direction().unit_vector(); - let t = 0.5 * (unit_direction.y() + 1.0); - - ((1.0 - t) * Color::new(1.0, 1.0, 1.0)) + (t * Color::new(0.5, 0.7, 1.0)) + // Sky background + // let unit_direction: Vec3 = r.direction().unit_vector(); + // let t = 0.5 * (unit_direction.y() + 1.0); + //((1.0 - t) * Color::new(1.0, 1.0, 1.0)) + (t * Color::new(0.5, 0.7, 1.0)) + Color::new_empty() } } diff --git a/src/main.rs b/src/main.rs index 5fa10f5..841b870 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,7 @@ pub mod vec3; use std::{f64, thread::available_parallelism}; -use image::{Pixel, RgbImage}; +use image::RgbImage; use indicatif::{ProgressBar, ProgressStyle}; use rayon::prelude::*; @@ -74,6 +74,13 @@ fn random_scene(aspect_ratio: f64) -> (Camera, HittableList) { } } + let material0 = Light::new(Color::new(15., 15., 15.)); + world.add(Box::new(Sphere::new( + Point3::new(-1.0, 1.0, 0.0), + 1.0, + Box::new(material0), + ))); + let material1: Dielectric = Dielectric::new(1.5); world.add(Box::new(Sphere::new( Point3::new(0.0, 1.0, 0.0), @@ -179,10 +186,10 @@ fn three_balls_scene(aspect_ratio: f64) -> (Camera, HittableList) { fn main() { // Image let aspect_ratio: f64 = 16. / 9.; - let image_width: i32 = 500; + let image_width: i32 = 1920; let image_height: i32 = (image_width as f64 / aspect_ratio as f64) as i32; - let samples_per_pixel: i32 = 50; - let max_depth: i32 = 4; + let samples_per_pixel: i32 = 400; + let max_depth: i32 = 10; let (cam, world) = random_scene(aspect_ratio); diff --git a/src/material.rs b/src/material.rs index 32ad529..758f2fd 100644 --- a/src/material.rs +++ b/src/material.rs @@ -16,6 +16,10 @@ use crate::vec3::{random_unit_vector, reflect, refract, Color}; */ pub trait Material: Send + Sync { + fn emitted(&self) -> Color { + Color::new(0.0, 0.0, 0.0) + } + fn scatter( &self, r_in: Ray, @@ -134,3 +138,29 @@ impl Material for Dielectric { true } } + +pub struct Light { + emit: Color +} + +impl Light { + pub const fn new(emit: Color) -> Self { + Light { emit } + } +} + +impl Material for Light { + fn scatter( + &self, + _r_in: Ray, + _rec: HitRecord, + _attenuation: &mut Color, + _scattered: &mut Ray, + ) -> bool { + false // Light sources dont scatter rays + } + + fn emitted(&self) -> Color { + self.emit + } +} \ No newline at end of file