Skip to content

Commit

Permalink
Defocus Blur and fix some naming issue
Browse files Browse the repository at this point in the history
  • Loading branch information
Latias94 committed May 4, 2021
1 parent 298c768 commit 0603298
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 29 deletions.
Binary file modified image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 25 additions & 6 deletions src/camera.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,22 @@ pub struct Camera {
lower_left_corner: Vec3,
horizontal: Vec3,
vertical: Vec3,
u: Vec3,
v: Vec3,
w: Vec3,
lens_radius: f32,
}

impl Camera {
pub fn new(look_from: Vec3, look_at: Vec3, vup: Vec3, vfov: f32, aspect_ratio: f32) -> Camera {
pub fn new(
look_from: Vec3,
look_at: Vec3,
vup: Vec3,
vfov: f32,
aspect_ratio: f32,
aperture: f32,
focus_dist: f32,
) -> Camera {
let theta = degrees_to_radians(vfov);
let h = libm::tanf(theta / 2.0);
let viewport_height: f32 = 2.0 * h;
Expand All @@ -22,21 +34,28 @@ impl Camera {
let v = w.cross(u);

let origin = look_from;
let horizontal = viewport_width * u;
let vertical = viewport_height * v;
let lower_left_corner = origin - horizontal / 2.0 - vertical / 2.0 - w;
let horizontal = focus_dist * viewport_width * u;
let vertical = focus_dist * viewport_height * v;
let lower_left_corner = origin - horizontal / 2.0 - vertical / 2.0 - focus_dist * w;
let lens_radius = aperture / 2.0;
Camera {
origin,
horizontal,
vertical,
u,
v,
w,
lower_left_corner,
lens_radius,
}
}

pub fn get_ray(&self, s: f32, t: f32) -> Ray {
let rd = self.lens_radius * Vec3::random_in_unit_disk();
let offset = rd.x() * self.u + rd.y() * self.v;
Ray::new(
self.origin,
self.lower_left_corner + s * self.horizontal + t * self.vertical - self.origin,
self.origin + offset,
self.lower_left_corner + s * self.horizontal + t * self.vertical - self.origin - offset,
)
}
}
4 changes: 2 additions & 2 deletions src/hit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ pub struct Sphere {
impl Hittable for Sphere {
fn hit(&self, t_min: f32, t_max: f32, ray: &Ray) -> Option<Hit> {
let oc = ray.origin - self.center;
let a = ray.direction.squared_length();
let a = ray.direction.length_squared();
let half_b = oc.dot(ray.direction);
let c = oc.squared_length() - self.radius * self.radius;
let c = oc.length_squared() - self.radius * self.radius;
let discriminant = half_b * half_b - a * c;
if discriminant < 0.0 {
return None;
Expand Down
22 changes: 10 additions & 12 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,21 +81,19 @@ fn main() {
}));

// Camera
// a distant view
// let cam = Camera::new(
// Vec3(-2.0, 2.0, 1.0),
// Vec3(0.0, 0.0, -1.0),
// Vec3(0.0, 1.0, 0.0),
// 90.0,
// ASPECT_RATIO,
// );
// zooming in
let look_from = Vec3(3.0, 3.0, 1.0);
let look_at = Vec3(0.0, 0.0, -1.0);
let vup = Vec3(0.0, 1.0, 0.0);
let dist_to_focus = (look_from - look_at).length();
let aperture: f32 = 2.0;
let cam = Camera::new(
Vec3(-2.0, 2.0, 1.0),
Vec3(0.0, 0.0, -1.0),
Vec3(0.0, 1.0, 0.0),
look_from,
look_at,
vup,
20.0,
ASPECT_RATIO,
aperture,
dist_to_focus,
);

// random f32
Expand Down
2 changes: 1 addition & 1 deletion src/materials.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ impl Material for Metal {
let reflected = Vec3::reflect(&r_in.direction.to_unit_vector(), &rec.normal.unwrap());
let scattered = Ray {
origin: rec.p,
direction: reflected + self.fuzz * Vec3::rand_in_unit_sphere(),
direction: reflected + self.fuzz * Vec3::random_in_unit_sphere(),
};
let same_direction = scattered.direction.dot(rec.normal.unwrap()) > 0.0;
if same_direction {
Expand Down
26 changes: 18 additions & 8 deletions src/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,12 @@ impl Vec3 {
)
}

pub fn squared_length(self) -> f32 {
pub fn length_squared(self) -> f32 {
self.dot(self)
}

pub fn length(self) -> f32 {
self.squared_length().sqrt()
self.length_squared().sqrt()
}

pub fn to_u8(&self) -> [u8; 3] {
Expand Down Expand Up @@ -148,31 +148,41 @@ impl Vec3 {
pub fn refract(v: &Vec3, n: &Vec3, etai_over_etat: f32) -> Vec3 {
let cos_theta = f32::min((-(*v)).dot(*n), 1.0);
let r_out_perp = etai_over_etat * (*v + cos_theta * (*n));
let r_out_parallel = libm::fabsf(1.0 - r_out_perp.squared_length()).sqrt() * -1.0 * *n;
let r_out_parallel = libm::fabsf(1.0 - r_out_perp.length_squared()).sqrt() * -1.0 * *n;
r_out_perp + r_out_parallel
}
pub fn other_refract(uv: Vec3, n: Vec3, etai_over_etat: f32) -> Vec3 {
let cos_theta = (-uv).dot(n);
let r_out_parallel = etai_over_etat * (uv + cos_theta * n);
let r_out_perp = -(1.0 - r_out_parallel.squared_length()).sqrt() * n;
let r_out_perp = -(1.0 - r_out_parallel.length_squared()).sqrt() * n;
r_out_parallel + r_out_perp
}

pub fn rand_in_unit_sphere() -> Vec3 {
pub fn random_in_unit_disk() -> Vec3 {
let gen_range = || -> f32 { rand::thread_rng().gen_range(-1.0..1.0) };
loop {
let p = Vec3(gen_range(), gen_range(), 0.0);
if p.length_squared() < 1.0 {
return p
}
}
}

pub fn random_in_unit_sphere() -> Vec3 {
loop {
let p = 2.0 * random::<Vec3>() - Vec3(1.0, 1.0, 1.0);
if p.squared_length() < 1.0 {
if p.length_squared() < 1.0 {
return p;
}
}
}

pub fn random_unit_vector() -> Vec3 {
Vec3::rand_in_unit_sphere().to_unit_vector()
Vec3::random_in_unit_sphere().to_unit_vector()
}

pub fn random_in_hemisphere(normal: &Vec3) -> Vec3 {
let in_unit_sphere = Vec3::rand_in_unit_sphere();
let in_unit_sphere = Vec3::random_in_unit_sphere();
if in_unit_sphere.dot(*normal) > 0.0 {
// In the same hemisphere as the normal
in_unit_sphere
Expand Down

0 comments on commit 0603298

Please sign in to comment.