Renderer/src/camera.rs
2022-06-29 16:17:28 +02:00

61 lines
1.6 KiB
Rust

use super::{Point3, Ray, Vec3};
pub struct Camera {
origin: Point3,
lower_left_corner: Point3,
horizontal: Vec3,
vertical: Vec3,
u: Vec3,
v: Vec3,
w: Vec3,
lens_radius: f64,
}
impl Camera {
pub fn new(
lookfrom: Point3,
lookat: Point3,
vup: Vec3,
vfov: f64, // vertical field of view in degrees
aspect_ratio: f64,
aperture: f64,
focus_dist: f64,
) -> Self {
let theta = vfov.to_radians();
let h = (theta / 2.0).tan();
let viewport_height = 2.0 * h;
let viewport_width = aspect_ratio * viewport_height;
let w = Vec3::unit_vector(lookfrom - lookat);
let u = Vec3::unit_vector(Vec3::cross(vup, w));
let v = Vec3::cross(w, u);
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 = aperture / 2.0;
return Camera {
origin,
horizontal,
vertical,
lower_left_corner,
u,
v,
w,
lens_radius,
};
}
pub fn get_ray(&self, u: f64, v: f64) -> Ray {
let rd = self.lens_radius * Vec3::random_in_unit_disk();
let offset = rd.x() * self.u + rd.y() * self.v;
return Ray::new(
self.origin + offset,
self.lower_left_corner + u * self.horizontal + v * self.vertical - self.origin - offset,
);
}
}