ft: 11: dielectrics

This commit is contained in:
2026-04-21 23:03:46 +02:00
parent 66c6bf438b
commit 79e6d04e50
2 changed files with 33 additions and 4 deletions

View File

@@ -1,7 +1,11 @@
use core::f32::math::sqrt;
use rand::RngExt;
use crate::{
objects::{hit::Hit, materials::traits::Material},
ray::Ray,
vec3::Colour,
vec3::{Colour, Vec3},
};
pub struct Dielectric {
@@ -14,6 +18,13 @@ impl Dielectric {
refraction_index: refraction_index,
}
}
fn _reflectance(cos: f32, refraction_index: f32) -> f32 {
// Shlick's approximation
let mut r0 = (1. - refraction_index) / (1. + refraction_index);
r0 *= r0;
return r0 + (1. - r0) * (1. - cos).powf(5.);
}
}
impl Material for Dielectric {
@@ -24,7 +35,21 @@ impl Material for Dielectric {
self.refraction_index
};
let unit = ray.dir().get_unit();
let refr = unit.refract(hit.n(), ri);
Some((Ray::new(*hit.p(), refr), Colour::new(1., 1., 1.)))
let cos_theta = if -unit.dot(hit.n()) > 1. {
1.
} else {
-unit.dot(hit.n())
};
let sin_theta = sqrt(1. - cos_theta * cos_theta);
let cannot_refract = ri * sin_theta > 1.;
let dir: Vec3;
let mut rng = rand::rng();
if cannot_refract || Dielectric::_reflectance(cos_theta, ri) > rng.random::<f32>() {
dir = unit.reflect(hit.n());
} else {
dir = unit.refract(hit.n(), ri);
}
Some((Ray::new(*hit.p(), dir), Colour::new(1., 1., 1.)))
}
}