diff --git a/source/camera.cpp b/source/camera.cpp index d6fb29a..b7ce660 100644 --- a/source/camera.cpp +++ b/source/camera.cpp @@ -55,7 +55,7 @@ Ray Camera::rayForPixel(uint32_t pixelX, uint32_t pixelY) return Ray(origin, direction); } -Canvas Camera::render(World world) +Canvas Camera::render(World world, uint32_t depth) { uint32_t x, y; Canvas image = Canvas(this->horizontalSize, this->verticalSize); @@ -65,7 +65,7 @@ Canvas Camera::render(World world) for(x = 0; x < this->horizontalSize; x++) { Ray r = this->rayForPixel(x, y); - Tuple colour = world.colourAt(r); + Tuple colour = world.colourAt(r, depth); image.putPixel(x, y, colour); } } diff --git a/source/include/camera.h b/source/include/camera.h index 2b30256..96c0b2f 100644 --- a/source/include/camera.h +++ b/source/include/camera.h @@ -32,7 +32,7 @@ public: Camera(uint32_t hsize, uint32_t vsize, double fov); void setTransform(Matrix transform); Ray rayForPixel(uint32_t pixelX, uint32_t pixelY); - Canvas render(World w); + Canvas render(World w, uint32_t depth = 5); }; #endif /* DORAYME_CAMERA_H */ diff --git a/source/include/world.h b/source/include/world.h index cf4f31c..bcb3af3 100644 --- a/source/include/world.h +++ b/source/include/world.h @@ -47,7 +47,7 @@ public: bool isShadowed(Tuple point); Colour reflectColour(Computation comps, uint32_t depthCount = 4); - Colour refractedColour(Computation comps, uint32_t depthCount = 0); + Colour refractedColour(Computation comps, uint32_t depthCount = 4); Intersect intersect(Ray r); diff --git a/source/world.cpp b/source/world.cpp index 103724f..d4c2c8c 100644 --- a/source/world.cpp +++ b/source/world.cpp @@ -175,6 +175,5 @@ Colour World::refractedColour(Computation comps, uint32_t depthCount) Tuple hitColour = this->colourAt(refractedRay, depthCount - 1) * comps.object->material.transparency; - return Colour(hitColour.x, hitColour.y, hitColour.z); } \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index fd5a7e6..2606c59 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -49,10 +49,15 @@ target_include_directories(ch11_reflection PUBLIC ../source/include) target_sources(ch11_reflection PRIVATE ch11_reflection.cpp) target_link_libraries(ch11_reflection rayonnement) -add_executable(ch11_refractiontest) -target_include_directories(ch11_refractiontest PUBLIC ../source/include) -target_sources(ch11_refractiontest PRIVATE ch11_refractiontest.cpp) -target_link_libraries(ch11_refractiontest rayonnement) +add_executable(ch11_refraction) +target_include_directories(ch11_refraction PUBLIC ../source/include) +target_sources(ch11_refraction PRIVATE ch11_refraction.cpp) +target_link_libraries(ch11_refraction rayonnement) + +add_executable(ch11_test) +target_include_directories(ch11_test PUBLIC ../source/include) +target_sources(ch11_test PRIVATE ch11_test.cpp) +target_link_libraries(ch11_test rayonnement) add_test(NAME Chapter05_Test COMMAND $) add_test(NAME Chapter06_Test COMMAND $) @@ -60,4 +65,5 @@ add_test(NAME Chapter07_Test COMMAND $) add_test(NAME Chapter09_Test COMMAND $) add_test(NAME Chapter10_Test COMMAND $) add_test(NAME Chapter11_Reflection COMMAND $) -add_test(NAME Chapter11_RefractionTest COMMAND $) +add_test(NAME Chapter11_Refraction COMMAND $) +add_test(NAME Chapter11_Test COMMAND $) diff --git a/tests/ch11_refraction.cpp b/tests/ch11_refraction.cpp new file mode 100644 index 0000000..47fe47f --- /dev/null +++ b/tests/ch11_refraction.cpp @@ -0,0 +1,69 @@ +/* + * DoRayMe - a quick and dirty Raytracer + * Render test for reflection in chapter 11. + * + * Created by Manoël Trapier + * Copyright (c) 2020 986-Studio. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +int main() +{ + World w = World(); + + /* First we need to construct the world */ + Plane floor = Plane(); + floor.material.pattern = new CheckersPattern(Colour(1, 1, 1), Colour(0, 0, 0)); + floor.setTransform(translation(0, -10, 0)); + w.addObject(&floor); + + + Sphere glassBall = Sphere(); + glassBall.material.shininess = 300; + glassBall.material.transparency = 1; + glassBall.material.refractiveIndex = 1.52; + glassBall.material.diffuse = 0.1; + w.addObject(&glassBall); + + Sphere airBall = Sphere(); + airBall.setTransform(scaling(0.5, 0.5, 0.5)); + airBall.material.shininess = 300; + airBall.material.transparency = 1; + airBall.material.refractiveIndex = 1.0009; + airBall.material.diffuse = 0.1; + w.addObject(&airBall); + + /* Add light */ + Light light = Light(POINT_LIGHT, Point(20, 10, 0), Colour(0.7, 0.7, 0.7)); + w.addLight(&light); + + /* Set the camera */ + Camera camera = Camera(1000, 1000, M_PI / 3); + + camera.setTransform(viewTransform(Point(0, 2.5, 0), + Point(0, 0, 0), + Vector(1, 0, 0))); + + /* Now render it */ + Canvas image = camera.render(w); + + image.SaveAsPNG("ch11_refraction.png"); + + return 0; +} \ No newline at end of file diff --git a/tests/ch11_refractiontest.cpp b/tests/ch11_refractiontest.cpp deleted file mode 100644 index 03728e6..0000000 --- a/tests/ch11_refractiontest.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * DoRayMe - a quick and dirty Raytracer - * Render test for reflection in chapter 11. - * - * Created by Manoël Trapier - * Copyright (c) 2020 986-Studio. - * - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -int main() -{ - World w = World(); - - /* First we need to construct the world */ - Plane floor = Plane(); - floor.material.specular = 0; - floor.material.pattern = new CheckersPattern(Colour(1, 1, 1), Colour(0, 0, 0)); - floor.material.pattern->setTransform(scaling(0.7, 0.7, 0.7)); - floor.setTransform(translation(0, -3, 0)); - w.addObject(&floor); - - /* Add some more reflective spheres */ - Sphere glassBall = Sphere(); - glassBall.setTransform(scaling(1.5, 1.5, 1.5)); - glassBall.material.refractiveIndex = 1.5; - glassBall.material.transparency = 1.0; - w.addObject(&glassBall); - - Sphere airBubble = Sphere(); - airBubble.setTransform( scaling(0.9, 0.9, 0.9)); - airBubble.material.specular = 0; - airBubble.material.ambient = 0; - airBubble.material.refractiveIndex = 1.00029; - airBubble.material.transparency = 1.0; - w.addObject(&airBubble); - - /* Add light */ - Light light = Light(POINT_LIGHT, Point(-10, 20, -10), Colour(1, 1, 1)); - - w.addLight(&light); - - /* Set the camera */ - Camera camera = Camera(1000, 1000, M_PI / 3); -#if 0 - camera.setTransform(viewTransform(Point(0, 1.5, -5), - Point(0, 1, 0), - Vector(0, 1, 0))); -#else - camera.setTransform(viewTransform(Point(0, 3.6, 0), - Point(0, 0, 0), - Vector(0, 0, 1))); -#endif - /* Now render it */ - Canvas image = camera.render(w); - - image.SaveAsPNG("ch11_refractiontest.png"); - - - return 0; -} \ No newline at end of file diff --git a/tests/ch11_test.cpp b/tests/ch11_test.cpp new file mode 100644 index 0000000..955386e --- /dev/null +++ b/tests/ch11_test.cpp @@ -0,0 +1,160 @@ +/* + * DoRayMe - a quick and dirty Raytracer + * Render test for reflection in chapter 11. + * + * Created by Manoël Trapier + * Copyright (c) 2020 986-Studio. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +int main() +{ + World w = World(); + + Material wallMaterial = Material(); + wallMaterial.pattern = new StripPattern(Colour(0.45, 0.45, 0.45), Colour(0.55, 0.55, 0.55)); + wallMaterial.pattern->setTransform( scaling(0.25, 0.25, 0.25) * rotationY(1.5708)); + wallMaterial.ambient = 0; + wallMaterial.diffuse = 0.4; + wallMaterial.specular = 0; + wallMaterial.reflective = 0.3; + + /* ----------------------------- */ + + /* The flood */ + Plane floor = Plane(); + floor.setTransform(rotationY(0.31415)); + floor.material.pattern = new CheckersPattern(Colour(0.35, 0.35, 0.35), Colour(0.65, 0.65, 0.65)); + floor.material.specular = 0; + floor.material.reflective = 0.4; + w.addObject(&floor); + + /* the ceiling */ + Plane ceiling = Plane(); + ceiling.setTransform(translation(0, 5, 0)); + ceiling.material.colour = Colour(0.8, 0.8, 0.8); + ceiling.material.ambient = 0.3; + ceiling.material.specular = 0; + w.addObject(&ceiling); + + /* West wall */ + Plane westWall = Plane(); + westWall.setTransform( translation(-5, 0, 0) * rotationZ(1.5708) * rotationY(1.5708)); + westWall.setMaterial(wallMaterial); + w.addObject(&westWall); + + /* east wall */ + Plane eastWall = Plane(); + eastWall.setTransform( translation(5, 0, 0) * rotationZ(1.5708) * rotationY(1.5708)); + eastWall.setMaterial(wallMaterial); + w.addObject(&eastWall); + + /* north wall */ + Plane northWall = Plane(); + northWall.setTransform( translation(0, 0, 5) * rotationX(1.5708)); + northWall.setMaterial(wallMaterial); + w.addObject(&northWall); + + /* south wall */ + Plane southWall = Plane(); + southWall.setTransform( translation(0, 0, -5) * rotationX(1.5708)); + southWall.setMaterial(wallMaterial); + w.addObject(&southWall); + + /* ----------------------------- */ + + /* Background balls */ + Sphere bg1 = Sphere(); + bg1.setTransform(translation(4.6, 0.4, 1) * scaling(0.4, 0.4, 0.4)); + bg1.material.colour = Colour(0.8, 0.5, 0.3); + bg1.material.shininess = 50; + w.addObject(&bg1); + + Sphere bg2 = Sphere(); + bg2.setTransform(translation(4.7, 0.3, 0.4) * scaling(0.3, 0.3, 0.3)); + bg2.material.colour = Colour(0.9, 0.4, 0.5); + bg2.material.shininess = 50; + w.addObject(&bg2); + + Sphere bg3 = Sphere(); + bg3.setTransform(translation(-1, 0.5, 4.5) * scaling(0.5, 0.5, 0.5)); + bg3.material.colour = Colour(0.4, 0.9, 0.6); + bg3.material.shininess = 50; + w.addObject(&bg3); + + Sphere bg4 = Sphere(); + bg4.setTransform(translation(-1.7, 0.3, 4.7) * scaling(0.3, 0.3, 0.3)); + bg4.material.colour = Colour(0.4, 0.6, 0.9); + bg4.material.shininess = 50; + w.addObject(&bg4); + + /* Forground balls */ + + /* Red sphere */ + Sphere redBall = Sphere(); + redBall.setTransform(translation(-0.6, 1, 0.6)); + redBall.material.colour = Colour(1, 0.3, 0.2); + redBall.material.shininess = 5; + redBall.material.specular = 0.4; + w.addObject(&redBall); + + /* blue glass ball */ + Sphere blueGlassBall = Sphere(); + blueGlassBall.setTransform(translation(0.6, 0.7, -0.6) * scaling(0.7, 0.7, 0.7)); + blueGlassBall.material.colour = Colour(0, 0, 0.2); + blueGlassBall.material.ambient = 0; + blueGlassBall.material.diffuse = 0.4; + blueGlassBall.material.specular = 0.9; + blueGlassBall.material.shininess = 300; + blueGlassBall.material.transparency = 0.9; + blueGlassBall.material.refractiveIndex = 1.5; + w.addObject(&blueGlassBall); + + /* green glass ball */ + Sphere greenGlassBall = Sphere(); + greenGlassBall.setTransform(translation(-0.7, 0.5, -0.8) * scaling(0.5, 0.5, 0.5)); + greenGlassBall.material.colour = Colour(0, 0.2, 0); + greenGlassBall.material.ambient = 0; + greenGlassBall.material.diffuse = 0.4; + greenGlassBall.material.specular = 0.9; + greenGlassBall.material.shininess = 300; + greenGlassBall.material.transparency = 0.9; + greenGlassBall.material.refractiveIndex = 1.5; + w.addObject(&greenGlassBall); + + /* ----------------------------- */ + + /* Add light */ + Light light = Light(POINT_LIGHT, Point(-4.9, 4.9, -1), Colour(1, 1, 1)); + w.addLight(&light); + + /* Set the camera */ + Camera camera = Camera(800, 400, 1.152); + camera.setTransform(viewTransform(Point(-2.6, 1.5, -3.9), + Point(-0.6, 1, -0.8), + Vector(0, 1, 0))); + + /* Now render it */ + Canvas image = camera.render(w); + + image.SaveAsPNG("ch11_test.png"); + + + return 0; +} \ No newline at end of file