Feat: Camera positioning

The camera can now be fully described in 3D space. Close of Chapter 11.
This commit is contained in:
2023-06-06 18:37:26 -05:00
parent b0efc9a248
commit b7ec69dc7f
2 changed files with 61 additions and 22 deletions

View File

@@ -22,30 +22,33 @@ pub struct Camera {
} }
impl 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 theta = degrees_to_radians(vfov);
let h = (theta / 2.0).tan(); let h = (theta / 2.0).tan();
let vp_height = 2.0 * h; let vp_height = 2.0 * h;
let vp_width = aspect_ratio * vp_height; 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 orig = lookfrom;
let verti = Vec3::new(0.0, vp_height, 0.0); let horiz = u * vp_width;
let orig = Vec3::zero(); let verti = v * vp_height;
let lower_left_corner = orig - horiz / 2.0 - verti / 2.0 - w;
Camera{ Camera{
origin: orig, 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, horizontal: horiz,
vertical: verti, vertical: verti,
} }
} }
pub fn get_ray(&self, u: f32, v: f32) -> Ray { pub fn get_ray(&self, s: f32, t: f32) -> Ray {
let dir = self.lower_left_corner let dir = self.lower_left_corner
+ self.horizontal * u + self.horizontal * s
+ self.vertical * v + self.vertical * t
- self.origin; - self.origin;
Ray{ Ray{
orig: self.origin, orig: self.origin,

View File

@@ -33,17 +33,37 @@ fn main() {
// world // world
let R = std::f32::consts::FRAC_PI_4.cos(); 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::Lambertian { albedo: Vec3::new(0.0, 0.0, 1.0) }; let mat_left = Material::Dielectric { index_refraction: 1.5 };
let mat_right = Material::Lambertian { albedo: Vec3::new(1.0, 0.0, 0.0) }; let mat_right = Material::Metal { albedo: Vec3::new(0.8, 0.6, 0.2), fuzz: 0.0 };
let mut world = HittableList::new(); let mut world = HittableList::new();
world.add( world.add(
Box::new( Box::new(
Sphere { Sphere {
center: Vec3::new( -R, 0.0, -1.0), center: Vec3::new(0.0, -100.5, -1.0),
radius: R, 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), material: Some(mat_left),
} }
) )
@@ -52,8 +72,18 @@ fn main() {
world.add( world.add(
Box::new( Box::new(
Sphere { Sphere {
center: Vec3::new( R, 0.0, -1.0), center: Vec3::new(-1.0, 0.0, -1.0),
radius: R, 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), material: Some(mat_right),
} }
) )
@@ -62,7 +92,13 @@ fn main() {
// camera // 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 // render
let mut small_rng = SmallRng::from_entropy(); let mut small_rng = SmallRng::from_entropy();