From b7ec69dc7f5ce23f2874260a69024d92b0f3b1a7 Mon Sep 17 00:00:00 2001 From: Robert Garrett Date: Tue, 6 Jun 2023 18:37:26 -0500 Subject: [PATCH] Feat: Camera positioning The camera can now be fully described in 3D space. Close of Chapter 11. --- src/camera.rs | 25 ++++++++++++---------- src/main.rs | 58 +++++++++++++++++++++++++++++++++++++++++---------- 2 files changed, 61 insertions(+), 22 deletions(-) diff --git a/src/camera.rs b/src/camera.rs index 376e432..a7ed241 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -22,31 +22,34 @@ pub struct Camera { } impl Camera { - pub fn new(vfov: f32, aspect_ratio: f32) -> Camera { + pub fn new(lookfrom: Vec3, lookat: Vec3, vup: Vec3, vfov: f32, aspect_ratio: f32) -> Camera { let theta = degrees_to_radians(vfov); let h = (theta / 2.0).tan(); let vp_height = 2.0 * h; let vp_width = aspect_ratio * vp_height; - let focal_length = 1.0; + let w = Vec3::as_unit(lookfrom - lookat); + let u = Vec3::as_unit(Vec3::cross(vup, w)); + let v = Vec3::cross(w, u); - let horiz = Vec3::new(vp_width, 0.0, 0.0); - let verti = Vec3::new(0.0, vp_height, 0.0); - let orig = Vec3::zero(); + let orig = lookfrom; + let horiz = u * vp_width; + let verti = v * vp_height; + let lower_left_corner = orig - horiz / 2.0 - verti / 2.0 - w; Camera{ origin: orig, - lower_left_corner: orig - horiz/2.0 - verti/2.0 - Vec3::new(0.0, 0.0, focal_length), + lower_left_corner, horizontal: horiz, vertical: verti, } } - pub fn get_ray(&self, u: f32, v: f32) -> Ray { - let dir = self.lower_left_corner - + self.horizontal * u - + self.vertical * v - - self.origin; + pub fn get_ray(&self, s: f32, t: f32) -> Ray { + let dir = self.lower_left_corner + + self.horizontal * s + + self.vertical * t + - self.origin; Ray{ orig: self.origin, dir, diff --git a/src/main.rs b/src/main.rs index 2b8db30..222162a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,18 +32,38 @@ fn main() { let max_depth = 50; // world - - let R = std::f32::consts::FRAC_PI_4.cos(); - - let mat_left = Material::Lambertian { albedo: Vec3::new(0.0, 0.0, 1.0) }; - let mat_right = Material::Lambertian { albedo: Vec3::new(1.0, 0.0, 0.0) }; + + let mat_ground = Material::Lambertian { albedo: Vec3::new(0.8, 0.8, 0.0) }; + let mat_center = Material::Lambertian { albedo: Vec3::new(0.1, 0.2, 0.5) }; + let mat_left = Material::Dielectric { index_refraction: 1.5 }; + let mat_right = Material::Metal { albedo: Vec3::new(0.8, 0.6, 0.2), fuzz: 0.0 }; let mut world = HittableList::new(); world.add( Box::new( Sphere { - center: Vec3::new( -R, 0.0, -1.0), - radius: R, + center: Vec3::new(0.0, -100.5, -1.0), + radius: 100.0, + material: Some(mat_ground), + } + ) + ); + + world.add( + Box::new( + Sphere { + center: Vec3::new(0.0, 0.0, -1.0), + radius: 0.5, + material: Some(mat_center), + } + ) + ); + + world.add( + Box::new( + Sphere { + center: Vec3::new(-1.0, 0.0, -1.0), + radius: 0.5, material: Some(mat_left), } ) @@ -52,17 +72,33 @@ fn main() { world.add( Box::new( Sphere { - center: Vec3::new( R, 0.0, -1.0), - radius: R, + center: Vec3::new(-1.0, 0.0, -1.0), + radius: -0.45, + material: Some(mat_left), + } + ) + ); + + world.add( + Box::new( + Sphere { + center: Vec3::new(1.0, 0.0, -1.0), + radius: 0.5, material: Some(mat_right), } ) ); - + // camera - let cam = Camera::new(90.0, aspect_ratio); + let cam = Camera::new( + Vec3::new(-2.0, 2.0, 1.0), + Vec3::new(0.0, 0.0, -1.0), + Vec3::new(0.0, 1.0, 0.0), + 20.0, + aspect_ratio + ); // render let mut small_rng = SmallRng::from_entropy();