Compare commits
7 Commits
657bbacde3
...
e651cc3ee0
| Author | SHA1 | Date | |
|---|---|---|---|
|
e651cc3ee0
|
|||
|
25a3661fd0
|
|||
|
5bdd7d8121
|
|||
|
2e92d9ed1e
|
|||
|
e906e14254
|
|||
|
5d866a2b9e
|
|||
|
d32ee59ca9
|
22
.gitea/workflows/build.yml
Normal file
22
.gitea/workflows/build.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
name: Build & Test
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
pull_request:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
env:
|
||||||
|
CARGO_TERM_COLOR: always
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Build
|
||||||
|
run: cargo build --verbose
|
||||||
|
- name: Run tests
|
||||||
|
run: cargo test --verbose
|
||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,4 +8,5 @@ Cargo.lock
|
|||||||
|
|
||||||
# These are backup files generated by rustfmt
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
img.ppm
|
|
||||||
|
render.png
|
||||||
@@ -8,4 +8,5 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "0.7.0"
|
rand = "0.7.0"
|
||||||
rayon = "1.8"
|
rayon = "1.8"
|
||||||
image = "0.25.9"
|
image = "0.25.9"
|
||||||
|
indicatif = "0.18.3"
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
# raychel-rs
|
# raychel-rs
|
||||||
### quick and dirty multithreaded raymarcher using the awesome ["ray tracing in one weekend" Book Series](https://raytracing.github.io/)
|
### quick and dirty multithreaded raymarcher using the awesome [_Ray Tracing in One Weekend_](https://raytracing.github.io/books/RayTracingInOneWeekend.html) Book Series
|
||||||

|

|
||||||
BIN
example.png
Normal file
BIN
example.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
75
src/main.rs
75
src/main.rs
@@ -8,7 +8,10 @@ pub mod rtweekend;
|
|||||||
pub mod sphere;
|
pub mod sphere;
|
||||||
pub mod vec3;
|
pub mod vec3;
|
||||||
|
|
||||||
|
use std::{f64, thread::available_parallelism};
|
||||||
|
|
||||||
use image::{Pixel, RgbImage};
|
use image::{Pixel, RgbImage};
|
||||||
|
use indicatif::{ProgressBar, ProgressStyle};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -27,15 +30,15 @@ use crate::{
|
|||||||
fn random_scene() -> HittableList {
|
fn random_scene() -> HittableList {
|
||||||
let mut world = HittableList::new_empty();
|
let mut world = HittableList::new_empty();
|
||||||
|
|
||||||
static GROUND_MATERIAL: Lambertian = Lambertian::new(Color::new(0.5, 0.5, 0.5));
|
let ground_material: Lambertian = Lambertian::new(Color::new(0.5, 0.5, 0.5));
|
||||||
world.add(Box::new(Sphere::new(
|
world.add(Box::new(Sphere::new(
|
||||||
Point3::new(0.0, -1000.0, 0.0),
|
Point3::new(0.0, -1000.0, 0.0),
|
||||||
1000.0,
|
1000.0,
|
||||||
&GROUND_MATERIAL,
|
Box::new(ground_material),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
for a in 0..12 {
|
for a in -12..12 {
|
||||||
for b in 0..12 {
|
for b in -12..12 {
|
||||||
let choose_mat = random_f64();
|
let choose_mat = random_f64();
|
||||||
let center = Point3::new(
|
let center = Point3::new(
|
||||||
a as f64 + 0.9 * random_f64(),
|
a as f64 + 0.9 * random_f64(),
|
||||||
@@ -46,38 +49,38 @@ fn random_scene() -> HittableList {
|
|||||||
if (center - Point3::new(4.0, 0.2, 0.0)).length() > 0.9 {
|
if (center - Point3::new(4.0, 0.2, 0.0)).length() > 0.9 {
|
||||||
if choose_mat < 0.8 {
|
if choose_mat < 0.8 {
|
||||||
//let albedo = Color::new(0.3, 0.8, 0.4);
|
//let albedo = Color::new(0.3, 0.8, 0.4);
|
||||||
static SPHERE_MATERIAL: Lambertian = Lambertian::new(Color::new(0.3, 0.8, 0.4));
|
let sphere_material: Lambertian = Lambertian::new(Color::random());
|
||||||
world.add(Box::new(Sphere::new(center, 0.2, &SPHERE_MATERIAL)));
|
world.add(Box::new(Sphere::new(center, 0.2, Box::new(sphere_material))));
|
||||||
} else if choose_mat < 0.95 {
|
} else if choose_mat < 0.95 {
|
||||||
static SPHERE_MATERIAL: Metal = Metal::new(Color::new(0.3, 0.6, 0.2), 0.2);
|
let sphere_material: Metal = Metal::new(Color::random(), 0.2);
|
||||||
world.add(Box::new(Sphere::new(center, 0.2, &SPHERE_MATERIAL)));
|
world.add(Box::new(Sphere::new(center, 0.2, Box::new(sphere_material))));
|
||||||
} else {
|
} else {
|
||||||
static SPHERE_MATERIAL: Dielectric = Dielectric::new(1.5);
|
let sphere_material: Dielectric = Dielectric::new(1.5);
|
||||||
world.add(Box::new(Sphere::new(center, 0.2, &SPHERE_MATERIAL)));
|
world.add(Box::new(Sphere::new(center, 0.2, Box::new(sphere_material))));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static 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),
|
||||||
1.0,
|
1.0,
|
||||||
&MATERIAL1,
|
Box::new(material1),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
static MATERIAL2: Lambertian = Lambertian::new(Color::new(0.4, 0.2, 0.1));
|
let material2: Lambertian = Lambertian::new(Color::new(0.4, 0.2, 0.1));
|
||||||
world.add(Box::new(Sphere::new(
|
world.add(Box::new(Sphere::new(
|
||||||
Point3::new(-4.0, 1.0, 0.0),
|
Point3::new(-4.0, 1.0, 0.0),
|
||||||
1.0,
|
1.0,
|
||||||
&MATERIAL2,
|
Box::new(material2),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
static MATERIAL3: Metal = Metal::new(Color::new(0.7, 0.6, 0.5), 0.0);
|
let material3: Metal = Metal::new(Color::new(0.7, 0.6, 0.5), 0.0);
|
||||||
world.add(Box::new(Sphere::new(
|
world.add(Box::new(Sphere::new(
|
||||||
Point3::new(4.0, 1.0, 0.0),
|
Point3::new(4.0, 1.0, 0.0),
|
||||||
1.0,
|
1.0,
|
||||||
&MATERIAL3,
|
Box::new(material3),
|
||||||
)));
|
)));
|
||||||
|
|
||||||
world
|
world
|
||||||
@@ -110,17 +113,17 @@ fn ray_color(r: Ray, world: &dyn Hittable, depth: i32) -> Color {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Image
|
// Image
|
||||||
let aspect_ratio: f64 = 1.0 / 1.0;
|
let aspect_ratio: f64 = 16. / 9.;
|
||||||
let image_height: i32 = 1000;
|
let image_width: i32 = 1920;
|
||||||
let image_width: i32 = (image_height 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 = 50;
|
let samples_per_pixel: i32 = 200;
|
||||||
let max_depth: i32 = 4;
|
let max_depth: i32 = 5;
|
||||||
|
|
||||||
// World
|
// World
|
||||||
let world = random_scene();
|
let world = random_scene();
|
||||||
|
|
||||||
// Camera
|
// Camera
|
||||||
let lookfrom = Point3::new(-13.0, 2.0, 3.0);
|
let lookfrom = Point3::new(13.0, 2.0, 3.0);
|
||||||
let lookat = Point3::new(0.0, 0.0, 0.0);
|
let lookat = Point3::new(0.0, 0.0, 0.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 = 10.0; //(lookfrom-lookat).length_squared();
|
||||||
@@ -135,14 +138,31 @@ fn main() {
|
|||||||
dist_to_focus,
|
dist_to_focus,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
let num_threads: usize = match available_parallelism() {
|
||||||
|
Ok(threads) => threads.into(),
|
||||||
|
Err(_) => 1,
|
||||||
|
};
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
rayon::ThreadPoolBuilder::new()
|
rayon::ThreadPoolBuilder::new()
|
||||||
.num_threads(11)
|
.num_threads(num_threads)
|
||||||
.build_global()
|
.build_global()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut img_buffer = RgbImage::new(image_width as u32, image_height as u32);
|
let mut img_buffer = RgbImage::new(image_width as u32, image_height as u32);
|
||||||
|
|
||||||
|
let total_pixels = (image_width * image_height) as u64;
|
||||||
|
let bar = ProgressBar::new(total_pixels);
|
||||||
|
|
||||||
|
bar.set_style(
|
||||||
|
ProgressStyle::default_bar()
|
||||||
|
.template(
|
||||||
|
"{spinner:.green} [{elapsed_precise}] [{bar:40.green/black}] {percent}% ({eta})",
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.progress_chars("#>-"),
|
||||||
|
);
|
||||||
|
|
||||||
img_buffer
|
img_buffer
|
||||||
.par_enumerate_pixels_mut()
|
.par_enumerate_pixels_mut()
|
||||||
.for_each(|(x, y, pixel)| {
|
.for_each(|(x, y, pixel)| {
|
||||||
@@ -162,7 +182,14 @@ fn main() {
|
|||||||
pixel.channels_mut()[0] = ir;
|
pixel.channels_mut()[0] = ir;
|
||||||
pixel.channels_mut()[1] = ig;
|
pixel.channels_mut()[1] = ig;
|
||||||
pixel.channels_mut()[2] = ib;
|
pixel.channels_mut()[2] = ib;
|
||||||
|
|
||||||
|
bar.inc(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
img_buffer.save("img.png").unwrap();
|
bar.finish_with_message("Render Complete!");
|
||||||
|
|
||||||
|
img_buffer.save("render.png").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print!("\r{} %", progress);
|
||||||
|
// let _ = stdout().flush();
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
use crate::hittable::*;
|
use crate::hittable::*;
|
||||||
use crate::material::Material;
|
use crate::material::Material;
|
||||||
use crate::vec3::*;
|
use crate::vec3::*;
|
||||||
|
use crate::Ray;
|
||||||
|
|
||||||
pub struct Sphere<'a> {
|
pub struct Sphere {
|
||||||
center: Point3,
|
center: Point3,
|
||||||
radius: f64,
|
radius: f64,
|
||||||
mat_ptr: &'a dyn Material,
|
mat_ptr: Box<dyn Material>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Sphere<'_> {
|
impl Sphere {
|
||||||
pub fn new<T: Material>(center: Point3, radius: f64, mat_ptr: &'static T) -> Self {
|
pub fn new<T: Material + 'static>(center: Point3, radius: f64, mat_ptr: Box<T>) -> Self {
|
||||||
Sphere {center, radius, mat_ptr}
|
Sphere {center, radius, mat_ptr}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hittable for Sphere<'_> {
|
impl Hittable for Sphere {
|
||||||
fn hit(&self, r: &crate::ray::Ray, t_min: f64, t_max: f64) -> Option<HitRecord<'_>> {
|
fn hit(&self, r: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord<'_>> {
|
||||||
let oc = r.origin() - self.center;
|
let oc = r.origin() - self.center;
|
||||||
let a = r.direction().length_squared();
|
let a = r.direction().length_squared();
|
||||||
let half_b = oc.dot(&r.direction());
|
let half_b = oc.dot(&r.direction());
|
||||||
@@ -51,7 +54,7 @@ impl Hittable for Sphere<'_> {
|
|||||||
p: p,
|
p: p,
|
||||||
normal: outward_normal,
|
normal: outward_normal,
|
||||||
front_face,
|
front_face,
|
||||||
mat_ptr: self.mat_ptr,
|
mat_ptr: self.mat_ptr.deref(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user