Compare commits

..

2 Commits

Author SHA1 Message Date
ffad2f12e4 Merge branch 'main' of ssh://git.djairo.dev:2222/djairoh/raytracing 2026-04-21 23:06:47 +02:00
79e6d04e50 ft: 11: dielectrics 2026-04-21 23:03:46 +02:00
2 changed files with 33 additions and 4 deletions

View File

@@ -21,18 +21,22 @@ fn main() {
pretty_env_logger::init(); pretty_env_logger::init();
// setup objects // setup objects
let blue = Arc::new(Metal::rgb(0.2, 0.4, 0.8, 1., 0.1));
let metal = Arc::new(Metal::rgb(0.7, 0.4, 0.2, 1., 0.1)); let metal = Arc::new(Metal::rgb(0.7, 0.4, 0.2, 1., 0.1));
let ground = Arc::new(Lambertian::rgb(0.8, 0.8, 0., 1.0)); let ground = Arc::new(Lambertian::rgb(0.8, 0.8, 0., 1.0));
let center = Arc::new(Lambertian::rgb(0.1, 0.2, 0.5, 1.)); let center = Arc::new(Lambertian::rgb(0.1, 0.2, 0.5, 1.));
let left = Arc::new(Dielectric::new(1.5)); let left = Arc::new(Dielectric::new(1.5));
let bubble = Arc::new(Dielectric::new(1. / 1.5));
let right = Arc::new(Metal::rgb(0.8, 0.6, 0.2, 1., 1.0)); let right = Arc::new(Metal::rgb(0.8, 0.6, 0.2, 1., 1.0));
let mut world = vec![Sphere::xyz(0., 0.5, -0.8, 0.1, metal.clone())]; let mut world = vec![Sphere::xyz(0., 0.5, -0.8, 0.1, metal.clone())];
world.push(Sphere::xyz(0., -100.5, -1., 100., ground.clone())); world.push(Sphere::xyz(0., -100.5, -1., 100., ground.clone()));
world.push(Sphere::xyz(0., 0., -1.2, 0.5, center.clone())); world.push(Sphere::xyz(0., 0., -1.2, 0.5, center.clone()));
world.push(Sphere::xyz(-1., 0., -1.0, 0.5, left.clone())); world.push(Sphere::xyz(-1., 0., -1.0, 0.5, left.clone()));
world.push(Sphere::xyz(-1., 0., -1.0, 0.4, bubble.clone()));
world.push(Sphere::xyz(1., 0., -1.0, 0.5, right.clone())); world.push(Sphere::xyz(1., 0., -1.0, 0.5, right.clone()));
world.push(Sphere::xyz(0., 0.7, -0.4, 0.2, blue.clone()));
let c = Camera::new(16. / 9., 800, 2, 50); let c = Camera::new(16. / 9., 1920, 3, 50);
c.render(&world); c.render(&world);
} }

View File

@@ -1,7 +1,11 @@
use core::f32::math::sqrt;
use rand::RngExt;
use crate::{ use crate::{
objects::{hit::Hit, materials::traits::Material}, objects::{hit::Hit, materials::traits::Material},
ray::Ray, ray::Ray,
vec3::Colour, vec3::{Colour, Vec3},
}; };
pub struct Dielectric { pub struct Dielectric {
@@ -14,6 +18,13 @@ impl Dielectric {
refraction_index: refraction_index, 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 { impl Material for Dielectric {
@@ -24,7 +35,21 @@ impl Material for Dielectric {
self.refraction_index self.refraction_index
}; };
let unit = ray.dir().get_unit(); let unit = ray.dir().get_unit();
let refr = unit.refract(&hit.n().get_unit(), ri); let cos_theta = if -unit.dot(hit.n()) > 1. {
Some((Ray::new(*hit.p(), refr), Colour::new(1., 1., 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.)))
} }
} }