diff options
author | Keuin <[email protected]> | 2022-04-16 15:22:40 +0800 |
---|---|---|
committer | Keuin <[email protected]> | 2022-04-16 15:49:01 +0800 |
commit | 52d11df35ca9846085b910e2e40434b48847d9d8 (patch) | |
tree | d12c19f67096d309b40807b99b5d90e5ed363a43 | |
parent | 52a8d9345762e7b2755ca78ae237058c8ebaa20c (diff) |
Add dielectric reflectiveness (using Schlick's Approximation).
-rw-r--r-- | material_dielectric.cpp | 15 | ||||
-rw-r--r-- | material_dielectric.h | 11 |
2 files changed, 24 insertions, 2 deletions
diff --git a/material_dielectric.cpp b/material_dielectric.cpp index 3aaf259..ed8e4eb 100644 --- a/material_dielectric.cpp +++ b/material_dielectric.cpp @@ -9,13 +9,24 @@ bool material_dielectric::scatter(ray3d &r, const object &hit_obj, double hit_t, assert(hit_obj.is_on(hit_p)); auto n = hit_obj.normal_vector(hit_p); auto ri_ = ri_inv; - if (dot(r.direction(), n) > 0) { + auto cos1 = dot(r.direction(), n); // -cos(a1) + if (cos1 > 0) { // the ray is started from the object's inner, // use normal vector and ri on the surface's inner side n = -n; ri_ = 1.0 / ri_; + } else { + cos1 = -cos1; + } + vec3d r2; + // determine reflection or refraction using Schlick's Approximation. + if (reflectance(cos1, ri_) > ruvg.range01_scalar()) { + // reflect + r2 = n.reflect(r.direction()); + } else { + // refract + r2 = n.refract<true>(r.direction(), ri_); } - const auto r2 = n.refract<true>(r.direction(), ri_); // refracted vector r.direction(r2.unit_vec()); r.source(hit_p); return true; diff --git a/material_dielectric.h b/material_dielectric.h index 48382b4..46b17da 100644 --- a/material_dielectric.h +++ b/material_dielectric.h @@ -10,8 +10,19 @@ class material_dielectric : public material { double ri_inv; + + static double reflectance(double cosine, double ref_idx) { + assert(cosine > 0); + assert(ref_idx > 0); + // 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); + } + public: explicit material_dielectric(double ri) : ri_inv{1.0 / ri} {} + bool scatter(ray3d &r, const object &hit_obj, double hit_t, random_uv_gen_3d &ruvg) const override; }; |