Getting Started - Naetw/A-simple-ray-tracer GitHub Wiki

Getting started

Using this project as a C++ library

TODO

"Hello World" Application

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!

  1. 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);
  2. 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.
  3. 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.
  4. Render the image!

    camera.renderImageToOstream(image_width, image_height, world, std::cout);

Full Code Listing

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);
}
⚠️ **GitHub.com Fallback** ⚠️