diff options
| author | ladevieq <ladevie.quentin@gmail.com> | 2020-12-21 23:13:25 +0100 |
|---|---|---|
| committer | ladevieq <ladevie.quentin@gmail.com> | 2020-12-21 23:13:25 +0100 |
| commit | 8da53c5f262b09756e1a93257cdcd5be25807839 (patch) | |
| tree | c34344074ca8766dafcbf27958f571bf14c35315 /src/dielectric.cpp | |
| parent | 56bed8e38f5b6d9effd77371ad781ae71601205b (diff) | |
Movable and rotatable camera + dielectric materials
Diffstat (limited to 'src/dielectric.cpp')
| -rw-r--r-- | src/dielectric.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/src/dielectric.cpp b/src/dielectric.cpp new file mode 100644 index 0000000..80ca069 --- /dev/null +++ b/src/dielectric.cpp @@ -0,0 +1,32 @@ +#include "dielectric.hpp" +#include "rt.hpp" +#include "hittable.hpp" + +dielectric::dielectric(double index_of_refraction) + : ior(index_of_refraction) {} + +bool dielectric::scatter(const ray& r, const struct hit_info& info, color& attenuation, ray& scattered) const { + auto unit_direction = r.direction.unit(); + auto refraction_ratio = info.front_face ? (1.0 / ior) : ior; + double cos_theta = fmin(info.normal.dot(-unit_direction), 1.0); + double sin_theta = sqrt(1.0 - cos_theta * cos_theta); + + vec3 direction; + if (refraction_ratio * sin_theta > 1.0 || reflectance(cos_theta, refraction_ratio) > randd()) { + direction = reflect(unit_direction, info.normal); + } else { + direction = refract(unit_direction, info.normal, refraction_ratio); + } + + scattered = ray { info.point, direction }; + attenuation = { 1.0, 1.0, 1.0 }; + + return true; +} + +double dielectric::reflectance(double cosine, double ref_idx) { + // Use Schlick's approximation for reflectance. + auto r0 = (1 - ref_idx) / (1 + ref_idx); + r0 = r0 * r0; + return r0 + (1 - r0) * pow ((1 - cosine), 5); +} |
