~ttt/ray_tracing_in_one_weekend

4ff91dec8fdda1ce5577a4ac312cc058b67cecb7 — Tomasz Kłak 3 years ago 0fb5380
ch 12 done
3 files changed, 56 insertions(+), 12 deletions(-)

M src/camera.rs
M src/main.rs
M src/vec3.rs
M src/camera.rs => src/camera.rs +32 -9
@@ 1,14 1,26 @@
use crate::{cross, degrees_to_radians, unit_vector, Point3, Ray, Vec3};
use crate::{cross, degrees_to_radians, random_in_unit_disk, unit_vector, 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, aspect_ratio: f64) -> Self {
    pub fn new(
        lookfrom: Point3,
        lookat: Point3,
        vup: Vec3,
        vfov: f64,
        aspect_ratio: f64,
        aperture: f64,
        focus_dist: f64,
    ) -> Self {
        let theta = degrees_to_radians(vfov);
        let h = (theta / 2.0).tan();
        let viewport_height = 2.0 * h;


@@ 18,21 30,32 @@ impl Camera {
        let u = unit_vector(cross(&vup, &w));
        let v = cross(&w, &u);
        let origin = lookfrom;
        let horizontal = viewport_width * u;
        let vertical = viewport_height * v;
        let lower_left_corner = origin - horizontal / 2. - vertical / 2. - w;
        let horizontal = focus_dist * viewport_width * u;
        let vertical = focus_dist * viewport_height * v;
        let lower_left_corner = origin - horizontal / 2. - vertical / 2. - focus_dist * w;

        let lens_radius = aperture / 2.;
        Self {
            origin,
            lower_left_corner,
            horizontal,
            vertical,
            u,
            v,
            w,
            lens_radius,
        }
    }

    pub fn get_ray(&self, s: f64, t: f64) -> Ray {
        return Ray::new(
            &self.origin,
            &(self.lower_left_corner + s * &self.horizontal + t * self.vertical - self.origin),
        );
        let rd: Vec3 = self.lens_radius * random_in_unit_disk();
        let offset = self.u * rd.x() + self.v * rd.y();

        Ray::new(
            &(self.origin + offset),
            &(self.lower_left_corner + s * self.horizontal + t * self.vertical
                - self.origin
                - offset),
        )
    }
}

M src/main.rs => src/main.rs +10 -3
@@ 90,12 90,19 @@ fn main() {
    )));

    // Camera
    let lookfrom = Point3::new(3., 3., 2.);
    let lookat = Point3::new(0., 0., -1.);
    let vup = Vec3::new(0., 1., 0.);
    let dist_to_focus = (lookfrom - lookat).length();
    let aperture = 2.0;
    let cam = Camera::new(
        Point3::new(-2., 2., 1.),
        Point3::new(0., 0., -1.),
        Point3::new(0., 1., 0.),
        lookfrom,
        lookat,
        vup,
        20.0,
        aspect_ratio,
        aperture,
        dist_to_focus,
    );

    // Render

M src/vec3.rs => src/vec3.rs +14 -0
@@ 245,3 245,17 @@ pub fn refract(uv: &Vec3, n: &Vec3, etai_over_etat: f64) -> Vec3 {
    let r_out_parallel = -((1.0 - r_out_perp.length_squared()).abs()).sqrt() * n;
    r_out_perp + r_out_parallel
}

pub fn random_in_unit_disk() -> Vec3 {
    loop {
        let p = Vec3::new(
            random_double_range(-1f64..1.),
            random_double_range(-1f64..1.),
            0.,
        );
        if p.length_squared() >= 1. {
            continue;
        }
        return p;
    }
}