diff --git a/README.md b/README.md index a8e7723..2518a3c 100644 --- a/README.md +++ b/README.md @@ -26,3 +26,7 @@ The Web Site of the book: http://raytracerchallenge.com/ | Chapiter 07 | Chapiter 08 | Chapiter 09 | |:------------------------: | :------------------------: | :----------------------------: | |![07](data/chapter_07.png) | ![08](data/chapter_08.png) | ![09](data/chapter_09.png) | + +| Chapiter 10 | Chapiter 11 | Chapiter 12 | +|:------------------------: | :------------------------: | :----------------------------: | +|![10](data/chapter_10.png) | | | \ No newline at end of file diff --git a/apps/chapter_10.cpp b/apps/chapter_10.cpp index aae064c..eec1250 100644 --- a/apps/chapter_10.cpp +++ b/apps/chapter_10.cpp @@ -43,44 +43,79 @@ int main(void) World the_world; Camera the_camera; Canvas the_canvas; - Plane *the_floor; + Plane *the_floor, *the_left_wall, *the_right_wall; Sphere *the_middle, *the_right, *the_left; chrono::time_point the_start, the_end; printf("Chapter 10 example.\n"); // Floor is an extremely flattened sphere with a matte texture. - the_floor = new Plane(); + the_floor = new Plane(); Material &the_floor_material = the_floor->material(); the_floor_material.set_color(Color(1, 0.9, 0.9)); the_floor_material.set_specular(0); - the_floor_material.set_pattern(new StripePattern(Color(1, 1, 1), Color(1, 0.9, 0.9))); + the_floor_material.set_pattern(new CheckersPattern(Color(0.52, 0.52, 0.52), Color::Black())); the_world.add_object(the_floor); + // Left Wall + the_left_wall = new Plane(); + the_left_wall->set_transform(Matrix::translation(0, 0, 10) * + Matrix::rotation_y(-std::numbers::pi / 4) * + Matrix::rotation_x(std::numbers::pi / 2)); + Material &the_left_wall_material = the_left_wall->material(); + the_left_wall_material.set_specular(0); + the_left_wall_material.set_pattern(new StripePattern(Color(0.52, 0.52, 0.52), Color::Black())); + the_world.add_object(the_left_wall); + + // Right Wall + the_right_wall = new Plane(); + the_right_wall->set_transform(Matrix::translation(0, 5, 10) * + Matrix::rotation_y(std::numbers::pi / 4) * + Matrix::rotation_x(std::numbers::pi / 2) * + Matrix::scaling(0.15, 0.15, 0.15)); + Material &the_right_wall_material = the_right_wall->material(); + the_right_wall_material.set_specular(0); + the_right_wall_material.set_pattern(new RingPattern(Color(1, 0.5, 0), Color(0.5, 1, 1))); + the_right_wall_material.pattern()->set_transform(Matrix::translation(25, 0, 15)); + the_world.add_object(the_right_wall); + // The large sphere in the middle is a unit sphere, translated upward slightly and colored green. the_middle = new Sphere(); - the_middle->set_transform(Matrix::translation(-0.5, 1, 0.5)); + the_middle->set_transform(Matrix::translation(-0.25, 1, 1.5) * + Matrix::rotation_y(-std::numbers::pi / 1.5) * + Matrix::rotation_z(-std::numbers::pi / 6)); + Material &the_middle_material = the_middle->material(); the_middle_material.set_color(Color(0.1, 1, 0.5)); - the_middle_material.set_pattern(new StripePattern(Color(1, 1, 1), Color(0.1, 1, 0.5))); + the_middle_material.set_pattern(new RingPattern(Color(0.24, 0.74, 0.37), Color(0.14, 0.47, 0.22))); + the_middle_material.pattern()->set_transform(Matrix::scaling(0.15, 0.15, 0.15) * + Matrix::rotation_x(std::numbers::pi / 2) * + Matrix::rotation_z(std::numbers::pi / 4)); the_middle_material.set_diffuse(0.7); the_middle_material.set_specular(0.3); the_world.add_object(the_middle); // The smaller green sphere on the right is scaled in half the_right = new Sphere(); - the_right->set_transform(Matrix::translation(1.5, 0.5, -0.5) * Matrix::scaling(0.5, 0.5, 0.5)); + the_right->set_transform(Matrix::translation(1.5, 0.5, -0.5) * + Matrix::scaling(0.5, 0.5, 0.5) * + Matrix::rotation_y(std::numbers::pi / 4)); Material &the_right_material = the_right->material(); the_right_material.set_color(Color(0.5, 1, 0.1)); + the_right_material.set_pattern(new GradientPattern(Color(0.53, 0.07, 0), Color(0.49, 0.40, 0))); + the_right_material.pattern()->set_transform(Matrix::scaling(2, 2, 2) * + Matrix::rotation_y(std::numbers::pi / 4)); the_right_material.set_diffuse(0.7); the_right_material.set_specular(0.3); the_world.add_object(the_right); // The smallest sphere is scaled by a third, before being translated the_left = new Sphere(); - the_left->set_transform(Matrix::translation(-1.5, 0.33, -0.75) * Matrix::scaling(0.33, 0.33, 0.33)); + the_left->set_transform(Matrix::translation(-1.5, 0.66, -1) * Matrix::scaling(0.66, 0.66, 0.66)); Material &the_left_material = the_left->material(); the_left_material.set_color(Color(1, 0.8, 0.1)); + the_left_material.set_pattern(new StripePattern(Color(0.25, 0.25, 0.8), Color(0.5, 0.5, 1))); + the_left_material.pattern()->set_transform(Matrix::scaling(0.15, 1, 1)); the_left_material.set_diffuse(0.7); the_left_material.set_specular(0.3); the_world.add_object(the_left); @@ -89,14 +124,14 @@ int main(void) the_world.set_light(PointLight(Tuple::Point(-10, 10, -10), Color(1, 1, 1))); // Configure the camera. - // the_camera = Camera(100, 50, std::numbers::pi / 2); - the_camera = Camera(320, 200, std::numbers::pi / 2); + // the_camera = Camera(100, 50, std::numbers::pi / 3); + the_camera = Camera(320, 200, std::numbers::pi / 3); the_camera.set_transform( - Matrix::view_transform(Tuple::Point(0, 1.5, -3.5), Tuple::Point(0, 1, 0), Tuple::Vector(0, 1, 0))); + Matrix::view_transform(Tuple::Point(0, 1.5, -5), Tuple::Point(0, 1, 0), Tuple::Vector(0, 1, 0))); - the_start = chrono::high_resolution_clock::now(); + the_start = chrono::high_resolution_clock::now(); the_canvas = the_camera.render(the_world); - the_end = chrono::high_resolution_clock::now(); + the_end = chrono::high_resolution_clock::now(); the_canvas.save_to_file("chapter10.ppm"); diff --git a/data/chapter_10.png b/data/chapter_10.png new file mode 100644 index 0000000..1b7517f Binary files /dev/null and b/data/chapter_10.png differ diff --git a/raytracing/src/renderer/material.cpp b/raytracing/src/renderer/material.cpp index 6d7a3f4..4be26af 100644 --- a/raytracing/src/renderer/material.cpp +++ b/raytracing/src/renderer/material.cpp @@ -133,7 +133,7 @@ void Material::set_shininess(double a_value) /* ------------------------------------------------------------------------- */ -const Pattern *Material::pattern(void) const +Pattern *Material::pattern(void) { return m_pattern; } @@ -191,7 +191,7 @@ Color Material::lighting(Shape *an_object, const PointLight &a_light, const Tupl // reflect_dot_eye represent the consine of the angle between reflection vector and the eye vector. // A negative number means the light reflects away from the eye. - the_reflect_v = (-the_light_v).reflect(a_normalv); + the_reflect_v = (-the_light_v).reflect(a_normalv); double the_reflect_dot_eye = the_reflect_v.dot(an_eyev); if (the_reflect_dot_eye <= 0) { @@ -201,7 +201,7 @@ Color Material::lighting(Shape *an_object, const PointLight &a_light, const Tupl { // Compute the specular contribution double the_factor = std::pow(the_reflect_dot_eye, m_shininess); - the_specular = a_light.intensity() * m_specular * the_factor; + the_specular = a_light.intensity() * m_specular * the_factor; } } diff --git a/raytracing/src/renderer/material.h b/raytracing/src/renderer/material.h index 58464bd..9457926 100644 --- a/raytracing/src/renderer/material.h +++ b/raytracing/src/renderer/material.h @@ -62,7 +62,7 @@ namespace Raytracer const double &shininess(void) const; void set_shininess(double a_value); - const Pattern *pattern(void) const; + Pattern *pattern(void); void set_pattern(Pattern *a_pattern); Color lighting(Shape *an_object, const PointLight &a_light, const Tuple &a_point, const Tuple &an_eyev,