diff options
author | Yann Herklotz <git@yannherklotz.com> | 2020-10-10 00:12:12 +0100 |
---|---|---|
committer | Yann Herklotz <git@yannherklotz.com> | 2020-10-10 00:12:12 +0100 |
commit | 495d1c9c113098f24767b595c7e830f0fa8bc991 (patch) | |
tree | 95eac21eacecadc58f23a59216e764ddd6928979 /src | |
parent | dd5ac7c5fe336e9cac794cfa72d139613a99b466 (diff) | |
download | leela-495d1c9c113098f24767b595c7e830f0fa8bc991.tar.gz leela-495d1c9c113098f24767b595c7e830f0fa8bc991.zip |
Format all the files and add moving sphere
Diffstat (limited to 'src')
-rw-r--r-- | src/camera.rs | 42 | ||||
-rw-r--r-- | src/colour.rs | 0 | ||||
-rw-r--r-- | src/hittable.rs | 20 | ||||
-rw-r--r-- | src/main.rs | 88 | ||||
-rw-r--r-- | src/material.rs | 39 | ||||
-rw-r--r-- | src/ray.rs | 9 | ||||
-rw-r--r-- | src/render.rs | 72 | ||||
-rw-r--r-- | src/scene.rs | 8 | ||||
-rw-r--r-- | src/sphere.rs | 104 | ||||
-rw-r--r-- | src/utils.rs | 51 |
10 files changed, 320 insertions, 113 deletions
diff --git a/src/camera.rs b/src/camera.rs index 7564c12..01cb977 100644 --- a/src/camera.rs +++ b/src/camera.rs @@ -1,8 +1,8 @@ -use cgmath::prelude::*; -use cgmath::{Vector3, vec3}; -use rand::prelude::*; use crate::ray::Ray; use crate::utils::random_in_unit_disk; +use cgmath::prelude::*; +use cgmath::{vec3, Vector3}; +use rand::prelude::*; pub struct Camera { origin: Vector3<f64>, @@ -12,12 +12,23 @@ pub struct Camera { u: Vector3<f64>, v: Vector3<f64>, w: Vector3<f64>, - lens_radius: f64 + lens_radius: f64, + time0: f64, + time1: f64, } impl Camera { - pub fn new(lookfrom: &Vector3<f64>, lookat: &Vector3<f64>, vup: &Vector3<f64>, - vfov: f64, aspect: f64, aperture: f64, focus_dist: f64) -> Camera { + pub fn new( + lookfrom: &Vector3<f64>, + lookat: &Vector3<f64>, + vup: &Vector3<f64>, + vfov: f64, + aspect: f64, + aperture: f64, + focus_dist: f64, + time0: f64, + time1: f64, + ) -> Camera { let lens_radius = aperture / 2.0; let half_height = (vfov / 2.0).tan(); let half_width = aspect * half_height; @@ -26,19 +37,28 @@ impl Camera { let v = w.cross(u); Camera { origin: *lookfrom, - lower_left_corner: lookfrom - half_width * focus_dist * u - - half_height * focus_dist * v - focus_dist * w, + lower_left_corner: lookfrom + - half_width * focus_dist * u + - half_height * focus_dist * v + - focus_dist * w, horizontal: 2.0 * half_width * focus_dist * u, vertical: 2.0 * half_height * focus_dist * v, lens_radius, - u, v, w + u, + v, + w, + time0, + time1, } } pub fn get_ray(&self, rng: &mut ThreadRng, s: f64, t: f64) -> Ray { let rd = self.lens_radius * random_in_unit_disk(rng); 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) + Ray::new( + self.origin + offset, + self.lower_left_corner + s * self.horizontal + t * self.vertical - self.origin - offset, + rng.gen_range(self.time0, self.time1), + ) } } diff --git a/src/colour.rs b/src/colour.rs new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/colour.rs diff --git a/src/hittable.rs b/src/hittable.rs index dcc5006..b5a4f20 100644 --- a/src/hittable.rs +++ b/src/hittable.rs @@ -1,22 +1,32 @@ -use cgmath::{Vector3, dot}; use crate::material::Material; use crate::ray::Ray; +use cgmath::{dot, Vector3}; pub struct Hit<'a> { pub t: f64, pub p: Vector3<f64>, pub normal: Vector3<f64>, pub front_face: bool, - pub material: &'a (dyn Material + std::marker::Sync) + pub material: &'a (dyn Material + std::marker::Sync), } impl<'a> Hit<'a> { - pub fn new(ray: &Ray, t: f64, out_normal: Vector3<f64>, material: &'a(dyn Material + std::marker::Sync)) - -> Hit<'a> { + pub fn new( + ray: &Ray, + t: f64, + out_normal: Vector3<f64>, + material: &'a (dyn Material + std::marker::Sync), + ) -> Hit<'a> { let front_face = dot(ray.dir, out_normal) < 0.0; let normal = if front_face { out_normal } else { -out_normal }; let p = ray.at(t); - Hit { t, p, normal, front_face, material } + Hit { + t, + p, + normal, + front_face, + material, + } } } diff --git a/src/main.rs b/src/main.rs index f1a627f..3db5b97 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use cgmath::prelude::*; -use cgmath::{Vector3, vec3}; +use cgmath::{vec3, Vector3}; use rand::prelude::*; use std::f64::consts::PI; @@ -16,44 +16,67 @@ pub fn random_scene(rng: &mut ThreadRng) -> scene::Scene { let mut scene = scene::Scene::new(); scene.add(Box::new(sphere::Sphere::new( - vec3(0.0, -1000.0, 0.0), 1000.0, Box::new(material::Lambertian::new(vec3(0.5, 0.5, 0.5)))))); + vec3(0.0, -1000.0, 0.0), + 1000.0, + Box::new(material::Lambertian::new(vec3(0.5, 0.5, 0.5))), + ))); - for a in -11 .. 11 { - for b in -11 .. 11 { + for a in -11..11 { + for b in -11..11 { let choose_mat: f64 = rng.gen(); - let center = vec3(a as f64 + 0.9*rng.gen::<f64>(), 0.2, b as f64 + 0.9*rng.gen::<f64>()); + let center = vec3( + a as f64 + 0.9 * rng.gen::<f64>(), + 0.2, + b as f64 + 0.9 * rng.gen::<f64>(), + ); if (center - vec3(4.0, 0.2, 0.0)).magnitude() > 0.9 { if choose_mat < 0.8 { // diffuse - let albedo = utils::random_vector3(rng, 0.0, 1.0).mul_element_wise(utils::random_vector3(rng, 0.0, 1.0)); - scene.add( - Box::new(sphere::Sphere::new(center, 0.2, Box::new(material::Lambertian::new(albedo))))); + let albedo = utils::random_vector3(rng, 0.0, 1.0) + .mul_element_wise(utils::random_vector3(rng, 0.0, 1.0)); + scene.add(Box::new(sphere::Sphere::new( + center, + 0.2, + Box::new(material::Lambertian::new(albedo)), + ))); } else if choose_mat < 0.95 { // metal let albedo = utils::random_vector3(rng, 0.5, 1.0); let fuzz = rng.gen_range(0.0, 0.5); - scene.add( - Box::new(sphere::Sphere::new( - center, 0.2, Box::new(material::Metal::new(albedo, fuzz))))); + scene.add(Box::new(sphere::Sphere::new( + center, + 0.2, + Box::new(material::Metal::new(albedo, fuzz)), + ))); } else { // glass scene.add(Box::new(sphere::Sphere::new( - center, 0.2, Box::new(material::Dielectric::new(1.5))))); + center, + 0.2, + Box::new(material::Dielectric::new(1.5)), + ))); } } } } scene.add(Box::new(sphere::Sphere::new( - vec3(0.0, 1.0, 0.0), 1.0, Box::new(material::Dielectric::new(1.5))))); + vec3(0.0, 1.0, 0.0), + 1.0, + Box::new(material::Dielectric::new(1.5)), + ))); - scene.add( - Box::new(sphere::Sphere::new(vec3(-4.0, 1.0, 0.0), 1.0, - Box::new(material::Lambertian::new(vec3(0.4, 0.2, 0.1)))))); + scene.add(Box::new(sphere::Sphere::new( + vec3(-4.0, 1.0, 0.0), + 1.0, + Box::new(material::Lambertian::new(vec3(0.4, 0.2, 0.1))), + ))); - scene.add( - Box::new(sphere::Sphere::new( - vec3(4.0, 1.0, 0.0), 1.0, Box::new(material::Metal::new(vec3(0.7, 0.6, 0.5), 0.0))))); + scene.add(Box::new(sphere::Sphere::new( + vec3(4.0, 1.0, 0.0), + 1.0, + Box::new(material::Metal::new(vec3(0.7, 0.6, 0.5), 0.0)), + ))); scene } @@ -61,8 +84,8 @@ pub fn random_scene(rng: &mut ThreadRng) -> scene::Scene { fn main() { let image_width = 400; let image_height = 200; - let samples = 50; - let threads = 1; + let samples = 400; + let threads = 4; let max_depth = 50; let aspect_ratio = image_width as f64 / image_height as f64; @@ -76,10 +99,27 @@ fn main() { let vup = vec3(0.0, 1.0, 0.0); let dist_to_focus = 10.0; let aperture = 0.1; - let camera = camera::Camera::new(&lookfrom, &lookat, &vup, - 20.0 * PI / 180.0, aspect_ratio, aperture, dist_to_focus); + let camera = camera::Camera::new( + &lookfrom, + &lookat, + &vup, + 20.0 * PI / 180.0, + aspect_ratio, + aperture, + dist_to_focus, + 0.0, + 1.0, + ); - render::render(&scene, &camera, image_height, image_width, samples, max_depth, threads); + render::render( + &scene, + &camera, + image_height, + image_width, + samples, + max_depth, + threads, + ); eprintln!("\nDone") } diff --git a/src/material.rs b/src/material.rs index 42e8d0c..91e7c02 100644 --- a/src/material.rs +++ b/src/material.rs @@ -1,16 +1,16 @@ +use crate::hittable::Hit; +use crate::ray::{NextRay, Ray}; +use crate::utils::{random_in_unit_sphere, random_unit_vector, reflect, refract, schlick}; use cgmath::prelude::*; -use cgmath::{Vector3, vec3, dot}; +use cgmath::{dot, vec3, Vector3}; use rand::prelude::*; -use crate::ray::{Ray, NextRay}; -use crate::hittable::Hit; -use crate::utils::{random_unit_vector, random_in_unit_sphere, reflect, refract, schlick}; pub trait Material { fn scatter(&self, rng: &mut ThreadRng, ray: &Ray, hit: &Hit) -> Option<NextRay>; } pub struct Lambertian { - pub albedo: Vector3<f64> + pub albedo: Vector3<f64>, } impl Lambertian { @@ -22,13 +22,16 @@ impl Lambertian { impl Material for Lambertian { fn scatter(&self, rng: &mut ThreadRng, _ray: &Ray, hit: &Hit) -> Option<NextRay> { let scatter_direction = hit.normal + random_unit_vector(rng); - Some(NextRay::new(self.albedo, Ray::new(hit.p, scatter_direction))) + Some(NextRay::new( + self.albedo, + Ray::new(hit.p, scatter_direction, 0.0), + )) } } pub struct Metal { pub albedo: Vector3<f64>, - pub fuzz: f64 + pub fuzz: f64, } impl Metal { @@ -41,7 +44,11 @@ impl Metal { impl Material for Metal { fn scatter(&self, rng: &mut ThreadRng, ray: &Ray, hit: &Hit) -> Option<NextRay> { let reflected = reflect(&ray.dir.normalize(), &hit.normal); - let scattered = Ray::new(hit.p, reflected + self.fuzz * random_in_unit_sphere(rng)); + let scattered = Ray::new( + hit.p, + reflected + self.fuzz * random_in_unit_sphere(rng), + 0.0, + ); if dot(scattered.dir, hit.normal) > 0.0 { Some(NextRay::new(self.albedo, scattered)) } else { @@ -51,7 +58,7 @@ impl Material for Metal { } pub struct Dielectric { - pub ref_idx: f64 + pub ref_idx: f64, } impl Dielectric { @@ -63,24 +70,28 @@ impl Dielectric { impl Material for Dielectric { fn scatter(&self, rng: &mut ThreadRng, ray: &Ray, hit: &Hit) -> Option<NextRay> { let attenuation = vec3(1.0, 1.0, 1.0); - let etai_over_etat = if hit.front_face { 1.0 / self.ref_idx } else { self.ref_idx }; + let etai_over_etat = if hit.front_face { + 1.0 / self.ref_idx + } else { + self.ref_idx + }; let unit_direction = ray.dir.normalize(); let cos_theta = f64::min(dot(-unit_direction, hit.normal), 1.0); - let sin_theta = (1.0 - cos_theta*cos_theta).sqrt(); + let sin_theta = (1.0 - cos_theta * cos_theta).sqrt(); if etai_over_etat * sin_theta > 1.0 { let reflected = reflect(&unit_direction, &hit.normal); - return Some(NextRay::new(attenuation, Ray::new(hit.p, reflected))) + return Some(NextRay::new(attenuation, Ray::new(hit.p, reflected, 0.0))); } let reflect_prob = schlick(cos_theta, etai_over_etat); if rng.gen::<f64>() < reflect_prob { let reflected = reflect(&unit_direction, &hit.normal); - return Some(NextRay::new(attenuation, Ray::new(hit.p, reflected))) + return Some(NextRay::new(attenuation, Ray::new(hit.p, reflected, 0.0))); } let refracted = refract(&unit_direction, &hit.normal, etai_over_etat); - Some(NextRay::new(attenuation, Ray::new(hit.p, refracted))) + Some(NextRay::new(attenuation, Ray::new(hit.p, refracted, 0.0))) } } @@ -2,12 +2,13 @@ use cgmath::Vector3; pub struct Ray { pub orig: Vector3<f64>, - pub dir: Vector3<f64> + pub dir: Vector3<f64>, + pub time: f64, } impl Ray { - pub fn new(orig: Vector3<f64>, dir: Vector3<f64>) -> Ray { - Ray {orig, dir} + pub fn new(orig: Vector3<f64>, dir: Vector3<f64>, time: f64) -> Ray { + Ray { orig, dir, time } } pub fn at(&self, t: f64) -> Vector3<f64> { @@ -17,7 +18,7 @@ impl Ray { pub struct NextRay { pub attenuation: Vector3<f64>, - pub ray: Ray + pub ray: Ray, } impl NextRay { diff --git a/src/render.rs b/src/render.rs index 47c6698..c3d132a 100644 --- a/src/render.rs +++ b/src/render.rs @@ -1,20 +1,22 @@ +use crate::camera::Camera; +use crate::hittable::Hittable; +use crate::ray::Ray; +use crate::scene::Scene; +use crate::utils::print_colour; use cgmath::prelude::*; -use cgmath::{Vector3, vec3}; +use cgmath::{vec3, Vector3}; use rand::prelude::*; use rayon::prelude::*; use std::f64::INFINITY; -use crate::camera::Camera; -use crate::scene::Scene; -use crate::utils::{print_colour}; -use crate::ray::Ray; -use crate::hittable::Hittable; fn ray_colour(rng: &mut ThreadRng, ray: &Ray, scene: &Scene, depth: i32) -> Vector3<f64> { - if depth <= 0 { return vec3(0.0, 0.0, 0.0) } + if depth <= 0 { + return vec3(0.0, 0.0, 0.0); + } if let Some(t) = scene.is_hit(ray, 0.001, INFINITY) { if let Some(nray) = t.material.scatter(rng, ray, &t) { - ray_colour(rng, &nray.ray, scene, depth-1).mul_element_wise(nray.attenuation) + ray_colour(rng, &nray.ray, scene, depth - 1).mul_element_wise(nray.attenuation) } else { vec3(0.0, 0.0, 0.0) } @@ -24,10 +26,19 @@ fn ray_colour(rng: &mut ThreadRng, ray: &Ray, scene: &Scene, depth: i32) -> Vect } } -pub fn thread_render(world: &Scene, camera: &Camera, rng: &mut ThreadRng, image_height: i32, - image_width: i32, samples: i32, max_depth: i32, i: i32, j: i32) -> Vector3<f64> { +pub fn thread_render( + world: &Scene, + camera: &Camera, + rng: &mut ThreadRng, + image_height: i32, + image_width: i32, + samples: i32, + max_depth: i32, + i: i32, + j: i32, +) -> Vector3<f64> { let mut colour = vec3(0.0, 0.0, 0.0); - for _ in 0 .. samples { + for _ in 0..samples { let ru: f64 = rng.gen(); let rv: f64 = rng.gen(); let u = (i as f64 + ru) / image_width as f64; @@ -38,19 +49,32 @@ pub fn thread_render(world: &Scene, camera: &Camera, rng: &mut ThreadRng, image_ colour } -pub fn render(world: &Scene, camera: &Camera, image_height: i32, image_width: i32, - samples: i32, max_depth: i32, threads: i32) { - for j in 0 .. image_height { - eprint!("\rScanlines: {:3} / {:3}", j+1, image_height); - for i in 0 .. image_width { - let colours = (0 .. threads) - .into_par_iter() - .map(|_| { - let mut trng = thread_rng(); - thread_render( - world, camera, &mut trng, image_height, image_width, - samples / threads, max_depth, i, j) - }); +pub fn render( + world: &Scene, + camera: &Camera, + image_height: i32, + image_width: i32, + samples: i32, + max_depth: i32, + threads: i32, +) { + for j in 0..image_height { + eprint!("\rScanlines: {:3} / {:3}", j + 1, image_height); + for i in 0..image_width { + let colours = (0..threads).into_par_iter().map(|_| { + let mut trng = thread_rng(); + thread_render( + world, + camera, + &mut trng, + image_height, + image_width, + samples / threads, + max_depth, + i, + j, + ) + }); let colour = colours.sum::<Vector3<f64>>(); print_colour(&colour, samples); } diff --git a/src/scene.rs b/src/scene.rs index 0aa775c..215935a 100644 --- a/src/scene.rs +++ b/src/scene.rs @@ -1,13 +1,15 @@ -use crate::hittable::{Hittable, Hit}; +use crate::hittable::{Hit, Hittable}; use crate::ray::Ray; pub struct Scene { - objects: Vec<Box<dyn Hittable + std::marker::Sync>> + objects: Vec<Box<dyn Hittable + std::marker::Sync>>, } impl Scene { pub fn new() -> Scene { - Scene { objects: Vec::new() } + Scene { + objects: Vec::new(), + } } pub fn add(&mut self, obj: Box<dyn Hittable + std::marker::Sync>) { diff --git a/src/sphere.rs b/src/sphere.rs index f1c88b6..59ca498 100644 --- a/src/sphere.rs +++ b/src/sphere.rs @@ -1,19 +1,27 @@ -use cgmath::prelude::*; -use cgmath::{Vector3, dot}; -use core::borrow::Borrow; +use crate::hittable::{Hit, Hittable}; use crate::material::Material; -use crate::hittable::{Hittable, Hit}; use crate::ray::Ray; +use cgmath::prelude::*; +use cgmath::{dot, Vector3}; +use core::borrow::Borrow; pub struct Sphere { center: Vector3<f64>, radius: f64, - material: Box<dyn Material + std::marker::Sync> + material: Box<dyn Material + std::marker::Sync>, } impl Sphere { - pub fn new(center: Vector3<f64>, radius: f64, material: Box<dyn Material + std::marker::Sync>) -> Sphere { - Sphere { center, radius, material } + pub fn new( + center: Vector3<f64>, + radius: f64, + material: Box<dyn Material + std::marker::Sync>, + ) -> Sphere { + Sphere { + center, + radius, + material, + } } } @@ -23,16 +31,92 @@ impl Hittable for Sphere { let a = ray.dir.magnitude2(); let b = dot(oc, ray.dir); let c = oc.magnitude2() - self.radius * self.radius; - let discriminant = b*b - a*c; + let discriminant = b * b - a * c; + + if discriminant > 0.0 { + let soln = (-b - discriminant.sqrt()) / a; + if soln < t_max && soln > t_min { + return Some(Hit::new( + ray, + soln, + (ray.at(soln) - self.center) / self.radius, + self.material.borrow(), + )); + } + let soln = (-b + discriminant.sqrt()) / a; + if soln < t_max && soln > t_min { + return Some(Hit::new( + ray, + soln, + (ray.at(soln) - self.center) / self.radius, + self.material.borrow(), + )); + } + } + None + } +} + +struct MovingSphere { + center0: Vector3<f64>, + center1: Vector3<f64>, + time0: f64, + time1: f64, + radius: f64, + material: Box<dyn Material + std::marker::Sync>, +} + +impl MovingSphere { + pub fn new( + center0: Vector3<f64>, + center1: Vector3<f64>, + time0: f64, + time1: f64, + radius: f64, + material: Box<dyn Material + std::marker::Sync>, + ) -> MovingSphere { + MovingSphere { + center0, + center1, + time0, + time1, + radius, + material, + } + } + + pub fn center(&self, time: f64) -> Vector3<f64> { + self.center0 + + ((time + self.time0) / (self.time0 + self.time1)) * (self.center1 - self.center0) + } +} + +impl Hittable for MovingSphere { + fn is_hit(&self, ray: &Ray, t_min: f64, t_max: f64) -> Option<Hit> { + let oc = ray.orig - self.center(ray.time); + let a = ray.dir.magnitude2(); + let b = dot(oc, ray.dir); + let c = oc.magnitude2() - self.radius * self.radius; + let discriminant = b * b - a * c; if discriminant > 0.0 { let soln = (-b - discriminant.sqrt()) / a; if soln < t_max && soln > t_min { - return Some(Hit::new(ray, soln, (ray.at(soln) - self.center) / self.radius, self.material.borrow())) + return Some(Hit::new( + ray, + soln, + (ray.at(soln) - self.center(ray.time)) / self.radius, + self.material.borrow(), + )); } let soln = (-b + discriminant.sqrt()) / a; if soln < t_max && soln > t_min { - return Some(Hit::new(ray, soln, (ray.at(soln) - self.center) / self.radius, self.material.borrow())) + return Some(Hit::new( + ray, + soln, + (ray.at(soln) - self.center(ray.time)) / self.radius, + self.material.borrow(), + )); } } None diff --git a/src/utils.rs b/src/utils.rs index 659de7d..7e8c51f 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,51 +1,66 @@ use cgmath::prelude::*; -use cgmath::{Vector3, vec3, dot}; +use cgmath::{dot, vec3, Vector3}; use rand::prelude::*; use std::f64::consts::PI; pub fn clamp(x: f64, min: f64, max: f64) -> f64 { - if x < min { min } - else if x > max { max } - else { x } + if x < min { + min + } else if x > max { + max + } else { + x + } } pub fn print_colour(colour: &Vector3<f64>, samples: i32) { let scolour = colour.map(|x| (x / samples as f64).sqrt()); - println!("{} {} {}" - , (256.0 * clamp(scolour.x, 0.0, 0.999)) as i32 - , (256.0 * clamp(scolour.y, 0.0, 0.999)) as i32 - , (256.0 * clamp(scolour.z, 0.0, 0.999)) as i32) + println!( + "{} {} {}", + (256.0 * clamp(scolour.x, 0.0, 0.999)) as i32, + (256.0 * clamp(scolour.y, 0.0, 0.999)) as i32, + (256.0 * clamp(scolour.z, 0.0, 0.999)) as i32 + ) } pub fn random_vector3(rng: &mut ThreadRng, min: f64, max: f64) -> Vector3<f64> { - vec3(rng.gen_range(min, max), rng.gen_range(min, max), rng.gen_range(min, max)) + vec3( + rng.gen_range(min, max), + rng.gen_range(min, max), + rng.gen_range(min, max), + ) } pub fn random_in_unit_sphere(rng: &mut ThreadRng) -> Vector3<f64> { loop { let p = random_vector3(rng, -1.0, 1.0); - if p.magnitude2() <= 1.0 { return p } + if p.magnitude2() <= 1.0 { + return p; + } } } pub fn random_unit_vector(rng: &mut ThreadRng) -> Vector3<f64> { - let a = rng.gen_range(0.0, 2.0*PI); + let a = rng.gen_range(0.0, 2.0 * PI); let z = rng.gen_range(-1.0, 1.0); - let r = ((1.0 - z*z) as f64).sqrt(); - vec3(r*a.cos(), r*a.sin(), z) + let r = ((1.0 - z * z) as f64).sqrt(); + vec3(r * a.cos(), r * a.sin(), z) } pub fn random_in_hemisphere(rng: &mut ThreadRng, normal: &Vector3<f64>) -> Vector3<f64> { let in_unit_sphere = random_in_unit_sphere(rng); - if dot(in_unit_sphere, *normal) > 0.0 { in_unit_sphere } - else { -in_unit_sphere } + if dot(in_unit_sphere, *normal) > 0.0 { + in_unit_sphere + } else { + -in_unit_sphere + } } pub fn random_in_unit_disk(rng: &mut ThreadRng) -> Vector3<f64> { loop { let p = vec3(rng.gen_range(-1.0, 1.0), rng.gen_range(-1.0, 1.0), 0.0); if p.magnitude2() < 1.0 { - return p + return p; } } } @@ -56,13 +71,13 @@ pub fn reflect(v: &Vector3<f64>, n: &Vector3<f64>) -> Vector3<f64> { pub fn refract(uv: &Vector3<f64>, n: &Vector3<f64>, etai_over_etat: f64) -> Vector3<f64> { let cos_theta = dot(-1.0 * uv, *n); - let r_out_parallel = etai_over_etat * (uv + cos_theta*n); + let r_out_parallel = etai_over_etat * (uv + cos_theta * n); let r_out_perp = -(1.0 - r_out_parallel.magnitude2()).sqrt() * n; r_out_parallel + r_out_perp } pub fn schlick(cosine: f64, ref_idx: f64) -> f64 { let r0 = (1.0 - ref_idx) / (1.0 + ref_idx); - let r0sq = r0*r0; + let r0sq = r0 * r0; r0sq + (1.0 - r0) * (1.0 - cosine).powi(5) } |