Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
c1548fa
commit dd72c24
Showing
3 changed files
with
196 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use glam::DVec3; | ||
use raytracer::{ | ||
camera::Camera, | ||
material::Material, | ||
shapes::{quad::Quad, sphere::Sphere}, | ||
textures::Texture, | ||
}; | ||
use std::{io, path::Path}; | ||
|
||
fn main() -> io::Result<()> { | ||
let mut world = vec![]; | ||
|
||
// Materials | ||
let left_red = Material::Lambertian { | ||
albedo: DVec3::new(1.0, 0.2, 0.2).into(), | ||
}; | ||
let back_green = Material::Lambertian { | ||
albedo: DVec3::new(0.2, 1.0, 0.2).into(), | ||
}; | ||
let right_blue = Material::Lambertian { | ||
albedo: DVec3::new(0.2, 0.2, 1.0).into(), | ||
}; | ||
let upper_orange = Material::Lambertian { | ||
albedo: DVec3::new(1.0, 0.5, 0.0).into(), | ||
}; | ||
let lower_teal = Material::Lambertian { | ||
albedo: DVec3::new(0.2, 0.8, 0.8).into(), | ||
}; | ||
|
||
// Quads | ||
world.push(Quad::new( | ||
DVec3::new(-3., -2., 5.), | ||
DVec3::new(0., 0., -4.), | ||
DVec3::new(0., 4., 0.), | ||
left_red, | ||
)); | ||
world.push(Quad::new( | ||
DVec3::new(-2., -2., 0.), | ||
DVec3::new(4., 0., 0.), | ||
DVec3::new(0., 4., 0.), | ||
back_green, | ||
)); | ||
world.push(Quad::new( | ||
DVec3::new(3., -2., 1.), | ||
DVec3::new(0., 0., 4.), | ||
DVec3::new(0., 4., 0.), | ||
right_blue, | ||
)); | ||
world.push(Quad::new( | ||
DVec3::new(-2., 3., 1.), | ||
DVec3::new(4., 0., 0.), | ||
DVec3::new(0., 0., 4.), | ||
upper_orange, | ||
)); | ||
world.push(Quad::new( | ||
DVec3::new(-2., -3., 5.), | ||
DVec3::new(4., 0., 0.), | ||
DVec3::new(0., 0., -4.), | ||
lower_teal, | ||
)); | ||
|
||
let camera = Camera::init() | ||
.image_width(800) | ||
.aspect_ratio(1.) | ||
.look_from(DVec3::new(0., 0., 9.)) | ||
.look_at(DVec3::ZERO) | ||
.vup(DVec3::Y) | ||
.focus_dist(10.0) | ||
.defocus_angle(0.0) | ||
.samples_per_pixel(500) | ||
.max_depth(50) | ||
.vfov(80.) | ||
.build(); | ||
|
||
let filename = Path::new(file!()) | ||
.file_name() | ||
.and_then(|s| s.to_str()) | ||
.unwrap() | ||
.trim_end_matches(".rs"); | ||
camera.render_to_disk(filename, world)?; | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
use std::{f64::consts::PI, ops::Range}; | ||
|
||
use glam::DVec3; | ||
|
||
use crate::{ | ||
hittable::{HitRecord, Hittable}, | ||
material::Material, | ||
ray::Ray, | ||
textures::Texture, | ||
}; | ||
|
||
pub struct Quad { | ||
Q: DVec3, | ||
u: DVec3, | ||
v: DVec3, | ||
material: Material, | ||
normal: DVec3, | ||
D: f64, | ||
w: DVec3, | ||
} | ||
|
||
impl Quad { | ||
pub fn new( | ||
Q: DVec3, | ||
u: DVec3, | ||
v: DVec3, | ||
material: Material, | ||
) -> Self { | ||
let n = u.cross(v); | ||
let normal = n.normalize(); | ||
let D = normal.dot(Q); | ||
let w = n / n.dot(n); | ||
Self { | ||
Q, | ||
u, | ||
v, | ||
material, | ||
normal, | ||
D, | ||
w, | ||
} | ||
} | ||
fn is_interior(a: f64, b: f64) -> Option<(f64, f64)> { | ||
// Given the hit point in plane coordinates, return false if it is outside the | ||
// primitive, otherwise set the hit record UV coordinates and return true. | ||
|
||
if (a < 0.) || (1. < a) || (b < 0.) || (1. < b) { | ||
return None; | ||
} | ||
|
||
// a,b == u,v | ||
Some((a, b)) | ||
} | ||
} | ||
|
||
impl Hittable for Quad { | ||
fn hit( | ||
&self, | ||
ray: &Ray, | ||
interval: Range<f64>, | ||
) -> Option<HitRecord> { | ||
let denom = self.normal.dot(ray.direction); | ||
|
||
// No hit if the ray is parallel to the plane. | ||
if denom.abs() < 1e-8 { | ||
return None; | ||
} | ||
// Return false if the hit point parameter t is outside the ray interval. | ||
let t = | ||
(self.D - self.normal.dot(ray.origin)) / denom; | ||
if !interval.contains(&t) { | ||
return None; | ||
} | ||
|
||
// Determine the hit point lies within the planar shape using its plane coordinates. | ||
let intersection = ray.at(t); | ||
let planar_hitpt_vector: DVec3 = | ||
intersection - self.Q; | ||
let alpha = | ||
self.w.dot(planar_hitpt_vector.cross(self.v)); | ||
let beta = | ||
self.w.dot(self.u.cross(planar_hitpt_vector)); | ||
|
||
let Some((u, v)) = Quad::is_interior(alpha, beta) | ||
else { | ||
return None; | ||
}; | ||
// Ray hits the 2D shape; set the rest of the hit record and return true. | ||
// rec.t = t; | ||
// rec.p = intersection; | ||
// rec.mat = mat; | ||
// rec.set_face_normal(r, normal); | ||
|
||
// return true; | ||
|
||
let rec = HitRecord::with_face_normal( | ||
self.material.clone(), | ||
intersection, | ||
self.normal, | ||
t, | ||
ray, | ||
u, | ||
v, | ||
); | ||
|
||
Some(rec) | ||
} | ||
} |