Add rects
This commit is contained in:
parent
14b5b2b125
commit
429b87e912
115
src/main.rs
115
src/main.rs
@ -15,7 +15,7 @@ use crate::image_texture::ImageTexture;
|
|||||||
use crate::noise::NoiseTexture;
|
use crate::noise::NoiseTexture;
|
||||||
use crate::perlin::Perlin;
|
use crate::perlin::Perlin;
|
||||||
use crate::texture::CheckerTexture;
|
use crate::texture::CheckerTexture;
|
||||||
use crate::xy_rect::XyRect;
|
use crate::rect::{Plane, Rect2D};
|
||||||
|
|
||||||
mod vec3;
|
mod vec3;
|
||||||
mod ray;
|
mod ray;
|
||||||
@ -29,13 +29,13 @@ mod texture;
|
|||||||
mod perlin;
|
mod perlin;
|
||||||
mod noise;
|
mod noise;
|
||||||
mod image_texture;
|
mod image_texture;
|
||||||
mod xy_rect;
|
mod rect;
|
||||||
|
|
||||||
// Image
|
// Image
|
||||||
const ASPECT_RATIO: f64 = 3.0 / 2.0;
|
const ASPECT_RATIO: f64 = 3.0 / 2.0;
|
||||||
const IMAGE_WIDTH: usize = 400;
|
const IMAGE_WIDTH: usize = 600;
|
||||||
const IMAGE_HEIGHT: usize = (IMAGE_WIDTH as f64 / ASPECT_RATIO) as usize;
|
const IMAGE_HEIGHT: usize = (IMAGE_WIDTH as f64 / ASPECT_RATIO) as usize;
|
||||||
const SAMPLES_PER_PIXEL: i32 = 100;
|
const SAMPLES_PER_PIXEL: i32 = 800;
|
||||||
const MAX_DEPTH: i32 = 50;
|
const MAX_DEPTH: i32 = 50;
|
||||||
|
|
||||||
struct Scene {
|
struct Scene {
|
||||||
@ -44,6 +44,93 @@ struct Scene {
|
|||||||
pub background: Color
|
pub background: Color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cornell_box() -> Scene {
|
||||||
|
let mut world:HittableList = Vec::new();
|
||||||
|
let red = Material::Lambertian(
|
||||||
|
Lambertian::new(Color::new(0.65, 0.05, 0.05)));
|
||||||
|
let white = Arc::new(Material::Lambertian(
|
||||||
|
Lambertian::new(Color::new(0.73, 0.73, 0.73))));
|
||||||
|
let green = Material::Lambertian(
|
||||||
|
Lambertian::new(Color::new(0.12, 0.45, 0.15)));
|
||||||
|
let light = Material::DiffuseLight(
|
||||||
|
DiffuseLight::from(Color::new(15.0, 15.0, 15.0)));
|
||||||
|
world.push(Arc::new(Rect2D::new(
|
||||||
|
Plane::YZ,
|
||||||
|
0.0,
|
||||||
|
555.0,
|
||||||
|
0.0,
|
||||||
|
555.0,
|
||||||
|
555.0,
|
||||||
|
Arc::new(green)
|
||||||
|
)));
|
||||||
|
world.push(Arc::new(Rect2D::new(
|
||||||
|
Plane::YZ,
|
||||||
|
0.0,
|
||||||
|
555.0,
|
||||||
|
0.0,
|
||||||
|
555.0,
|
||||||
|
0.0,
|
||||||
|
Arc::new(red)
|
||||||
|
)));
|
||||||
|
world.push(Arc::new(Rect2D::new(
|
||||||
|
Plane::XZ,
|
||||||
|
213.0,
|
||||||
|
343.0,
|
||||||
|
227.0,
|
||||||
|
332.0,
|
||||||
|
554.0,
|
||||||
|
Arc::new(light)
|
||||||
|
)));
|
||||||
|
world.push(Arc::new(Rect2D::new(
|
||||||
|
Plane::XZ,
|
||||||
|
0.0,
|
||||||
|
555.0,
|
||||||
|
0.0,
|
||||||
|
555.0,
|
||||||
|
0.0,
|
||||||
|
white.clone()
|
||||||
|
)));
|
||||||
|
world.push(Arc::new(Rect2D::new(
|
||||||
|
Plane::XZ,
|
||||||
|
0.0,
|
||||||
|
555.0,
|
||||||
|
0.0,
|
||||||
|
555.0,
|
||||||
|
555.0,
|
||||||
|
white.clone()
|
||||||
|
)));
|
||||||
|
world.push(Arc::new(Rect2D::new(
|
||||||
|
Plane::XY,
|
||||||
|
0.0,
|
||||||
|
555.0,
|
||||||
|
0.0,
|
||||||
|
555.0,
|
||||||
|
555.0,
|
||||||
|
white.clone()
|
||||||
|
)));
|
||||||
|
|
||||||
|
let look_from = Point3::new(278.0, 278.0, -800.0);
|
||||||
|
let look_at = Point3::new(278.0, 278.0, 0.0);
|
||||||
|
let focus_dist = 2.0;
|
||||||
|
|
||||||
|
let cam = Camera::new(
|
||||||
|
look_from,
|
||||||
|
look_at,
|
||||||
|
Vec3::new(0.0, 1.0, 0.0),
|
||||||
|
1.0,
|
||||||
|
40.0,
|
||||||
|
0.0,
|
||||||
|
focus_dist,
|
||||||
|
0.0,
|
||||||
|
1.0);
|
||||||
|
|
||||||
|
Scene {
|
||||||
|
world,
|
||||||
|
cam,
|
||||||
|
background: Color::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn simple_light() -> Scene {
|
fn simple_light() -> Scene {
|
||||||
let mut world:HittableList = Vec::new();
|
let mut world:HittableList = Vec::new();
|
||||||
|
|
||||||
@ -64,14 +151,15 @@ fn simple_light() -> Scene {
|
|||||||
let difflight = Material::DiffuseLight(
|
let difflight = Material::DiffuseLight(
|
||||||
// Brighter than 1.0/1.0/1.0 so it can light things
|
// Brighter than 1.0/1.0/1.0 so it can light things
|
||||||
DiffuseLight::from(Color::new(4.0, 4.0, 4.0)));
|
DiffuseLight::from(Color::new(4.0, 4.0, 4.0)));
|
||||||
world.push(Arc::new(XyRect {
|
world.push(Arc::new(Rect2D::new(
|
||||||
x0: 3.0,
|
Plane::XY,
|
||||||
x1: 5.0,
|
3.0,
|
||||||
y0: 1.0,
|
5.0,
|
||||||
y1: 3.0,
|
1.0,
|
||||||
k: -2.0,
|
3.0,
|
||||||
material: Arc::new(difflight)
|
-2.0,
|
||||||
}));
|
Arc::new(difflight)
|
||||||
|
)));
|
||||||
|
|
||||||
let look_from = Point3::new(26.0, 3.0, 6.0);
|
let look_from = Point3::new(26.0, 3.0, 6.0);
|
||||||
let look_at = Point3::new(0.0, 2.0, 0.0);
|
let look_at = Point3::new(0.0, 2.0, 0.0);
|
||||||
@ -336,13 +424,14 @@ fn random_scene() -> Scene {
|
|||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// World
|
// World
|
||||||
let scene: u8 = 4;
|
let scene: u8 = 5;
|
||||||
let scene_setup = match scene {
|
let scene_setup = match scene {
|
||||||
0 => two_spheres(),
|
0 => two_spheres(),
|
||||||
1 => two_perlin_spheres(),
|
1 => two_perlin_spheres(),
|
||||||
2 => earth(),
|
2 => earth(),
|
||||||
3 => sun(),
|
3 => sun(),
|
||||||
4 => simple_light(),
|
4 => simple_light(),
|
||||||
|
5 => cornell_box(),
|
||||||
_ => random_scene(),
|
_ => random_scene(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
88
src/rect.rs
Normal file
88
src/rect.rs
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
use crate::hittable::{HitRecord, Hittable};
|
||||||
|
use crate::{Aabb, Material, Point3, Ray, Vec3};
|
||||||
|
|
||||||
|
pub enum Plane {
|
||||||
|
XY,
|
||||||
|
XZ,
|
||||||
|
YZ
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Rect2D {
|
||||||
|
plane: Plane,
|
||||||
|
a0: f64,
|
||||||
|
a1: f64,
|
||||||
|
b0: f64,
|
||||||
|
b1: f64,
|
||||||
|
k: f64,
|
||||||
|
material: Arc<Material>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Rect2D {
|
||||||
|
pub fn new(plane: Plane, a0: f64, a1: f64, b0: f64, b1: f64, k: f64, material: Arc<Material>) -> Self {
|
||||||
|
Self { plane, a0, a1, b0, b1, k, material }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hittable for Rect2D {
|
||||||
|
fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord> {
|
||||||
|
let t = match &self.plane {
|
||||||
|
Plane::XY => (self.k - ray.origin().z()) / ray.direction().z(),
|
||||||
|
Plane::XZ => (self.k - ray.origin().y()) / ray.direction().y(),
|
||||||
|
Plane::YZ => (self.k - ray.origin().x()) / ray.direction().x(),
|
||||||
|
};
|
||||||
|
let (a, b) = match &self.plane {
|
||||||
|
Plane::XY => (
|
||||||
|
ray.origin().x() + t * ray.direction().x(),
|
||||||
|
ray.origin().y() + t * ray.direction().y()),
|
||||||
|
Plane::XZ => (
|
||||||
|
ray.origin().x() + t * ray.direction().x(),
|
||||||
|
ray.origin().z() + t * ray.direction().z()),
|
||||||
|
Plane::YZ => (
|
||||||
|
ray.origin().y() + t * ray.direction().y(),
|
||||||
|
ray.origin().z() + t * ray.direction().z()),
|
||||||
|
};
|
||||||
|
if t < t_min || t > t_max {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
if a < self.a0 || a > self.a1 || b < self.b0 || b > self.b1 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let normal = match &self.plane {
|
||||||
|
Plane::XY => Vec3::new(0.0, 0.0, 1.0),
|
||||||
|
Plane::XZ => Vec3::new(0.0, 1.0, 0.0),
|
||||||
|
Plane::YZ => Vec3::new(1.0, 0.0, 0.0),
|
||||||
|
};
|
||||||
|
let dot = ray.direction().dot(&normal);
|
||||||
|
let front_face = dot < 0.0;
|
||||||
|
let normal = if front_face { normal } else { -normal };
|
||||||
|
Some(HitRecord {
|
||||||
|
point: ray.at(t),
|
||||||
|
normal,
|
||||||
|
t,
|
||||||
|
u: (a-self.a0)/(self.a1 -self.a0),
|
||||||
|
v: (b-self.b0)/(self.b1 -self.b0),
|
||||||
|
front_face,
|
||||||
|
material: &self.material
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bounding_box(&self, _time0: f64, _time1: f64) -> Option<Aabb> {
|
||||||
|
// The bounding box must have non-zero width in each dimension, so pad the Z
|
||||||
|
// dimension a small amount.
|
||||||
|
match &self.plane {
|
||||||
|
Plane::XY => Some(Aabb {
|
||||||
|
minimum: Point3::new(self.a0, self.b0, self.k-0.0001),
|
||||||
|
maximum: Point3::new(self.a1, self.b1, self.k+0.0001),
|
||||||
|
}),
|
||||||
|
Plane::XZ=> Some(Aabb {
|
||||||
|
minimum: Point3::new(self.a0, self.k-0.0001, self.b0),
|
||||||
|
maximum: Point3::new(self.a1, self.k+0.0001, self.b1),
|
||||||
|
}),
|
||||||
|
Plane::YZ => Some(Aabb {
|
||||||
|
minimum: Point3::new(self.k-0.0001, self.a0, self.b0),
|
||||||
|
maximum: Point3::new(self.k+0.0001, self.a1, self.b1),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,48 +0,0 @@
|
|||||||
use std::sync::Arc;
|
|
||||||
use crate::hittable::{HitRecord, Hittable};
|
|
||||||
use crate::{Aabb, Material, Point3, Ray, Vec3};
|
|
||||||
|
|
||||||
pub struct XyRect {
|
|
||||||
pub x0: f64,
|
|
||||||
pub x1: f64,
|
|
||||||
pub y0: f64,
|
|
||||||
pub y1: f64,
|
|
||||||
pub k: f64,
|
|
||||||
pub material: Arc<Material>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Hittable for XyRect {
|
|
||||||
fn hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<HitRecord> {
|
|
||||||
let t = (self.k - ray.origin().z()) / ray.direction().z();
|
|
||||||
if t < t_min || t > t_max {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let x = ray.origin().x() + t * ray.direction().x();
|
|
||||||
let y = ray.origin().y() + t * ray.direction().y();
|
|
||||||
if x < self.x0 || x > self.x1 || y < self.y0 || y > self.y1 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let normal = Vec3::new(0.0, 0.0, 1.0);
|
|
||||||
let dot = ray.direction().dot(&normal);
|
|
||||||
let front_face = dot < 0.0;
|
|
||||||
let normal = if front_face { normal } else { -normal };
|
|
||||||
Some(HitRecord {
|
|
||||||
point: ray.at(t),
|
|
||||||
normal,
|
|
||||||
t,
|
|
||||||
u: (x-self.x0)/(self.x1-self.x0),
|
|
||||||
v: (y-self.y0)/(self.y1-self.y0),
|
|
||||||
front_face,
|
|
||||||
material: &self.material
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bounding_box(&self, _time0: f64, _time1: f64) -> Option<Aabb> {
|
|
||||||
// The bounding box must have non-zero width in each dimension, so pad the Z
|
|
||||||
// dimension a small amount.
|
|
||||||
Some(Aabb {
|
|
||||||
minimum: Point3::new(self.x0, self.y0, self.k-0.0001),
|
|
||||||
maximum: Point3::new(self.x1, self.y1, self.k+0.0001),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user