diff --git a/img.ppm b/img.ppm index c717936..79b1e6d 100644 Binary files a/img.ppm and b/img.ppm differ diff --git a/src/camera.rs b/src/camera.rs index 2f84b59..bf7d1b8 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -7,29 +7,48 @@ pub struct Camera { lower_left_corner: Point3, horizontal: Vec3, vertical: Vec3, + u: Vec3, + v: Vec3, + w: Vec3, + lens_radius: f64, } impl Camera { - pub fn new(vfov: f64, aspect_ratio: f64) -> Self { + pub fn new( + lookfrom: Point3, + lookat: Point3, + vup: Vec3, + vfov: f64, + aspect_ratio: f64, + apeture: f64, + focus_dist: f64, + ) -> Self { let theta = degrees_to_radians(vfov); let h = f64::tan(theta/2.0); let viewport_height = 2.0 * h; let viewport_width = aspect_ratio * viewport_height; - let focal_length = 1.0; - - let origin = Point3::new(0.0, 0.0, 0.0); - let horizontal = Vec3::new(viewport_width, 0.0, 0.0); - let vertical = Vec3::new(0.0, viewport_width, 0.0); - let lower_left_corner = origin - horizontal / 2.0 - vertical / 2.0 - Vec3::new(0.0, 0.0, focal_length); + let w = (lookfrom - lookat).unit_vector(); + let u = (vup.cross(&w)).unit_vector(); + let v = w.cross(&u); - Camera { origin, lower_left_corner, horizontal, vertical} + let origin = lookfrom; + let horizontal = focus_dist * viewport_width * u; + let vertical = focus_dist * viewport_height * v; + let lower_left_corner = origin - horizontal/2.0 - vertical/2.0 - focus_dist * w; + + let lens_radius = apeture / 2.0; + + Camera { origin, lower_left_corner, horizontal, vertical, u, v, w, lens_radius} } - pub fn get_ray(&self, u: f64, v: f64) -> Ray { + pub fn get_ray(&self, s: f64, t: f64) -> Ray { + let rd = self.lens_radius * random_in_unit_disk(); + let offset = self.u * rd.x() + self.v * rd.y(); + Ray { origin: self.origin, - direction: self.lower_left_corner + u * self.horizontal + v * self.vertical - self.origin + direction: self.lower_left_corner + s*self.horizontal + t*self.vertical - self.origin - offset } } } \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index e9912fe..9bfed35 100644 --- a/src/main.rs +++ b/src/main.rs @@ -58,7 +58,7 @@ fn main() { static MATERIAL_GROUND: Lambertian = Lambertian::new(Color::new(0.3, 0.8, 0.0)); static MATERIAL_CENTER: Lambertian = Lambertian::new(Color::new(0.1, 0.2, 0.5)); static MATERIAL_LEFT: Dielectric = Dielectric::new(1.5); - static MATERIAL_RIGHT: Metal = Metal::new(Color::new(0.8, 0.6, 0.2), 0.3); + static MATERIAL_RIGHT: Metal = Metal::new(Color::new(0.8, 0.6, 0.2), 0.0); world.add(Box::new(Sphere::new(Point3::new(0.0, -100.5, -1.0), 100.0, &MATERIAL_GROUND))); world.add(Box::new(Sphere::new(Point3::new(0.0, 0.0, -1.0), 0.5, &MATERIAL_CENTER))); @@ -66,7 +66,20 @@ fn main() { world.add(Box::new(Sphere::new(Point3::new(1.0, 0.0, -1.0), 0.5, &MATERIAL_RIGHT))); // Camera - let cam = Camera::new(90.0, aspect_ratio); + let lookfrom = Point3::new(-2.0, 2.0, 1.0); + let lookat = Point3::new(0.0, 0.0, -1.0); + let vup = Vec3::new(0.0, 1.0, 0.0); + let dist_to_focus = (lookfrom-lookat).length_squared(); + + let cam = Camera::new( + lookfrom, + lookat, + vup, + 30.0, + aspect_ratio, + 0.0, + dist_to_focus + ); // Render //let mut rng = rand::thread_rng(); diff --git a/src/vec3.rs b/src/vec3.rs index c198d4d..d1c248c 100644 --- a/src/vec3.rs +++ b/src/vec3.rs @@ -45,9 +45,9 @@ impl Vec3 { pub fn cross(&self, rhs: &Self) -> Self { Self { elements: [ - self.y() * rhs.z() + self.z() * rhs.y(), - self.z() * rhs.x() + self.x() * rhs.z(), - self.x() * rhs.y() + self.y() * rhs.x() + self.y() * rhs.z() - self.z() * rhs.y(), + self.z() * rhs.x() - self.x() * rhs.z(), + self.x() * rhs.y() - self.y() * rhs.x() ] } } @@ -247,4 +247,14 @@ pub fn refract(uv: &Vec3, n: &Vec3, etai_over_etat: f64) -> Vec3 { let r_out_parallel = -f64::sqrt(f64::abs(1.0 - r_out_perp.length_squared())) * *n; r_out_perp + r_out_parallel +} + +pub fn random_in_unit_disk() -> Vec3 { + loop { + let p = Vec3::new(random_range_f64(-1.0, 1.0), random_range_f64(-1.0, 1.0), 0.0); + if p.length_squared() >= 1.0 { + continue; + } + return p; + } } \ No newline at end of file