diff --git a/raytracing/src/renderer/world.cpp b/raytracing/src/renderer/world.cpp index 47c7d34..0a7ee5c 100644 --- a/raytracing/src/renderer/world.cpp +++ b/raytracing/src/renderer/world.cpp @@ -168,6 +168,20 @@ Color World::shade_hit(const IntersectionData &an_intersection_data) const /* ------------------------------------------------------------------------- */ +Color World::reflected_color(const IntersectionData &a_data) const +{ + if (a_data.object()->material().reflective() == 0.0) + { + return Color(0, 0, 0); + } + Ray the_reflected_ray(a_data.over_point(), a_data.reflectv()); + Color the_color = color_at(the_reflected_ray); + + return the_color * a_data.object()->material().reflective(); +} + +/* ------------------------------------------------------------------------- */ + Color World::color_at(const Ray &a_ray) const { Color the_color = Color::Black(); diff --git a/raytracing/src/renderer/world.h b/raytracing/src/renderer/world.h index 806da10..acb5ec0 100644 --- a/raytracing/src/renderer/world.h +++ b/raytracing/src/renderer/world.h @@ -64,6 +64,7 @@ namespace Raytracer Intersections intersect_world(const Ray &a_ray) const; Color shade_hit(const IntersectionData &an_intersection_data) const; + Color reflected_color(const IntersectionData &an_intersection_data) const; Color color_at(const Ray &a_ray) const; bool is_shadowed(const Tuple &a_point) const; diff --git a/tests/11_reflection_refraction.cpp b/tests/11_reflection_refraction.cpp index 6ed2359..b81fb47 100644 --- a/tests/11_reflection_refraction.cpp +++ b/tests/11_reflection_refraction.cpp @@ -70,3 +70,83 @@ SCENARIO("Precomputing the reflection vector", "[features/intersections.feature] } } } + +/* ------------------------------------------------------------------------- */ + +SCENARIO("The reflected color for a non reflective material", "[features/world.feature]") +{ + GIVEN("w <- default_world()") + { + World w = World::default_world(); + AND_GIVEN("ray(point(0, 0, 0), vector(0, 0, 1)") + { + Ray r(Tuple::Point(0, 0, 0), Tuple::Vector(0, 0, 1)); + AND_GIVEN("shape <-the second object in w") + { + Shape *shape = w.objects(1); + AND_GIVEN("shape.material.ambient <- 1") + { + shape->material().set_ambient(1); + AND_GIVEN("i <- intersection(1, shape)") + { + Intersection i(1, shape); + WHEN("comps <- prepare_computation(i, r)") + { + IntersectionData comps = i.prepare_computations(r); + AND_WHEN("color <- reflected_color(w, comps)") + { + Color color = w.reflected_color(comps); + THEN("color = color(0, 0, 0)") + { + REQUIRE(color == Color(0, 0, 0)); + } + } + } + } + } + } + } + } +} + +/* ------------------------------------------------------------------------- */ + +SCENARIO("The reflected color for a reflective material", "[features/world.feature]") +{ + GIVEN("w <- default_world()") + { + World w = World::default_world(); + AND_GIVEN("shape <- plane() with:") + // | material.reflective | 0.5 | + // | transform | translation(0, -1, 0) | + { + Plane shape; + shape.material().set_reflective(0.5); + shape.set_transform(Matrix::translation(0, -1, 0)); + AND_GIVEN("shape is added to w") + { + w.add_object(&shape); + AND_GIVEN("ray(point(0, 0, -3), vector(0, -sqrt(2) / 2, sqrt(2) / 2)") + { + Ray r(Tuple::Point(0, 0, -3), Tuple::Vector(0, -sqrt(2) / 2, sqrt(2) / 2)); + AND_GIVEN("i <- intersection(1, shape)") + { + Intersection i(sqrt(2), &shape); + WHEN("comps <- prepare_computation(i, r)") + { + IntersectionData comps = i.prepare_computations(r); + AND_WHEN("color <- reflected_color(w, comps)") + { + Color color = w.reflected_color(comps); + THEN("color = color(0, 0, 0)") + { + REQUIRE(color == Color(0.19032, 0.2379, 0.14274)); + } + } + } + } + } + } + } + } +}