ch11_reflection.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. /*
  2. * DoRayMe - a quick and dirty Raytracer
  3. * Render test for reflection in chapter 11.
  4. *
  5. * Created by Manoël Trapier
  6. * Copyright (c) 2020 986-Studio.
  7. *
  8. */
  9. #include <world.h>
  10. #include <light.h>
  11. #include <sphere.h>
  12. #include <plane.h>
  13. #include <material.h>
  14. #include <colour.h>
  15. #include <canvas.h>
  16. #include <camera.h>
  17. #include <pattern.h>
  18. #include <strippattern.h>
  19. #include <gradientpattern.h>
  20. #include <checkerspattern.h>
  21. #include <ringpattern.h>
  22. #include <transformation.h>
  23. int main()
  24. {
  25. /* First we need to construct the world */
  26. Plane floor = Plane();
  27. floor.material.specular = 0;
  28. floor.material.pattern = new RingPattern(Colour(1, 0.9, 0.9), Colour(1, 0.2, 0.2));
  29. floor.material.reflective = 0.1;
  30. Plane wall = Plane();
  31. wall.material.specular = 0;
  32. wall.material.pattern = new StripPattern(Colour(1, 0.9, 0.9), Colour(1, 0.2, 0.2));
  33. wall.material.pattern->setTransform(translation(0, 0, 1) * rotationY(M_PI/4));
  34. wall.setTransform(translation(0, 0, 5) * rotationX(M_PI/2));
  35. Sphere middle = Sphere();
  36. middle.setTransform(translation(-0.7, 1, 0.6));
  37. middle.material.diffuse = 0.7;
  38. middle.material.specular = 0.3;
  39. middle.material.pattern = new StripPattern(Colour(0.1, 1, 0.5), Colour(0, 0.2, 0.2));
  40. middle.material.pattern->setTransform((rotationZ(M_PI/4) * rotationY(M_PI/5) * scaling(0.2, 0.2, 0.2)));
  41. Sphere right = Sphere();
  42. right.setTransform(translation(1.5, 0.5, -0.5) * scaling(0.5, 0.5, 0.5));
  43. right.material.diffuse = 0.7;
  44. right.material.specular = 0.3;
  45. right.material.pattern = new StripPattern(Colour(0.5, 1, 0.1), Colour(0, 0, 0));
  46. right.material.pattern->setTransform((scaling(0.1, 0.1, 0.1)));
  47. right.material.reflective = 0.1;
  48. Sphere left = Sphere();
  49. left.setTransform(translation(-1.5, 0.33, -0.75) * scaling(0.33, 0.33, 0.33));
  50. left.material.diffuse = 0.7;
  51. left.material.specular = 0.3;
  52. left.material.pattern = new GradientPattern(Colour(1, 0.8, 0.1), Colour(0.1, 0.1, 1));
  53. left.material.pattern->setTransform(translation(1.5, 0, 0) * scaling(2.1, 2, 2) * rotationY(-M_PI/4));
  54. Sphere fourth = Sphere();
  55. fourth.setTransform(translation(.5, 0.25, 0.4) * scaling(0.3, 0.3, 0.3));
  56. fourth.material.diffuse = 0.7;
  57. fourth.material.specular = 0.3;
  58. fourth.material.pattern = new CheckersPattern(Colour(0.1, 0.8, 0.1), Colour(0.8, 1, 0.8));
  59. fourth.material.pattern->setTransform( scaling(0.2, 0.2, 0.2));
  60. fourth.material.reflective = 0.4;
  61. World w = World();
  62. w.addObject(&floor);
  63. w.addObject(&wall);
  64. w.addObject(&middle);
  65. w.addObject(&left);
  66. w.addObject(&right);
  67. w.addObject(&fourth);
  68. /* Add some more reflective spheres */
  69. Sphere ref1 = Sphere();
  70. ref1.setTransform(translation(1, 1, .4) * scaling(0.2, 0.2, 0.2));
  71. ref1.material.reflective = 1;
  72. ref1.material.colour = Colour(0.3, 0.7, 0.6);
  73. w.addObject(&ref1);
  74. Sphere ref2 = Sphere();
  75. ref2.setTransform(translation(1.5, 2, -.8) * scaling(0.2, 0.2, 0.2));
  76. ref2.material.reflective = 1;
  77. ref2.material.specular = 0.5;
  78. ref2.material.colour = Colour(0.3, 0.3, 0.3);
  79. w.addObject(&ref2);
  80. Sphere ref3 = Sphere();
  81. ref3.setTransform(translation(-2, 1.678, .4) * scaling(0.4, 0.4, 0.4));
  82. ref3.material.reflective = 1;
  83. ref3.material.specular = 0.5;
  84. w.addObject(&ref3);
  85. /* Add light */
  86. //Light light = Light(POINT_LIGHT, Point(-10, 10, -10), Colour(1, 1, 1));
  87. Light light = Light(AREA_LIGHT, Point(-9, 10, -9),
  88. Vector(2, 0, 0), 5,
  89. Vector(0, 2, 0), 5,
  90. Colour(1, 1, 1));
  91. w.addLight(&light);
  92. #define WIDTH (100)
  93. #define HEIGHT (50)
  94. /* Set the camera */
  95. Camera camera = Camera(WIDTH, HEIGHT, M_PI / 3);
  96. camera.setTransform(viewTransform(Point(0, 1.5, -5),
  97. Point(0, 1, 0),
  98. Vector(0, 1, 0)));
  99. /* Now render it */
  100. printf("Render full scene...\n");
  101. Canvas image = camera.render(w);
  102. image.SaveAsPNG("ch11_reflection.png");
  103. /* Let's try to zoom on the small reflective ball in the back */
  104. Camera camera2 = Camera(HEIGHT, HEIGHT, M_PI / 40);
  105. camera2.setTransform(viewTransform(Point(0, 1.5, -5),
  106. Point(1, 1, .4),
  107. Vector(0, 1, 0)));
  108. printf("Render reflective ball...\n");
  109. Canvas image2 = camera2.render(w);
  110. image2.SaveAsPNG("ch11_zooming_on_reflective_ball.png");
  111. /* Zooming on a reflexion on a reflective ball */
  112. Camera camera3 = Camera(HEIGHT, HEIGHT, M_PI / 600);
  113. camera3.setTransform(viewTransform(Point(0, 1.5, -5),
  114. Point(1.05, 1.063, .4),
  115. Vector(0, 1, 0)));
  116. printf("Render reflection on ball...\n");
  117. Canvas image3 = camera3.render(w);
  118. image3.SaveAsPNG("ch11_reflection_on_ball.png");
  119. return 0;
  120. }