ft: 10: metals

This commit is contained in:
2026-04-16 14:04:55 +02:00
parent e8f84b590b
commit b756cc394a
12 changed files with 199 additions and 41 deletions

View File

@@ -0,0 +1,79 @@
use rand::RngExt;
use crate::{
objects::{hit::Hit, materials::traits::Material},
ray::Ray,
vec3::{Colour, Vec3},
};
pub struct Lambertian {
albedo: Colour,
prob: f32,
}
impl Lambertian {
pub fn new(albedo: Colour, prob: f32) -> Self {
Self {
albedo: albedo,
prob: prob,
}
}
pub fn rgb(r: f32, g: f32, b: f32, prob: f32) -> Self {
Self {
albedo: Colour::new(r, g, b),
prob: prob,
}
}
}
impl Material for Lambertian {
fn scatter(&self, hit: &Hit, ray: &Ray) -> Option<(Ray, Colour)> {
let mut rng = rand::rng();
if self.prob >= rng.random::<f32>() {
let mut dir = *hit.n() + Vec3::random_unit();
if dir.near_zero() {
dir = *hit.n();
}
let scattered = Ray::new(*hit.p(), dir);
return Some((scattered, self.albedo));
}
return None;
}
}
pub struct Metal {
albedo: Colour,
prob: f32,
fuzz: f32,
}
impl Metal {
pub fn new(albedo: Colour, prob: f32, fuzz: f32) -> Self {
Self {
albedo: albedo,
prob: prob,
fuzz: fuzz,
}
}
pub fn rgb(r: f32, g: f32, b: f32, prob: f32, fuzz: f32) -> Self {
Self {
albedo: Colour::new(r, g, b),
prob: prob,
fuzz: fuzz,
}
}
}
impl Material for Metal {
fn scatter(&self, hit: &Hit, ray: &Ray) -> Option<(Ray, Colour)> {
let mut rng = rand::rng();
if self.prob >= rng.random::<f32>() {
let mut refl = ray.dir().reflect(hit.n());
refl = refl.get_unit() + self.fuzz * Vec3::random_unit();
return Some((Ray::new(*hit.p(), refl), self.albedo));
}
return None;
}
}