~ttt/ray_tracing_in_one_weekend

faa4acf3862c12c4457ca7c8154a1ae032abd30a — Tomasz Kłak 3 years ago e0393b5
ch 7 done
8 files changed, 165 insertions(+), 28 deletions(-)

M .gitignore
M Cargo.lock
M Cargo.toml
A src/camera.rs
M src/hittable_list.rs
M src/main.rs
A src/rtweekend.rs
M src/vec3.rs
M .gitignore => .gitignore +2 -0
@@ 1,1 1,3 @@
/target
*.ppm
tags

M Cargo.lock => Cargo.lock +78 -0
@@ 1,5 1,83 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"

[[package]]
name = "getrandom"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8"
dependencies = [
 "cfg-if",
 "libc",
 "wasi",
]

[[package]]
name = "libc"
version = "0.2.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"

[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"

[[package]]
name = "rand"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
dependencies = [
 "libc",
 "rand_chacha",
 "rand_core",
 "rand_hc",
]

[[package]]
name = "rand_chacha"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
dependencies = [
 "ppv-lite86",
 "rand_core",
]

[[package]]
name = "rand_core"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
dependencies = [
 "getrandom",
]

[[package]]
name = "rand_hc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
dependencies = [
 "rand_core",
]

[[package]]
name = "ray_tracing_in_one_weekend"
version = "0.1.0"
dependencies = [
 "rand",
]

[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"

M Cargo.toml => Cargo.toml +1 -0
@@ 7,3 7,4 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rand = "0.8"

A src/camera.rs => src/camera.rs +36 -0
@@ 0,0 1,36 @@
use crate::{Point3, Ray, Vec3};

pub struct Camera {
    origin: Point3,
    lower_left_corner: Point3,
    horizontal: Vec3,
    vertical: Vec3,
}

impl Camera {
    pub fn new() -> Self {
        let aspect_ratio = 16.0 / 9.0;
        let viewport_height = 2.0;
        let viewport_width = aspect_ratio * viewport_height;
        let focal_length = 1.0;

        let origin = Point3::new(0., 0., 0.);
        let horizontal = Vec3::new(viewport_width, 0.0, 0.0);
        let vertical = Vec3::new(0.0, viewport_height, 0.0);
        let lower_left_corner =
            origin - horizontal / 2. - vertical / 2. - Vec3::new(0., 0., focal_length);
        Self {
            origin,
            lower_left_corner,
            horizontal,
            vertical,
        }
    }

    pub fn get_ray(&self, u: f64, v: f64) -> Ray {
        return Ray::new(
            &self.origin,
            &(self.lower_left_corner + u * self.horizontal + v * self.vertical - self.origin),
        );
    }
}

M src/hittable_list.rs => src/hittable_list.rs +1 -2
@@ 1,6 1,5 @@
use crate::hittable::*;
use crate::ray::*;
use crate::vec3::*;
use std::sync::Arc;

#[derive(Clone)]


@@ 10,7 9,7 @@ pub struct HittableList {

impl HittableList {
    pub fn empty() -> Self {
        HittableList{ objects: vec![] }
        HittableList { objects: vec![] }
    }

    pub fn clear(&mut self) {

M src/main.rs => src/main.rs +17 -22
@@ 18,6 18,9 @@ use sphere::*;
mod rtweekend;
use rtweekend::*;

mod camera;
use camera::*;

fn hit_sphere(center: &Point3, radius: f64, r: &Ray) -> f64 {
    let oc = r.origin() - *center;
    let a = r.direction().length_squared();


@@ 34,7 37,7 @@ 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));
        return 0.5 * (rec.normal + Color::new(1.0, 1.0, 1.0));
    }
    let unit_direction = unit_vector(r.direction());
    let t = 0.5 * (unit_direction.y() + 1.0);


@@ 48,25 51,17 @@ fn main() {
    // Image
    let aspect_ratio = 16.0 / 9.0;
    let image_width = 400;
    let image_width = 800;
    // let image_width = 1600;
    let image_height = (image_width as f64 / aspect_ratio) as i32;
    let samples_per_pixel = 100;

    // World
    let mut world = HittableList::empty();
    world.add(Arc::new(Sphere::new(Point3::new(0.0,0.0,-1.0), 0.5)));
    world.add(Arc::new(Sphere::new(Point3::new(0.0,-100.5,-1.0), 100.0)));
    world.add(Arc::new(Sphere::new(Point3::new(0.0, 0.0, -1.0), 0.5)));
    world.add(Arc::new(Sphere::new(Point3::new(0.0, -100.5, -1.0), 100.0)));

    // Camera

    let viewport_height = 2.0;
    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_height, 0.0);
    let lower_left_corner =
        origin - horizontal / 2f64 - vertical / 2f64 - Vec3::new(0.0, 0.0, focal_length);
    let cam = Camera::new();

    // Render



@@ 75,14 70,14 @@ fn main() {
    for j in (0..=(image_height - 1)).rev() {
        eprint!("\rScanlines remaining: {} ", j);
        for i in 0..image_width {
            let u = i as f64 / (image_width - 1) as f64;
            let v = j as f64 / (image_height - 1) as f64;
            let r = Ray::new(
                &origin,
                &(lower_left_corner + u * horizontal + v * vertical - origin),
            );
            let pixel_color = ray_color(&r, &world);
            write_color(&mut handle, pixel_color);
            let mut pixel_color = Color::default();
            for _ in 0..samples_per_pixel {
                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);
            }
            write_color(&mut handle, pixel_color, samples_per_pixel);
        }
    }
    eprintln!("\nDone!");

A src/rtweekend.rs => src/rtweekend.rs +16 -0
@@ 0,0 1,16 @@
use rand::Rng;
pub use std::f64::consts::PI;
pub use std::f64::INFINITY;
use std::ops::Range;

pub fn degrees_to_radians(degrees: f64) -> f64 {
    degrees * PI / 180.0
}

pub fn random_double() -> f64 {
    random_double_range(0.0..1.0)
}

pub fn random_double_range(r: Range<f64>) -> f64 {
    rand::thread_rng().gen_range(r)
}

M src/vec3.rs => src/vec3.rs +14 -4
@@ 163,13 163,23 @@ pub fn unit_vector(v: Vec3) -> Vec3 {
    v / v.length()
}

pub fn write_color(out: &mut impl std::io::Write, pixel_color: Color) {
pub fn write_color(out: &mut impl std::io::Write, pixel_color: Color, samples_per_pixel: usize) {
    let mut r = pixel_color.x();
    let mut g = pixel_color.y();
    let mut b = pixel_color.z();

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

    write!(
        out,
        "{} {} {}\n",
        (255.999 * pixel_color.x()) as i32,
        (255.999 * pixel_color.y()) as i32,
        (255.999 * pixel_color.z()) as i32
        (256.0 * r.clamp(0.0, 0.999)).round() as usize,
        (256.0 * g.clamp(0.0, 0.999)).round() as usize,
        (256.0 * b.clamp(0.0, 0.999)).round() as usize,
    )
    .unwrap();
}