use crate::{
HitData,
random,
Material,
Ray, ray,
Vec3, dot, normalize, reflect
};
pub struct Metal {
albedo: Vec3,
fuzziness: f32
}
impl Metal {
pub fn new(albedo: Vec3, fuzziness: f32) -> Metal {
let fuzziness = if fuzziness < 0f32 { 0f32 } else
if fuzziness > 1f32 { 1f32 } else
{ fuzziness };
Metal {albedo, fuzziness}
}
}
impl Material for Metal {
fn scatter(&self, ray_in: &Ray, hit_data: &HitData) -> (Vec3, Ray) {
let reflected = reflect!(normalize!(ray_in.direction), hit_data.normal);
let attenuation = self.albedo;
let mut scattered = ray!(
hit_data.point,
reflected + self.fuzziness * random::point_in_sphere()
);
if dot!(scattered.direction, hit_data.normal) < 0f32 {
scattered.direction = -scattered.direction
}
(attenuation, scattered)
}
}