Add cuboids, fox aspect raio
This commit is contained in:
parent
c2d16937ff
commit
9ce878a47a
@ -87,4 +87,6 @@ impl Camera {
|
|||||||
time1
|
time1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn aspect_ratio(&self) -> f64 { self.aspect_ratio }
|
||||||
}
|
}
|
||||||
|
88
src/cuboid.rs
Normal file
88
src/cuboid.rs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
use crate::{Aabb, HittableList, Material, Plane, Point3, Ray, Rect2D};
|
||||||
|
use crate::hittable::{HitRecord, Hittable};
|
||||||
|
|
||||||
|
pub struct Cuboid {
|
||||||
|
minimum: Point3,
|
||||||
|
maximum: Point3,
|
||||||
|
sides: HittableList
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Cuboid {
|
||||||
|
pub fn new(p0: Point3, p1: Point3, material: Arc<Material>) -> Self {
|
||||||
|
let mut sides: HittableList = Vec::with_capacity(6);
|
||||||
|
sides.push(Arc::new(Rect2D::new(
|
||||||
|
Plane::XY,
|
||||||
|
p0.x(),
|
||||||
|
p1.x(),
|
||||||
|
p0.y(),
|
||||||
|
p1.y(),
|
||||||
|
p1.z(),
|
||||||
|
material.clone()
|
||||||
|
)));
|
||||||
|
sides.push(Arc::new(Rect2D::new(
|
||||||
|
Plane::XY,
|
||||||
|
p0.x(),
|
||||||
|
p1.x(),
|
||||||
|
p0.y(),
|
||||||
|
p1.y(),
|
||||||
|
p0.z(),
|
||||||
|
material.clone()
|
||||||
|
)));
|
||||||
|
sides.push(Arc::new(Rect2D::new(
|
||||||
|
Plane::XZ,
|
||||||
|
p0.x(),
|
||||||
|
p1.x(),
|
||||||
|
p0.z(),
|
||||||
|
p1.z(),
|
||||||
|
p1.y(),
|
||||||
|
material.clone()
|
||||||
|
)));
|
||||||
|
sides.push(Arc::new(Rect2D::new(
|
||||||
|
Plane::XZ,
|
||||||
|
p0.x(),
|
||||||
|
p1.x(),
|
||||||
|
p0.z(),
|
||||||
|
p1.z(),
|
||||||
|
p0.y(),
|
||||||
|
material.clone()
|
||||||
|
)));
|
||||||
|
sides.push(Arc::new(Rect2D::new(
|
||||||
|
Plane::YZ,
|
||||||
|
p0.y(),
|
||||||
|
p1.y(),
|
||||||
|
p0.z(),
|
||||||
|
p1.z(),
|
||||||
|
p1.x(),
|
||||||
|
material.clone()
|
||||||
|
)));
|
||||||
|
sides.push(Arc::new(Rect2D::new(
|
||||||
|
Plane::YZ,
|
||||||
|
p0.y(),
|
||||||
|
p1.y(),
|
||||||
|
p0.z(),
|
||||||
|
p1.z(),
|
||||||
|
p0.x(),
|
||||||
|
material.clone()
|
||||||
|
)));
|
||||||
|
|
||||||
|
Cuboid {
|
||||||
|
minimum: p0,
|
||||||
|
maximum: p1,
|
||||||
|
sides
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hittable for Cuboid {
|
||||||
|
fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord> {
|
||||||
|
ray.hit_world(&self.sides, t_min, t_max)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bounding_box(&self, _time0: f64, _time1: f64) -> Option<Aabb> {
|
||||||
|
Some(Aabb {
|
||||||
|
minimum: self.minimum,
|
||||||
|
maximum: self.maximum
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
31
src/main.rs
31
src/main.rs
@ -11,6 +11,7 @@ use rand::distributions::{Distribution, Uniform};
|
|||||||
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
use rayon::iter::{IntoParallelIterator, ParallelIterator};
|
||||||
use crate::material::{Dielectric, DiffuseLight, Lambertian, Material, Metal};
|
use crate::material::{Dielectric, DiffuseLight, Lambertian, Material, Metal};
|
||||||
use crate::aabb::Aabb;
|
use crate::aabb::Aabb;
|
||||||
|
use crate::cuboid::Cuboid;
|
||||||
use crate::image_texture::ImageTexture;
|
use crate::image_texture::ImageTexture;
|
||||||
use crate::noise::NoiseTexture;
|
use crate::noise::NoiseTexture;
|
||||||
use crate::perlin::Perlin;
|
use crate::perlin::Perlin;
|
||||||
@ -30,11 +31,11 @@ mod perlin;
|
|||||||
mod noise;
|
mod noise;
|
||||||
mod image_texture;
|
mod image_texture;
|
||||||
mod rect;
|
mod rect;
|
||||||
|
mod cuboid;
|
||||||
|
|
||||||
// Image
|
// Image
|
||||||
const ASPECT_RATIO: f64 = 3.0 / 2.0;
|
const ASPECT_RATIO: f64 = 3.0 / 2.0;
|
||||||
const IMAGE_WIDTH: usize = 600;
|
const IMAGE_WIDTH: usize = 600;
|
||||||
const IMAGE_HEIGHT: usize = (IMAGE_WIDTH as f64 / ASPECT_RATIO) as usize;
|
|
||||||
const SAMPLES_PER_PIXEL: i32 = 100;
|
const SAMPLES_PER_PIXEL: i32 = 100;
|
||||||
const MAX_DEPTH: i32 = 50;
|
const MAX_DEPTH: i32 = 50;
|
||||||
|
|
||||||
@ -54,6 +55,8 @@ fn cornell_box() -> Scene {
|
|||||||
Lambertian::from(Color::new(0.12, 0.45, 0.15)));
|
Lambertian::from(Color::new(0.12, 0.45, 0.15)));
|
||||||
let light = Material::DiffuseLight(
|
let light = Material::DiffuseLight(
|
||||||
DiffuseLight::from(Color::new(15.0, 15.0, 15.0)));
|
DiffuseLight::from(Color::new(15.0, 15.0, 15.0)));
|
||||||
|
|
||||||
|
// Walls
|
||||||
world.push(Arc::new(Rect2D::new(
|
world.push(Arc::new(Rect2D::new(
|
||||||
Plane::YZ,
|
Plane::YZ,
|
||||||
0.0,
|
0.0,
|
||||||
@ -109,6 +112,19 @@ fn cornell_box() -> Scene {
|
|||||||
white.clone()
|
white.clone()
|
||||||
)));
|
)));
|
||||||
|
|
||||||
|
// Boxes
|
||||||
|
world.push(Arc::new(Cuboid::new(
|
||||||
|
Point3::new(130.0, 0.0, 65.0),
|
||||||
|
Point3::new(295.0, 165.0, 230.0),
|
||||||
|
white.clone()
|
||||||
|
)));
|
||||||
|
world.push(Arc::new(Cuboid::new(
|
||||||
|
Point3::new(265.0, 0.0, 295.0),
|
||||||
|
Point3::new(430.0, 330.0, 460.0),
|
||||||
|
white.clone()
|
||||||
|
)));
|
||||||
|
|
||||||
|
|
||||||
let look_from = Point3::new(278.0, 278.0, -800.0);
|
let look_from = Point3::new(278.0, 278.0, -800.0);
|
||||||
let look_at = Point3::new(278.0, 278.0, 0.0);
|
let look_at = Point3::new(278.0, 278.0, 0.0);
|
||||||
let focus_dist = 2.0;
|
let focus_dist = 2.0;
|
||||||
@ -438,18 +454,19 @@ fn main() {
|
|||||||
let between = Uniform::from(0.0..1.0);
|
let between = Uniform::from(0.0..1.0);
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
let mut pixels = vec![0; IMAGE_WIDTH * IMAGE_HEIGHT * 3];
|
let image_height: usize = (IMAGE_WIDTH as f64 / scene_setup.cam.aspect_ratio()) as usize;
|
||||||
|
let mut pixels = vec![0; IMAGE_WIDTH * image_height * 3];
|
||||||
let bands: Vec<(usize, &mut [u8])> = pixels.chunks_mut(3).enumerate().collect();
|
let bands: Vec<(usize, &mut [u8])> = pixels.chunks_mut(3).enumerate().collect();
|
||||||
let count = Mutex::new(0);
|
let count = Mutex::new(0);
|
||||||
bands.into_par_iter().for_each(|(i, pixel)| {
|
bands.into_par_iter().for_each(|(i, pixel)| {
|
||||||
let row = IMAGE_HEIGHT - (i / IMAGE_WIDTH) - 1;
|
let row = image_height - (i / IMAGE_WIDTH) - 1;
|
||||||
let col = i % IMAGE_WIDTH;
|
let col = i % IMAGE_WIDTH;
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
let mut color = Color::default();
|
let mut color = Color::default();
|
||||||
(0..SAMPLES_PER_PIXEL).for_each(|_s| {
|
(0..SAMPLES_PER_PIXEL).for_each(|_s| {
|
||||||
let random_number = between.sample(&mut rng);
|
let random_number = between.sample(&mut rng);
|
||||||
let u = (col as f64 + random_number) / (IMAGE_WIDTH - 1) as f64;
|
let u = (col as f64 + random_number) / (IMAGE_WIDTH - 1) as f64;
|
||||||
let v = (row as f64 + random_number) / (IMAGE_HEIGHT - 1) as f64;
|
let v = (row as f64 + random_number) / (image_height - 1) as f64;
|
||||||
let ray = scene_setup.cam.get_ray(u, v);
|
let ray = scene_setup.cam.get_ray(u, v);
|
||||||
color += ray.pixel_color(scene_setup.background, &scene_setup.world, MAX_DEPTH);
|
color += ray.pixel_color(scene_setup.background, &scene_setup.world, MAX_DEPTH);
|
||||||
});
|
});
|
||||||
@ -459,15 +476,15 @@ fn main() {
|
|||||||
pixel[2] = bytes[2];
|
pixel[2] = bytes[2];
|
||||||
if i % 100 == 0 {
|
if i % 100 == 0 {
|
||||||
let mut rem = count.lock().unwrap();
|
let mut rem = count.lock().unwrap();
|
||||||
let percent_done_before = 100 * *rem / (IMAGE_WIDTH * IMAGE_HEIGHT);
|
let percent_done_before = 100 * *rem / (IMAGE_WIDTH * image_height);
|
||||||
*rem += 100;
|
*rem += 100;
|
||||||
let percent_done_after = 100 * *rem / (IMAGE_WIDTH * IMAGE_HEIGHT);
|
let percent_done_after = 100 * *rem / (IMAGE_WIDTH * image_height);
|
||||||
if percent_done_before != percent_done_after {
|
if percent_done_before != percent_done_after {
|
||||||
eprint!("\rProgress: {}% ", percent_done_after);
|
eprint!("\rProgress: {}% ", percent_done_after);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
PNG::write("imc.png", &pixels, IMAGE_WIDTH, IMAGE_HEIGHT).expect("Error writing image: {}");
|
PNG::write("imc.png", &pixels, IMAGE_WIDTH, image_height).expect("Error writing image: {}");
|
||||||
eprintln!("\nDone. Time: {}ms", start.elapsed().as_millis());
|
eprintln!("\nDone. Time: {}ms", start.elapsed().as_millis());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
32
src/ray.rs
32
src/ray.rs
@ -29,36 +29,6 @@ impl Ray {
|
|||||||
if depth <= 0 {
|
if depth <= 0 {
|
||||||
return Color::default();
|
return Color::default();
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if let Some(rect) = self.hit_world(world, 0.001, f64::INFINITY) {
|
|
||||||
let scattered = rect.material.scatter(self, &rect);
|
|
||||||
return match scattered {
|
|
||||||
Some((scattered_ray, albedo)) => {
|
|
||||||
match scattered_ray {
|
|
||||||
Some(sr) => {
|
|
||||||
albedo * sr.pixel_color(background, world, depth-1)
|
|
||||||
},
|
|
||||||
None => albedo
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => { return background }
|
|
||||||
};
|
|
||||||
|
|
||||||
} else {
|
|
||||||
let unit_direction = self.direction().unit_vector();
|
|
||||||
let t = 0.5 * (unit_direction.y() + 1.0);
|
|
||||||
return (1.0 - t) * Color::new(1.0, 1.0, 1.0) + t * Color::new(0.5, 0.7, 1.0);
|
|
||||||
//return background;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Hot nothing, display sky color
|
|
||||||
let unit_direction = self.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)
|
|
||||||
//return background;
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
match self.hit_world(world, 0.001, f64::INFINITY) {
|
match self.hit_world(world, 0.001, f64::INFINITY) {
|
||||||
Some(rect) => {
|
Some(rect) => {
|
||||||
let scattered = rect.material.scatter(self, &rect);
|
let scattered = rect.material.scatter(self, &rect);
|
||||||
@ -78,7 +48,7 @@ impl Ray {
|
|||||||
None => background
|
None => background
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn hit_world<'material>(
|
pub fn hit_world<'material>(
|
||||||
&self,
|
&self,
|
||||||
world: &'material HittableList,
|
world: &'material HittableList,
|
||||||
t_min: f64,
|
t_min: f64,
|
||||||
|
Loading…
Reference in New Issue
Block a user