Getting Started - Naetw/A-simple-ray-tracer GitHub Wiki
TODO
Here is an image generated by the ray tracer:
There're 4 spheres in this image:
- A glass sphere at left
- A lambertian sphere at center
- A metal sphere at right
- A big lambertian sphere at bottom
Let's see how to construct this image in code!
-
Determine the image size and its aspect ratio
const auto aspect_ratio = 16.0 / 9.0; const int32_t image_width = 400; const auto image_height = static_cast<int32_t>(image_width / aspect_ratio);
-
Construct the WORLD! (a list of objects in the image)
HittableList world; auto ground_material = std::make_shared<Lambertian>(Albedo(0.8, 0.8, 0.0)); auto center_material = std::make_shared<Lambertian>(Albedo(0.1, 0.2, 0.5)); auto left_material = std::make_shared<Dielectric>(1.5); auto right_material = std::make_shared<Metal>(Albedo(0.8, 0.6, 0.2), /* fuzziness */ 0.0); world.add(std::make_shared<Sphere>(center_material, Point3(0, 0, -1), 0.5)); world.add(std::make_shared<Sphere>(ground_material, Point3(0, -100.5, -1), 100)); world.add(std::make_shared<Sphere>(left_material, Point3(-1, 0, -1), 0.5)); world.add(std::make_shared<Sphere>(right_material, Point3(1, 0, -1), 0.5));
- Each object has two basic attributes - material and shape. Different materials have different behaviors when a ray hits. Currently, there's only one shape - sphere.
- After constructing materials we need, we add objects in the world, with each object being designated a material.
- [TODO] More details can be found at here.
-
Construct a virtual camera which helps us capture (create) the image
Camera camera(/* origin */ Ponit3(0, 0, 0), /* look at */ Point3(0, 0, -1), /* view up */ Vector3(0, 1, 0), aspect_ratio, /* angle_of_vertical_fov */ 90, /* aperture */ 0, /* focus_distance */ 1, /* samples_per_pixel */ 400, /* max_depth */ 50);
- [TODO] More details can be found at here.
-
Render the image!
camera.renderImageToOstream(image_width, image_height, world, std::cout);
- Then, the image will be outputted to standard output in the PPM image format.
Here is the complete code listing for our "Hello World" application.
#include "Camera.h"
#include "Color.h"
#include "Dielectric.h"
#include "HittableList.h"
#include "Lambertian.h"
#include "Metal.h"
#include "Point3.h"
#include "Ray.h"
#include "Sphere.h"
#include "Vector3.h"
#include <cstdint>
#include <iostream>
int main() {
// Image
const auto aspect_ratio = 16.0 / 9.0;
const int32_t image_width = 400;
const auto image_height = static_cast<int32_t>(image_width / aspect_ratio);
// World
HittableList world;
auto ground_material = std::make_shared<Lambertian>(Albedo(0.8, 0.8, 0.0));
auto center_material = std::make_shared<Lambertian>(Albedo(0.1, 0.2, 0.5));
auto left_material = std::make_shared<Dielectric>(1.5);
auto right_material = std::make_shared<Metal>(Albedo(0.8, 0.6, 0.2), /* fuzziness */ 0.0);
world.add(std::make_shared<Sphere>(center_material, Point3(0, 0, -1), 0.5));
world.add(std::make_shared<Sphere>(ground_material, Point3(0, -100.5, -1), 100));
world.add(std::make_shared<Sphere>(left_material, Point3(-1, 0, -1), 0.5));
world.add(std::make_shared<Sphere>(right_material, Point3(1, 0, -1), 0.5));
// Camera
Camera camera(/* origin */ Ponit3(0, 0, 0),
/* look at */ Point3(0, 0, -1),
/* view up */ Vector3(0, 1, 0),
aspect_ratio,
/* angle_of_vertical_fov */ 90,
/* aperture */ 0,
/* focus_distance */ 1,
/* samples_per_pixel */ 200,
/* max_depth */ 50);
// Render
camera.renderImageToOstream(image_width, image_height, world, std::cout);
}