add camera + multisampling

This commit is contained in:
K Tyl 2020-06-06 21:11:09 +01:00
parent bcbc0719b3
commit 4d2012a6a2
4 changed files with 83 additions and 14 deletions

31
src/camera.h Normal file
View File

@ -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_;
};

View File

@ -1,13 +1,23 @@
#pragma once
#include "vec3.h"
#include "rtweekend.h"
#include <iostream>
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<int>(255.999 * pixel_colour.x()) << ' '
<< static_cast<int>(255.999 * pixel_colour.y()) << ' '
<< static_cast<int>(255.999 * pixel_colour.z()) << '\n';
out << static_cast<int>(256 * clamp(r, 0.0, 0.999)) << ' '
<< static_cast<int>(256 * clamp(g, 0.0, 0.999)) << ' '
<< static_cast<int>(256 * clamp(b, 0.0, 0.999)) << '\n';
}

View File

@ -3,12 +3,14 @@
#include "hittable_list.h"
#include "sphere.h"
#include "colour.h"
#include "camera.h"
#include <iostream>
const double ASPECT_RATIO = 16.0 / 9.0;
const int WIDTH = 384;
const int HEIGHT = static_cast<int>(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<sphere>(point3(0,0,-1), 0.5));
world.add(make_shared<sphere>(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);
}
}

View File

@ -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"