From 272141d93324f32c15b7e230b0e37d122a418f54 Mon Sep 17 00:00:00 2001 From: Keuin Date: Fri, 15 Apr 2022 18:03:14 +0800 Subject: Add fuzzy reflective material. --- main_simple_scanner.cpp | 2 +- material_reflective.cpp | 16 +++++++++++++++- material_reflective.h | 39 ++++++++++++++++++++++++++++++++++----- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/main_simple_scanner.cpp b/main_simple_scanner.cpp index 054597b..72091dd 100644 --- a/main_simple_scanner.cpp +++ b/main_simple_scanner.cpp @@ -50,7 +50,7 @@ void generate_image(uint16_t image_width, uint16_t image_height, double viewport #ifdef SCENE_REFLECT material_diffuse_lambertian m_ground{{0.8, 0.8, 0.0}}; material_diffuse_lambertian m_ball_center{{0.7, 0.3, 0.3}}; - material_reflective m_ball_left{{0.8, 0.8, 0.8}}; + material_fuzzy_reflective m_ball_left{{0.8, 0.8, 0.8}, 1.0}; material_reflective m_ball_right{{0.8, 0.6, 0.2}}; // the earth world.add_object(std::make_shared(vec3d{0.0, -100.5, -1.0}, 100.0, m_ground)); diff --git a/material_reflective.cpp b/material_reflective.cpp index dc38baf..aa0d361 100644 --- a/material_reflective.cpp +++ b/material_reflective.cpp @@ -6,7 +6,9 @@ #include "material.h" #include "material_reflective.h" -bool material_reflective::scatter(ray3d &r, const object &hit_obj, double hit_t, random_uv_gen_3d &ruvg) const { +// perfectly-smooth reflective +template<> +bool material_reflective_::scatter(ray3d &r, const object &hit_obj, double hit_t, random_uv_gen_3d &ruvg) const { const auto hit_point = r.at(hit_t); const auto nv = hit_obj.normal_vector(hit_point); const auto reflected = nv.reflect(r.direction()); @@ -15,3 +17,15 @@ bool material_reflective::scatter(ray3d &r, const object &hit_obj, double hit_t, r.decay(albedo); return dot(reflected, nv) > 0; } + +// fuzzy reflective +template<> +bool material_reflective_::scatter(ray3d &r, const object &hit_obj, double hit_t, random_uv_gen_3d &ruvg) const { + const auto hit_point = r.at(hit_t); + const auto nv = hit_obj.normal_vector(hit_point); + const auto reflected = nv.reflect(r.direction()) + fuzzy_.f * ruvg.range01(); + r.source(hit_point); + r.direction(reflected.unit_vec()); + r.decay(albedo); + return dot(reflected, nv) > 0; +} \ No newline at end of file diff --git a/material_reflective.h b/material_reflective.h index 91afa7c..64e6457 100644 --- a/material_reflective.h +++ b/material_reflective.h @@ -8,15 +8,44 @@ #include "vec.h" #include "material.h" -// metal -class material_reflective : public material { +template +struct s_fuzzy_ { + // non-fuzzy material does not need these variables + // we remove them with an empty struct +}; + +template<> +struct s_fuzzy_ { + double f; // how fuzzy the material is + // those are parameters that only fuzzy materials have +}; + +// metal with perfectly smooth surface +template +class material_reflective_ : public material { vec3d albedo; + s_fuzzy_ fuzzy_; public: - explicit material_reflective(vec3d &color) : albedo(color) {} - explicit material_reflective(vec3d &&color) : albedo(color) {} - explicit material_reflective(double color) : albedo{color, color, color} {} + // FIXME conditionally enable these constructors by template parameter `Fuzzy`. + + // Non-fuzzy constructors + explicit material_reflective_(vec3d &color) : albedo(color), fuzzy_{} {} + + explicit material_reflective_(vec3d &&color) : albedo(color), fuzzy_{} {} + + explicit material_reflective_(double color) : albedo{color, color, color}, fuzzy_{} {} + + // Fuzzy constructors, with special parameters + explicit material_reflective_(vec3d &color, double f) : albedo(color), fuzzy_{f} {} + + explicit material_reflective_(vec3d &&color, double f) : albedo(color), fuzzy_{f} {} + + explicit material_reflective_(double color, double f) : albedo{color, color, color}, fuzzy_{f} {} bool scatter(ray3d &r, const object &hit_obj, double hit_t, random_uv_gen_3d &ruvg) const override; }; +using material_reflective = material_reflective_; +using material_fuzzy_reflective = material_reflective_; + #endif //RT_MATERIAL_REFLECTIVE_H -- cgit v1.2.3