Compare commits
3 Commits
0f1f128387
...
d8a3d4c989
| Author | SHA1 | Date | |
|---|---|---|---|
|
d8a3d4c989
|
|||
|
44f8803f41
|
|||
|
bff7c79abd
|
@@ -2,3 +2,4 @@
|
|||||||

|

|
||||||
### quick and dirty multithreaded raymarcher using the awesome [_Ray Tracing in One Weekend_](https://raytracing.github.io/books/RayTracingInOneWeekend.html) Book Series
|
### quick and dirty multithreaded raymarcher using the awesome [_Ray Tracing in One Weekend_](https://raytracing.github.io/books/RayTracingInOneWeekend.html) Book Series
|
||||||

|

|
||||||
|

|
||||||
BIN
example_dark.png
Normal file
BIN
example_dark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.8 MiB |
@@ -73,21 +73,24 @@ impl Camera {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(rec) = world.hit(&r, 0.001, f64::INFINITY) {
|
if let Some(rec) = world.hit(&r, 0.001, f64::INFINITY) {
|
||||||
|
let emitted = rec.material.emitted();
|
||||||
let mut scattered = Ray::new_empty();
|
let mut scattered = Ray::new_empty();
|
||||||
let mut attenuation = Color::new_empty();
|
let mut attenuation = Color::new_empty();
|
||||||
|
|
||||||
if rec
|
if rec
|
||||||
.material
|
.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();
|
// Sky background
|
||||||
let t = 0.5 * (unit_direction.y() + 1.0);
|
// 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))
|
//((1.0 - t) * Color::new(1.0, 1.0, 1.0)) + (t * Color::new(0.5, 0.7, 1.0))
|
||||||
|
Color::new_empty()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
src/color.rs
12
src/color.rs
@@ -1,6 +1,8 @@
|
|||||||
use crate::{vec3::*, rtweekend::clamp};
|
use image::Rgb;
|
||||||
|
|
||||||
pub fn get_scaled_color_components(c: Color, samples_per_pixel: i32) -> (u8, u8, u8) {
|
use crate::{rtweekend::clamp, vec3::*};
|
||||||
|
|
||||||
|
pub fn get_scaled_color_components(c: Color, samples_per_pixel: i32) -> Rgb<u8> {
|
||||||
let r = c.x();
|
let r = c.x();
|
||||||
let g = c.y();
|
let g = c.y();
|
||||||
let b = c.z();
|
let b = c.z();
|
||||||
@@ -11,9 +13,9 @@ pub fn get_scaled_color_components(c: Color, samples_per_pixel: i32) -> (u8, u8,
|
|||||||
let g = (scale * g).sqrt();
|
let g = (scale * g).sqrt();
|
||||||
let b = (scale * b).sqrt();
|
let b = (scale * b).sqrt();
|
||||||
|
|
||||||
(
|
Rgb([
|
||||||
(255.0 * clamp(r, 0.0, 1.0)) as u8,
|
(255.0 * clamp(r, 0.0, 1.0)) as u8,
|
||||||
(255.0 * clamp(g, 0.0, 1.0)) as u8,
|
(255.0 * clamp(g, 0.0, 1.0)) as u8,
|
||||||
(255.0 * clamp(b, 0.0, 1.0)) as u8,
|
(255.0 * clamp(b, 0.0, 1.0)) as u8,
|
||||||
)
|
])
|
||||||
}
|
}
|
||||||
|
|||||||
27
src/main.rs
27
src/main.rs
@@ -10,7 +10,7 @@ pub mod vec3;
|
|||||||
|
|
||||||
use std::{f64, thread::available_parallelism};
|
use std::{f64, thread::available_parallelism};
|
||||||
|
|
||||||
use image::{Pixel, RgbImage};
|
use image::RgbImage;
|
||||||
use indicatif::{ProgressBar, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
use rayon::prelude::*;
|
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);
|
let material1: Dielectric = Dielectric::new(1.5);
|
||||||
world.add(Box::new(Sphere::new(
|
world.add(Box::new(Sphere::new(
|
||||||
Point3::new(0.0, 1.0, 0.0),
|
Point3::new(0.0, 1.0, 0.0),
|
||||||
@@ -159,15 +166,15 @@ fn three_balls_scene(aspect_ratio: f64) -> (Camera, HittableList) {
|
|||||||
let lookfrom = Point3::new(-2.0, 2.0, 1.0);
|
let lookfrom = Point3::new(-2.0, 2.0, 1.0);
|
||||||
let lookat = Point3::new(0.0, 0.0, -1.0);
|
let lookat = Point3::new(0.0, 0.0, -1.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 = 10.0; //(lookfrom - lookat).length_squared();
|
let dist_to_focus = (lookfrom - lookat).length();
|
||||||
let vfov = 20.0;
|
let focal_length_mm = 20.0;
|
||||||
let defocus_angle = 0.0;
|
let defocus_angle = 0.0;
|
||||||
|
|
||||||
let cam = Camera::new(
|
let cam = Camera::new(
|
||||||
lookfrom,
|
lookfrom,
|
||||||
lookat,
|
lookat,
|
||||||
vup,
|
vup,
|
||||||
vfov,
|
focal_length_mm,
|
||||||
aspect_ratio,
|
aspect_ratio,
|
||||||
defocus_angle,
|
defocus_angle,
|
||||||
dist_to_focus,
|
dist_to_focus,
|
||||||
@@ -181,10 +188,9 @@ fn main() {
|
|||||||
let aspect_ratio: f64 = 16. / 9.;
|
let aspect_ratio: f64 = 16. / 9.;
|
||||||
let image_width: i32 = 1920;
|
let image_width: i32 = 1920;
|
||||||
let image_height: i32 = (image_width as f64 / aspect_ratio as f64) as i32;
|
let image_height: i32 = (image_width as f64 / aspect_ratio as f64) as i32;
|
||||||
let samples_per_pixel: i32 = 200;
|
let samples_per_pixel: i32 = 400;
|
||||||
let max_depth: i32 = 10;
|
let max_depth: i32 = 10;
|
||||||
|
|
||||||
// Camera and World
|
|
||||||
let (cam, world) = random_scene(aspect_ratio);
|
let (cam, world) = random_scene(aspect_ratio);
|
||||||
|
|
||||||
let num_threads: usize = match available_parallelism() {
|
let num_threads: usize = match available_parallelism() {
|
||||||
@@ -226,11 +232,7 @@ fn main() {
|
|||||||
pixel_color += cam.ray_color(r, &world, max_depth);
|
pixel_color += cam.ray_color(r, &world, max_depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (ir, ig, ib) = get_scaled_color_components(pixel_color, samples_per_pixel);
|
*pixel = get_scaled_color_components(pixel_color, samples_per_pixel);
|
||||||
|
|
||||||
pixel.channels_mut()[0] = ir;
|
|
||||||
pixel.channels_mut()[1] = ig;
|
|
||||||
pixel.channels_mut()[2] = ib;
|
|
||||||
|
|
||||||
bar.inc(1);
|
bar.inc(1);
|
||||||
});
|
});
|
||||||
@@ -239,6 +241,3 @@ fn main() {
|
|||||||
|
|
||||||
img_buffer.save("render.png").unwrap();
|
img_buffer.save("render.png").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
// print!("\r{} %", progress);
|
|
||||||
// let _ = stdout().flush();
|
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ use crate::vec3::{random_unit_vector, reflect, refract, Color};
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
pub trait Material: Send + Sync {
|
pub trait Material: Send + Sync {
|
||||||
|
fn emitted(&self) -> Color {
|
||||||
|
Color::new(0.0, 0.0, 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
fn scatter(
|
fn scatter(
|
||||||
&self,
|
&self,
|
||||||
r_in: Ray,
|
r_in: Ray,
|
||||||
@@ -134,3 +138,29 @@ impl Material for Dielectric {
|
|||||||
true
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user