~ttt/ray_tracing_in_one_weekend

d047353b7bbc003f31d64e90360240c577fa0d06 — Tomasz Kłak 3 years ago faa4acf
ch 8 done
2 files changed, 43 insertions(+), 8 deletions(-)

M src/main.rs
M src/vec3.rs
M src/main.rs => src/main.rs +11 -5
@@ 35,9 35,14 @@ fn hit_sphere(center: &Point3, radius: f64, r: &Ray) -> f64 {
    }
}

fn ray_color(r: &Ray, world: &dyn Hittable) -> Color {
    if let Some(rec) = world.hit(r, 0.0, INFINITY) {
        return 0.5 * (rec.normal + Color::new(1.0, 1.0, 1.0));
fn ray_color(r: &Ray, world: &dyn Hittable, depth: isize) -> Color {
    // If we've exceeded the ray bounce limit, no more light is gathered.
    if depth <= 0 {
        return Color::default();
    }
    if let Some(rec) = world.hit(r, 0.001, INFINITY) {
        let target = rec.p + rec.normal + random_unit_vector();
        return 0.5 * ray_color(&Ray::new(&rec.p, &(target - rec.p)), world, depth - 1);
    }
    let unit_direction = unit_vector(r.direction());
    let t = 0.5 * (unit_direction.y() + 1.0);


@@ 51,9 56,10 @@ fn main() {
    // Image
    let aspect_ratio = 16.0 / 9.0;
    let image_width = 400;
    // let image_width = 1600;
    let image_width = 1600;
    let image_height = (image_width as f64 / aspect_ratio) as i32;
    let samples_per_pixel = 100;
    let max_depth = 50;

    // World
    let mut world = HittableList::empty();


@@ 75,7 81,7 @@ fn main() {
                let u = (i as f64 + random_double()) / (image_width - 1) as f64;
                let v = (j as f64 + random_double()) / (image_height - 1) as f64;
                let r = cam.get_ray(u, v);
                pixel_color += ray_color(&r, &world);
                pixel_color += ray_color(&r, &world, max_depth);
            }
            write_color(&mut handle, pixel_color, samples_per_pixel);
        }

M src/vec3.rs => src/vec3.rs +32 -3
@@ 1,3 1,6 @@
use crate::{random_double, random_double_range};
use std::ops::Range;

#[derive(Debug, Clone, Copy)]
pub struct Vec3 {
    e: [f64; 3],


@@ 28,6 31,18 @@ impl Vec3 {
    pub fn length_squared(&self) -> f64 {
        self.e[0] * self.e[0] + self.e[1] * self.e[1] + self.e[2] * self.e[2]
    }

    pub fn random() -> Self {
        Self::new(random_double(), random_double(), random_double())
    }

    pub fn random_range(r: Range<f64>) -> Self {
        Self::new(
            random_double_range(r.clone()),
            random_double_range(r.clone()),
            random_double_range(r.clone()),
        )
    }
}

impl std::ops::Neg for &Vec3 {


@@ 170,9 185,9 @@ pub fn write_color(out: &mut impl std::io::Write, pixel_color: Color, samples_pe

    // Divide the color by the number of samples.
    let scale = 1.0 / samples_per_pixel as f64;
    r *= scale;
    g *= scale;
    b *= scale;
    r = (scale * r).sqrt();
    g = (scale * g).sqrt();
    b = (scale * b).sqrt();

    write!(
        out,


@@ 183,3 198,17 @@ pub fn write_color(out: &mut impl std::io::Write, pixel_color: Color, samples_pe
    )
    .unwrap();
}

pub fn random_in_unit_sphere() -> Vec3 {
    loop {
        let p = Vec3::random_range(-1.0..1.0);
        if p.length_squared() >= 1.0 {
            continue;
        }
        return p;
    }
}

pub fn random_unit_vector() -> Vec3 {
    unit_vector(random_in_unit_sphere())
}