Skip to content
Permalink
Browse files

Add focus blur and cast rays in parallel

  • Loading branch information...
P1n3appl3 committed Jan 9, 2019
1 parent 3b991ed commit 00a276178a9aca963b71a6a3b919afaf5907e4f9
Showing with 211 additions and 42 deletions.
  1. +106 −0 Cargo.lock
  2. +1 −0 Cargo.toml
  3. BIN examples/cover.png
  4. BIN examples/cover_different_perspective.png
  5. +33 −5 src/camera.rs
  6. +56 −2 src/hitable.rs
  7. +15 −35 src/main.rs

Some generated files are not rendered by default. Learn more.

@@ -9,3 +9,4 @@ rand = "0.6.3"
png = "0.13.2"
progressive = "0.1.0"
itertools = "0.8.0"
rayon = "1.0.3"
BIN +309 KB examples/cover.png
Binary file not shown.
Binary file not shown.
@@ -1,11 +1,29 @@
use super::ray::Ray;
use super::vec3::Vec3;
use rand::random;

fn rand_in_unit_disk() -> Vec3 {
let mut p;
while {
p = Vec3::new(
random::<f32>() * 2.0 - 1.0,
random::<f32>() * 2.0 - 1.0,
0.0,
);
p.dot(p) >= 1.0
} {}
p
}

pub struct Camera {
origin: Vec3,
lower_left: Vec3,
horizontal: Vec3,
vertical: Vec3,
lens_radius: f32,
u: Vec3,
v: Vec3,
w: Vec3,
}

impl Camera {
@@ -16,6 +34,8 @@ impl Camera {
vup: Vec3,
vfov: f32,
aspect: f32,
aperture: f32,
focus_dist: f32,
) -> Self {
let theta = vfov * std::f32::consts::PI / 180.0;
let half_height = (theta / 2.0).tan();
@@ -25,17 +45,25 @@ impl Camera {
let v = w.cross(u);
Camera {
origin: look_from,
lower_left: look_from - u.scale(half_width) - v.scale(half_height) - w,
horizontal: u.scale(2.0 * half_width),
vertical: v.scale(2.0 * half_height),
lower_left: look_from
- (u.scale(half_width) + v.scale(half_height) + w).scale(focus_dist),
horizontal: u.scale(2.0 * half_width * focus_dist),
vertical: v.scale(2.0 * half_height * focus_dist),
lens_radius: aperture / 2.0,
u: u,
v: v,
w: w,
}
}

pub fn get_ray(&self, h: f32, v: f32) -> Ray {
let rand = rand_in_unit_disk().scale(self.lens_radius);
let offset = self.u.scale(rand.x) + self.v.scale(rand.y);
Ray::new(
self.origin,
self.origin + offset,
self.lower_left + self.horizontal.scale(h) + self.vertical.scale(v)
- self.origin,
- self.origin
- offset,
)
}
}
@@ -1,6 +1,7 @@
use super::material::Material;
use super::material::{Material, Material::*};
use super::ray::Ray;
use super::vec3::Vec3;
use rand::random;

/// The relevant information for a ray collision with an object
pub struct HitRecord {
@@ -10,7 +11,7 @@ pub struct HitRecord {
pub material: Material,
}

pub trait Hitable {
pub trait Hitable: Send + Sync {
fn hit(&self, r: Ray, t_min: f32, t_max: f32) -> Option<HitRecord>;
fn get_material(&self) -> Material;
}
@@ -70,6 +71,59 @@ impl HitableGroup {
pub fn new(items: Vec<Box<Hitable>>) -> Self {
HitableGroup { items: items }
}
pub fn random_scene() -> Self {
let mut world = HitableGroup::new(vec![
Box::new(Sphere::new(
Vec3::new(0.0, -1000.0, 0.0),
1000.0,
Diffuse(Vec3::new(0.5, 0.5, 0.5)),
)),
Box::new(Sphere::new(
Vec3::new(-4.0, 1.0, 0.0),
1.0,
Diffuse(Vec3::new(0.2, 0.3, 0.7)),
)),
Box::new(Sphere::new(
Vec3::new(4.0, 1.0, 0.0),
1.0,
Metal(Vec3::new(0.7, 0.6, 0.5), 0.0),
)),
Box::new(Sphere::new(Vec3::new(0.0, 1.0, 0.0), 1.0, Dielectric(1.5))),
]);

for a in -11..11 {
for b in -11..11 {
let pos = Vec3::new(
a as f32 + 0.9 * random::<f32>(),
0.2,
b as f32 + 0.9 * random::<f32>(),
);
if (pos - Vec3::new(4.0, 0.2, 0.0)).len() < 0.9 {
continue;
}
world.items.push(Box::new(Sphere::new(
pos,
0.2,
match (random::<f32>() * 100.0) as u8 {
0...5 => Dielectric(1.5),
5...20 => Metal(
(Vec3::new(1.0, 1.0, 1.0)
+ Vec3::new(random(), random(), random()))
.scale(0.5),
random::<f32>() / 2.0,
),
_ => Diffuse(Vec3::new(
random::<f32>() * random::<f32>(),
random::<f32>() * random::<f32>(),
random::<f32>() * random::<f32>(),
)),
},
)))
}
}

world
}
}

impl Hitable for HitableGroup {

0 comments on commit 00a2761

Please sign in to comment.
You can’t perform that action at this time.