Feat: Total internal reflection, Schlick's approx.

Completion of Chapter 10: Dielectrics.
This commit is contained in:
2023-06-06 18:06:59 -05:00
parent 4f14a166a6
commit 7ee6da0234
2 changed files with 28 additions and 4 deletions

View File

@@ -4,6 +4,7 @@ use crate::hittable::HitRecord;
use crate::vec3;
use crate::vec3::Vec3;
use rand::Rng;
use rand::rngs::SmallRng;
use rand::distributions::Uniform;
@@ -64,14 +65,28 @@ impl Material {
let refraction_ratio = if rec.front_face { 1.0 / index_refraction } else { *index_refraction };
let unit_direction = Vec3::as_unit(ray_in.dir);
let refracted = Vec3::refract(unit_direction, rec.normal, refraction_ratio);
let cos_theta = vec3::min(Vec3::dot(-unit_direction, rec.normal), 1.0);
let sin_theta = (1.0 - cos_theta * cos_theta).sqrt();
let cannot_refract = refraction_ratio * sin_theta > 1.0;
let direction = if cannot_refract || Material::reflectance(cos_theta, refraction_ratio) > srng.sample(distrib) {
Vec3::reflect(unit_direction, rec.normal)
} else {
Vec3::refract(unit_direction, rec.normal, refraction_ratio)
};
*scattered = Ray {
orig: rec.p,
dir: refracted
dir: direction
};
return true;
},
}
}
fn reflectance(cosine: f32, ref_idx: f32) -> f32 {
// Schlick's approximation for reflectance.
let r0 = (1.0 - ref_idx) / (1.0 + ref_idx);
let r0 = r0 * r0;
return r0 + (1.0 - r0) * (1.0 - cosine).powf(5.0);
}
}