Skip to content

Commit

Permalink
Glass material
Browse files Browse the repository at this point in the history
  • Loading branch information
Jeremy5909 committed May 1, 2024
1 parent bc2cbe9 commit ac32a7b
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 11 deletions.
21 changes: 12 additions & 9 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use camera::Camera;
use color::Color;
use material::{Lambertian, Metal};
use material::{Dielectric, Lambertian, Metal};

use crate::{hittable_list::HittableList, sphere::Sphere, vec3::Point3};

Expand All @@ -15,21 +15,24 @@ mod camera;
mod material;

fn main() {
let ground = Lambertian {albedo: Color::new(0.8,0.8,0.0)};
let center = Lambertian {albedo: Color::new(0.1, 0.2, 0.5)};
let left = Metal {albedo: Color::new(0.8, 0.8, 0.8), fuzz: 0.3};
let right = Metal {albedo: Color::new(0.8, 0.6, 0.2), fuzz: 1.0};
let ground_mat = Lambertian {albedo: Color::new(0.8,0.8,0.0)};
let center_mat = Lambertian {albedo: Color::new(0.1, 0.2, 0.5)};
let left_mat = Dielectric { refraction_index: 1.5};
let bubble_mat = Dielectric { refraction_index: 1.0 / 1.5};
let right_mat = Metal {albedo: Color::new(0.8, 0.6, 0.2), fuzz: 1.0};

let mut world = HittableList::new();

let ground = Sphere::new(Point3::new(0.0, -100.5, -1.0), 100.0, &ground);
let center = Sphere::new(Point3::new(0.0, 0.0, -1.2), 0.5, &center);
let left = Sphere::new(Point3::new(-1.0, 0.0, -1.0), 0.5, &left);
let right = Sphere::new(Point3::new(1.0, 0.0, -1.0), 0.5, &right);
let ground = Sphere::new(Point3::new(0.0, -100.5, -1.0), 100.0, &ground_mat);
let center = Sphere::new(Point3::new(0.0, 0.0, -1.2), 0.5, &center_mat);
let left = Sphere::new(Point3::new(-1.0, 0.0, -1.0), 0.5, &left_mat);
let bubble = Sphere::new(Point3::new(-1.0, 0.0, -1.0), 0.4, &bubble_mat);
let right = Sphere::new(Point3::new(1.0, 0.0, -1.0), 0.5, &right_mat);

world.add(&ground);
world.add(&center);
world.add(&left);
world.add(&bubble);
world.add(&right);

let mut cam = Camera::new(16.0/9.0, 400);
Expand Down
33 changes: 32 additions & 1 deletion src/material.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use crate::{color::Color, hittable::HitRecord, ray::Ray, vec3::{random_unit_vector, reflect, unit_vector}};
use rand::random;

use crate::{color::Color, hittable::HitRecord, ray::Ray, vec3::{dot, random_unit_vector, reflect, refract, unit_vector}};

pub trait Material {
fn scatter(&self, r_in: &Ray, rec: &HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool;
Expand Down Expand Up @@ -36,3 +38,32 @@ impl Material for Metal {
true
}
}

pub struct Dielectric { pub refraction_index: f64 }
impl Dielectric {
fn reflectance(cosine: f64, refraction_index: f64) -> f64 {
let r0 = (1.0 - refraction_index) / (1.0 + refraction_index);
let r0 = r0 * r0;
r0 + (1.0-r0) * (1.0 - cosine).powi(5)

}
}
impl Material for Dielectric {
fn scatter(&self, r_in: &Ray, rec: &HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool {
*attenuation = Color::new(1.0, 1.0, 1.0);
let ri = if rec.front_face {1.0/self.refraction_index} else {self.refraction_index};

let unit_dir = unit_vector(r_in.dir());
let cos_theta = dot(-unit_dir, rec.normal).min(1.0);
let sin_theta = (1.0 - cos_theta*cos_theta).sqrt();

let direction = if ri * sin_theta > 1.0 || Self::reflectance(cos_theta, ri) > random() {
reflect(&unit_dir, &rec.normal)
} else {
refract(&unit_dir, &rec.normal, ri)
};

*scattered = Ray::new(rec.p, direction);
true
}
}
9 changes: 8 additions & 1 deletion src/vec3.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{fmt::Display, ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, RangeBounds, Sub}};
use std::{cmp::min, fmt::Display, ops::{Add, AddAssign, Div, DivAssign, Index, IndexMut, Mul, MulAssign, Neg, RangeBounds, Sub}};
use rand::{distributions::uniform::SampleRange, random, thread_rng, Rng};

#[derive(Clone, Copy, Default)]
Expand Down Expand Up @@ -167,4 +167,11 @@ pub fn random_on_hemisphere(normal: Vec3) -> Vec3 {

pub fn reflect(v: &Vec3, n: &Vec3) -> Vec3 {
*v - 2.0 * dot(*n, *v) * *n
}

pub fn refract(uv: &Vec3, n: &Vec3, etai_over_etat: f64) -> Vec3 {
let cos_theta = dot(- *uv, *n).min(1.0);
let r_out_perp = etai_over_etat * (*uv + cos_theta * *n);
let r_out_parallel = -(1.0 - r_out_perp.length_squared()).abs().sqrt() * *n;
r_out_parallel + r_out_perp
}

0 comments on commit ac32a7b

Please sign in to comment.