diff options
Diffstat (limited to 'src/material')
-rw-r--r-- | src/material/dielectric.rs | 25 | ||||
-rw-r--r-- | src/material/mod.rs | 1 |
2 files changed, 25 insertions, 1 deletions
diff --git a/src/material/dielectric.rs b/src/material/dielectric.rs index bcacb78..1a49f73 100644 --- a/src/material/dielectric.rs +++ b/src/material/dielectric.rs @@ -1,10 +1,18 @@ +use std::ops::Neg; + use super::Material; use crate::{hittable::HitRecord, vec3::Vec3}; use crate::vec3::Color; use crate::ray::Ray; +pub struct DielectricAttenuation { + pub albedo: Color, + pub constant: f64, +} + pub struct Dielectric { pub index_of_refraction: f64, + pub attenuation: Option<DielectricAttenuation>, } impl Dielectric { @@ -18,7 +26,22 @@ impl Dielectric { impl Material for Dielectric { fn scatter(&self, ray_in: &Ray, hit_record: &HitRecord, attenuation: &mut Color, scattered: &mut Ray) -> bool { - *attenuation = Color { x: 1.0, y: 1.0, z: 1.0 }; + if let Some(props) = &self.attenuation { + let outward_normal = if hit_record.front_face { + hit_record.normal.clone() + } else { + -&hit_record.normal + }; + if outward_normal.dot(&ray_in.direction) > 0.0 { + let distance = (&ray_in.origin - &hit_record.p).length(); + let falloff_ratio = (props.constant * distance).neg().exp(); + *attenuation = &props.albedo * falloff_ratio; + } else { + *attenuation = props.albedo.clone(); + } + } else { + *attenuation = Color { x: 1.0, y: 1.0, z: 1.0 }; + } let refraction_ratio = if hit_record.front_face { 1.0 / self.index_of_refraction } else { self.index_of_refraction }; let unit_direction = ray_in.direction.unit_vector(); let cos_theta = hit_record.normal.dot(&-&unit_direction).min(1.0); diff --git a/src/material/mod.rs b/src/material/mod.rs index bf1eb24..c292ea1 100644 --- a/src/material/mod.rs +++ b/src/material/mod.rs @@ -4,6 +4,7 @@ mod metal; pub use metal::Metal; mod dielectric; pub use dielectric::Dielectric; +pub use dielectric::DielectricAttenuation; mod diffuse_light; pub use diffuse_light::DiffuseLight; mod isotropic; |