Skip to content

my C++ implementation of the ray tracer from Ray Tracing in One Weekend

Notifications You must be signed in to change notification settings

neuroevolutus/RayTracingInOneWeekend

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ray Tracing in One Weekend

This repository contains my implementation of the ray tracer described in the wonderful Ray Tracing in One Weekend book as a standalone library. The code here uses C++23 and utilises as much of C++20 modules and other modern C++ features as possible.

Tested Platforms / Required Tools

The code has been tested using Apple macOS Sonoma 14.4.1, Clang 17.0.6, Ninja 1.11.1 and GNU Bash 5.2.26.

Utilising the Library

To integrate the code into your own executable, create a directory with a main.cxx that imports the appropriate modules from the RTIOW pseudo-namespace:

main.cxx
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <memory>

import RTIOW.Camera;
import RTIOW.Color;
import RTIOW.HittableObjectList;
import RTIOW.Material;
import RTIOW.Utility;
import RTIOW.Sphere;
import RTIOW.Vec3;

int main()
{
  // World
  HittableObjectList world{};

  auto const ground_material{ std::make_shared<Lambertian>(Color(0.5, 0.5, 0.5)
  ) };
  world.add(std::make_shared<Sphere>(Point3(0, -1000, 0), 1000, ground_material)
  );

  for (int a{ -11 }; a < 11; ++a) {
    for (int b{ -11 }; b < 11; ++b) {
      auto const   choose_material{ random_double() };
      Point3 const center(
        a + 0.9 * random_double(),
        0.2,
        b + 0.9 * random_double()
      );

      if ((center - Point3(4, 0.2, 0)).length() > 0.9) {
        if (choose_material < 0.8) {
          // Diffuse
          auto const albedo{ Color::random() * Color::random() };
          auto const material{ std::make_shared<Lambertian>(albedo) };
          world.add(std::make_shared<Sphere>(center, 0.2, material));
        } else if (choose_material < 0.95) {
          // Metal
          auto const albedo{ Color::random(0.5, 1) };
          auto const fuzz{ random_double(0, 0.5) };
          auto const material{ std::make_shared<Metal>(albedo, fuzz) };
          world.add(std::make_shared<Sphere>(center, 0.2, material));
        } else {
          // Glass
          auto const material{ std::make_shared<Dielectric>(1.5) };
          world.add(std::make_shared<Sphere>(center, 0.2, material));
        }
      }
    }
  }

  auto const material_1{ std::make_shared<Dielectric>(1.5) };
  world.add(std::make_shared<Sphere>(Point3(0, 1, 0), 1.0, material_1));

  auto const material_2{ std::make_shared<Lambertian>(Color(0.4, 0.2, 0.1)) };
  world.add(std::make_shared<Sphere>(Point3(-4, 1, 0), 1.0, material_2));

  auto const material_3{ std::make_shared<Metal>(Color(0.7, 0.6, 0.5), 0.0) };
  world.add(std::make_shared<Sphere>(Point3(4, 1, 0), 1.0, material_3));

  Camera camera{};

  camera.aspect_ratio      = 16.0 / 9.0;
  camera.image_width       = 1200;
  camera.samples_per_pixel = 500;
  camera.max_depth         = 50;

  camera.vertical_field_of_view_in_degrees = 20;
  camera.look_from                         = Point3(13, 2, 3);
  camera.look_at                           = Point3(0, 0, 0);
  camera.v_up                              = Vec3(0, 1, 0);

  camera.defocus_angle_in_degrees = 0.6;
  camera.focus_distance           = 10;

  camera.render(world);

  return EXIT_SUCCESS;
}

and create a CMakeLists.tx file using FetchContent:

CMakeLists.txt
cmake_minimum_required(VERSION 3.29)

include(FetchContent)

FetchContent_Declare(
  RTIOW
  GIT_REPOSITORY https://github.com/neuroevolutus/RayTracingInOneWeekend.git
  GIT_TAG main
)

FetchContent_MakeAvailable(RTIOW)

project(test CXX)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

add_executable(main main.cxx)
target_link_libraries(main RTIOW::raytracer)

Building Your Project

Initialise your CMake build with cmake -B release -G Ninja -D CMAKE_BUILD_TYPE=Release -D CMAKE_CXX_COMPILER=$(which clang+)`. Then, build the project with `+cmake --build release.

Generating the PPM Image File

In your CMake project, simply run release/main > image.ppm. You should get an image file that looks like the one below:

A Ray-Traced Scene

About

my C++ implementation of the ray tracer from Ray Tracing in One Weekend

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published