From 4d2012a6a2ae2484742bc60fdb4dd026b0ea713b Mon Sep 17 00:00:00 2001 From: K Tyl Date: Sat, 6 Jun 2020 21:11:09 +0100 Subject: [PATCH] add camera + multisampling --- src/camera.h | 31 +++++++++++++++++++++++++++++++ src/colour.h | 20 +++++++++++++++----- src/main.cpp | 27 ++++++++++++++++++--------- src/rtweekend.h | 19 +++++++++++++++++++ 4 files changed, 83 insertions(+), 14 deletions(-) create mode 100644 src/camera.h diff --git a/src/camera.h b/src/camera.h new file mode 100644 index 0000000..18b3e4d --- /dev/null +++ b/src/camera.h @@ -0,0 +1,31 @@ +#pragma once + +#include "rtweekend.h" + +class camera +{ + public: + const double ASPECT_RATIO = 16.0 / 9.0; + const double VIEWPORT_HEIGHT = 2.0; + const double VIEWPORT_WIDTH = ASPECT_RATIO * VIEWPORT_HEIGHT; + const double FOCAL_LENGTH = 1.0; + + camera() : + origin_(point3(0,0,0)), + horizontal_(vec3(VIEWPORT_WIDTH,0.0,0.0)), + vertical_(vec3(0.0, VIEWPORT_HEIGHT, 0.0)) + { + lower_left_corner_ = origin_ - horizontal_/2 - vertical_/2 - vec3(0,0,FOCAL_LENGTH); + } + + ray get_ray(double u, double v) const + { + return ray(origin_, lower_left_corner_ + u*horizontal_ + v*vertical_ - origin_); + } + + private: + point3 origin_; + point3 lower_left_corner_; + vec3 horizontal_; + vec3 vertical_; +}; diff --git a/src/colour.h b/src/colour.h index 2d42906..95d02d5 100755 --- a/src/colour.h +++ b/src/colour.h @@ -1,13 +1,23 @@ #pragma once -#include "vec3.h" +#include "rtweekend.h" #include -void write_colour(std::ostream &out, colour pixel_colour) +void write_colour(std::ostream &out, colour pixel_colour, int samples_per_pixel) { + auto r = pixel_colour.x(); + auto g = pixel_colour.y(); + auto b = pixel_colour.z(); + + // divide the colour total by the number of samples + auto scale = 1.0 / samples_per_pixel; + r *= scale; + g *= scale; + b *= scale; + // write the translated [0,255] value of each colour component. - out << static_cast(255.999 * pixel_colour.x()) << ' ' - << static_cast(255.999 * pixel_colour.y()) << ' ' - << static_cast(255.999 * pixel_colour.z()) << '\n'; + out << static_cast(256 * clamp(r, 0.0, 0.999)) << ' ' + << static_cast(256 * clamp(g, 0.0, 0.999)) << ' ' + << static_cast(256 * clamp(b, 0.0, 0.999)) << '\n'; } diff --git a/src/main.cpp b/src/main.cpp index 5a5220e..e34542a 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,12 +3,14 @@ #include "hittable_list.h" #include "sphere.h" #include "colour.h" +#include "camera.h" #include const double ASPECT_RATIO = 16.0 / 9.0; const int WIDTH = 384; const int HEIGHT = static_cast(WIDTH / ASPECT_RATIO); +const int SAMPLES_PER_PIXEL = 100; colour ray_colour(const ray& r, const hittable& world) { @@ -44,17 +46,24 @@ int main() world.add(make_shared(point3(0,0,-1), 0.5)); world.add(make_shared(point3(0,-100.5,-1), 100)); - for (int y = HEIGHT - 1; y >= 0; --y) + camera cam; + + for (int j = HEIGHT - 1; j >= 0; --j) { - std::cerr << "\rScanlines remaining: " << y << ' ' << std::flush; - for (int x = 0; x < WIDTH; ++x) + std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush; + for (int i = 0; i < WIDTH; ++i) { - auto u = double(x) / (WIDTH-1); - auto v = double(y) / (HEIGHT-1); - ray r(origin, lower_left_corner + u*horizontal + v*vertical - origin); - - colour pixel_colour = ray_colour(r, world); - write_colour(std::cout, pixel_colour); + colour pixel_colour(0,0,0); + + for (int s = 0; s < SAMPLES_PER_PIXEL; ++s) + { + auto u = (i + random_double()) / (WIDTH-1); + auto v = (j + random_double()) / (HEIGHT-1); + ray r = cam.get_ray(u, v); + pixel_colour += ray_colour(r, world); + } + + write_colour(std::cout, pixel_colour, SAMPLES_PER_PIXEL); } } diff --git a/src/rtweekend.h b/src/rtweekend.h index 2ec65b8..882b353 100644 --- a/src/rtweekend.h +++ b/src/rtweekend.h @@ -23,6 +23,25 @@ inline double degrees_to_radians(double degrees) return degrees * pi / 180; } +inline double random_double() +{ + // returns a random real in [0,1) + return rand() / (RAND_MAX + 1.0); +} + +inline double random_double(double min, double max) +{ + // returns a random real in [min,max) + return min + (max-min)*random_double(); +} + +inline double clamp(double x, double min, double max) +{ + if (x < min) return min; + if (x > max) return max; + return x; +} + // common headers #include "ray.h"