69 lines
1.8 KiB
Rust
69 lines
1.8 KiB
Rust
use crate::math_utils::{reflect};
|
|
use crate::types_defined::{Color, HitRecord, Ray, Vec3};
|
|
|
|
|
|
#[derive(Debug)]
|
|
pub enum MaterialKind {
|
|
Lambertian(Lambertian),
|
|
Metal(Metal),
|
|
}
|
|
|
|
pub trait Material {
|
|
fn scatter(&self, r_in: &Ray, hit_record: &mut HitRecord, attenuation: &mut Color, ray: &mut Ray) -> bool;
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Lambertian {
|
|
pub albedo: Color,
|
|
}
|
|
|
|
impl Clone for Lambertian {
|
|
fn clone(&self) -> Self {
|
|
Lambertian {
|
|
albedo: self.albedo,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Material for Lambertian {
|
|
fn scatter(&self, r_in: &Ray, hit_record: &mut HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool {
|
|
|
|
let scatter_direction = r_in.direction + Vec3::random_unit_on_hemisphere(hit_record.normal);
|
|
// hit_record.normal + Vec3::random_unit();
|
|
// let scatter_direction = reflect(r_in.direction, hit_record.normal);
|
|
|
|
// if near_zero(scatter_direction) {
|
|
// scattered.direction = r_in.direction;
|
|
// }
|
|
|
|
*scattered = Ray::new(hit_record.p, scatter_direction);
|
|
*attenuation = self.albedo.clone();
|
|
|
|
true
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub struct Metal {
|
|
pub albedo: Color,
|
|
pub fuzz: f32
|
|
}
|
|
|
|
impl Clone for Metal {
|
|
fn clone(&self) -> Self {
|
|
Metal {
|
|
albedo: self.albedo,
|
|
fuzz: self.fuzz
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Material for Metal {
|
|
fn scatter(&self, r_in: &Ray, hit_record: &mut HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool {
|
|
let reflected = reflect(r_in.direction, hit_record.normal);
|
|
let fuzz_relected = (reflected / reflected.length_squared()) + (Vec3::random_unit() * self.fuzz);
|
|
*scattered = Ray::new(hit_record.p, fuzz_relected);
|
|
*attenuation = self.albedo.clone();
|
|
true
|
|
}
|
|
} |