├── Renderings └── Latest.png ├── .gitattributes ├── OneWeekend ├── RaytracingLib │ ├── vcpkg.json │ ├── RaytracingLib.vcxproj.user │ ├── RaytracingLib.ixx │ ├── vcpkg-configuration.json │ ├── ray.ixx │ ├── color.ixx │ ├── sphere.ixx │ ├── camera.ixx │ ├── RaytracingLib.vcxproj.filters │ ├── hittable.ixx │ ├── scene.ixx │ ├── material.ixx │ ├── algebra.ixx │ ├── images.ixx │ └── RaytracingLib.vcxproj ├── Raytracing │ ├── Raytracing.vcxproj.user │ ├── Raytracing.vcxproj.filters │ ├── main.cpp │ └── Raytracing.vcxproj ├── Readme.md ├── CMakeLists.txt └── Raytracing.sln ├── .gitignore ├── README.md └── LICENSE /Renderings/Latest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pjmlp/RaytracingWeekend-CPP/HEAD/Renderings/Latest.png -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | # Trying to make C++ modules visible to Github, as per https://github.com/github/linguist/blob/master/docs/overrides.md 2 | *.ixx linguist-language=C++ 3 | -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/vcpkg.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", 3 | "dependencies": [ 4 | "stb" 5 | ] 6 | } -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/RaytracingLib.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /OneWeekend/Raytracing/Raytracing.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | false 5 | 6 | -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/RaytracingLib.ixx: -------------------------------------------------------------------------------- 1 | export module RaytracingLib; 2 | 3 | export import :algebra; 4 | export import :camera; 5 | export import :color; 6 | export import :hittable; 7 | export import :ray; 8 | export import :sphere; 9 | export import :images; 10 | export import :material; 11 | export import :scene; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | 34 | # Visual Studio directories 35 | .vs 36 | x64 37 | vcpkg_installed -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/vcpkg-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "default-registry": { 3 | "kind": "git", 4 | "baseline": "2c401863dd54a640aeb26ed736c55489c079323b", 5 | "repository": "https://github.com/microsoft/vcpkg" 6 | }, 7 | "registries": [ 8 | { 9 | "kind": "artifact", 10 | "location": "https://github.com/microsoft/vcpkg-ce-catalog/archive/refs/heads/main.zip", 11 | "name": "microsoft" 12 | } 13 | ] 14 | } 15 | -------------------------------------------------------------------------------- /OneWeekend/Readme.md: -------------------------------------------------------------------------------- 1 | # Intro 2 | 3 | This folder contains the version of the first weekend of the Raytracing in one weekend series. 4 | 5 | # Building 6 | 7 | Currently it depends on the stb_image as suggested by the tutorials. 8 | 9 | ## Windows 10 | 11 | It makes use of Visual Studio 2022, and third party dependecies are expected to have been installed via vcpkg. 12 | 13 | ## POSIX OSes 14 | 15 | Initial support has been added for clang 17, alongside cmake 3.26 and ninja 1.11.1. 16 | 17 | Note that there are still some issues, see the CMakeLists.txt file for more information. 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Overview 2 | 3 | Peter Shirley's raytracing tutorials updated to C++ modules, while taking advantage of more recent language features. 4 | 5 | The current state being generated is, 6 | 7 | ![Current state](Renderings/Latest.png) 8 | 9 | 10 | # Security 11 | 12 | I have tried to write the code using C++ best practices for secure code, as means to prove it is possible to have fast code while going safe. 13 | 14 | Naturally, there might be hidden dragons still lying around the code. 15 | 16 | # License 17 | 18 | Given that the code is based on Peter Shirley's work, I have adopted the same license. 19 | 20 | -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/ray.ixx: -------------------------------------------------------------------------------- 1 | export module RaytracingLib:ray; 2 | 3 | import std; 4 | 5 | import :algebra; 6 | 7 | // public view of the module 8 | export namespace RaytracingLib { 9 | 10 | class ray final { 11 | public: 12 | ray() = default; 13 | 14 | ray(const point3& origin, const vec3& direction) 15 | : orig(origin), dir(direction) 16 | {} 17 | 18 | point3 origin() const { return orig; } 19 | vec3 direction() const { return dir; } 20 | 21 | point3 at(double t) const { 22 | return orig + t * dir; 23 | } 24 | 25 | public: 26 | point3 orig; 27 | vec3 dir; 28 | }; 29 | } -------------------------------------------------------------------------------- /OneWeekend/Raytracing/Raytracing.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/color.ixx: -------------------------------------------------------------------------------- 1 | export module RaytracingLib:color; 2 | 3 | import std; 4 | 5 | import :algebra; 6 | 7 | // public view of the module 8 | export namespace RaytracingLib { 9 | 10 | void write_color(std::ostream& out, color pixel_color) { 11 | // Write the translated [0,255] value of each color component. 12 | out << static_cast(255.999 * pixel_color.x()) << ' ' 13 | << static_cast(255.999 * pixel_color.y()) << ' ' 14 | << static_cast(255.999 * pixel_color.z()) << '\n'; 15 | } 16 | 17 | void write_color(std::ostream& out, color pixel_color, int samples_per_pixel) { 18 | auto r = pixel_color.x(); 19 | auto g = pixel_color.y(); 20 | auto b = pixel_color.z(); 21 | 22 | // Divide the color by the number of samples. 23 | auto scale = 1.0 / samples_per_pixel; 24 | r *= scale; 25 | g *= scale; 26 | b *= scale; 27 | 28 | // Write the translated [0,255] value of each color component. 29 | out << static_cast(256 * clamp(r, 0.0, 0.999)) << ' ' 30 | << static_cast(256 * clamp(g, 0.0, 0.999)) << ' ' 31 | << static_cast(256 * clamp(b, 0.0, 0.999)) << '\n'; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/sphere.ixx: -------------------------------------------------------------------------------- 1 | export module RaytracingLib:sphere; 2 | 3 | import std; 4 | 5 | import :algebra; 6 | import :hittable; 7 | import :ray; 8 | 9 | // public view of the module 10 | export namespace RaytracingLib { 11 | 12 | class sphere final : public hittable { 13 | public: 14 | sphere() = default; 15 | ~sphere() = default; 16 | sphere(point3 cen, double r, shared_ptr m) : center(cen), radius(r), mat_ptr(m) {}; 17 | 18 | virtual bool hit( 19 | const ray& r, double t_min, double t_max, hit_record& rec) const override; 20 | 21 | public: 22 | point3 center; 23 | double radius; 24 | shared_ptr mat_ptr; 25 | }; 26 | 27 | bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 28 | vec3 oc = r.origin() - center; 29 | auto a = r.direction().length_squared(); 30 | auto half_b = dot(oc, r.direction()); 31 | auto c = oc.length_squared() - radius * radius; 32 | 33 | auto discriminant = half_b * half_b - a * c; 34 | if (discriminant < 0) return false; 35 | auto sqrtd = std::sqrt(discriminant); 36 | 37 | // Find the nearest root that lies in the acceptable range. 38 | auto root = (-half_b - sqrtd) / a; 39 | if (root < t_min || t_max < root) { 40 | root = (-half_b + sqrtd) / a; 41 | if (root < t_min || t_max < root) 42 | return false; 43 | } 44 | 45 | rec.t = root; 46 | rec.p = r.at(rec.t); 47 | vec3 outward_normal = (rec.p - center) / radius; 48 | rec.set_face_normal(r, outward_normal); 49 | rec.mat_ptr = mat_ptr; 50 | 51 | return true; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /OneWeekend/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # See https://www.kitware.com/import-cmake-c20-modules/ for how it was done 2 | 3 | # Note there are some issues with header units in cmake. 4 | # https://gitlab.kitware.com/cmake/cmake/-/issues/24616 5 | 6 | # There is also anothe issue with clang's module support 7 | # https://github.com/llvm/llvm-project/issues/62707 8 | # https://github.com/Kitware/CMake/commit/7b05724ac81c3262ce8aded5578326ecec327ae4 9 | 10 | cmake_minimum_required(VERSION 3.26) 11 | project(std_module_example CXX) 12 | 13 | set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "2182bf5c-ef0d-489a-91da-49dbc3090d2a") 14 | 15 | # Default to C++ extensions being off. Clang's modules support have trouble 16 | # with extensions right now and it is not required for any other compiler 17 | set(CMAKE_CXX_EXTENSIONS OFF) 18 | 19 | if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") 20 | include(gcc_modules.cmake) 21 | elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") 22 | # Ensure some code quality is taken care of. 23 | add_compile_options(-Wall -Wextra -Wpedantic) 24 | endif() 25 | 26 | 27 | # Uncoment for debug builds 28 | #set(CMAKE_BUILD_TYPE Debug) 29 | 30 | set(CMAKE_CXX_STANDARD 20) 31 | set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1) 32 | 33 | add_library(RayTracingLib) 34 | target_sources(RayTracingLib 35 | PUBLIC 36 | FILE_SET cxx_modules TYPE CXX_MODULES FILES 37 | RaytracingLib/algebra.ixx 38 | RaytracingLib/camera.ixx 39 | RaytracingLib/color.ixx 40 | RaytracingLib/hittable.ixx 41 | RaytracingLib/images.ixx 42 | RaytracingLib/material.ixx 43 | RaytracingLib/ray.ixx 44 | RaytracingLib/RaytracingLib.ixx 45 | RaytracingLib/scene.ixx 46 | RaytracingLib/sphere.ixx 47 | ) 48 | 49 | add_executable(RayTracing Raytracing/main.cpp) 50 | target_link_libraries(RayTracing PRIVATE RayTracingLib) 51 | -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/camera.ixx: -------------------------------------------------------------------------------- 1 | export module RaytracingLib:camera; 2 | 3 | import std; 4 | 5 | import :algebra; 6 | import :ray; 7 | 8 | // public view of the module 9 | export namespace RaytracingLib { 10 | 11 | class camera { 12 | public: 13 | camera( 14 | point3 lookfrom, 15 | point3 lookat, 16 | vec3 vup, 17 | double vfov, // vertical field-of-view in degrees 18 | double aspect_ratio, 19 | double aperture, 20 | double focus_dist 21 | ) { 22 | auto theta = degrees_to_radians(vfov); 23 | auto h = std::tan(theta / 2); 24 | auto viewport_height = 2.0 * h; 25 | auto viewport_width = aspect_ratio * viewport_height; 26 | 27 | w = unit_vector(lookfrom - lookat); 28 | u = unit_vector(cross(vup, w)); 29 | v = cross(w, u); 30 | 31 | origin = lookfrom; 32 | horizontal = focus_dist * viewport_width * u; 33 | vertical = focus_dist * viewport_height * v; 34 | lower_left_corner = origin - horizontal / 2 - vertical / 2 - focus_dist * w; 35 | 36 | lens_radius = aperture / 2; 37 | } 38 | 39 | ray get_ray(double s, double t) const { 40 | vec3 rd = lens_radius * random_in_unit_disk(); 41 | vec3 offset = u * rd.x() + v * rd.y(); 42 | 43 | return ray( 44 | origin + offset, 45 | lower_left_corner + s * horizontal + t * vertical - origin - offset 46 | ); 47 | } 48 | 49 | private: 50 | point3 origin; 51 | point3 lower_left_corner; 52 | vec3 horizontal; 53 | vec3 vertical; 54 | vec3 u, v, w; 55 | double lens_radius; 56 | }; 57 | } 58 | -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/RaytracingLib.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/hittable.ixx: -------------------------------------------------------------------------------- 1 | export module RaytracingLib:hittable; 2 | 3 | import std; 4 | 5 | import :algebra; 6 | import :ray; 7 | 8 | // public view of the module 9 | export namespace RaytracingLib { 10 | // avoid some typing 11 | using std::shared_ptr; 12 | using std::make_shared; 13 | 14 | // forward declarations 15 | class material; 16 | 17 | struct hit_record { 18 | point3 p; 19 | vec3 normal; 20 | shared_ptr mat_ptr; 21 | double t = {}; 22 | bool front_face = {}; 23 | 24 | inline void set_face_normal(const ray& r, const vec3& outward_normal) { 25 | front_face = dot(r.direction(), outward_normal) < 0; 26 | normal = front_face ? outward_normal : -outward_normal; 27 | } 28 | }; 29 | 30 | class hittable { 31 | public: 32 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const = 0; 33 | }; 34 | 35 | class hittable_list : public hittable { 36 | public: 37 | hittable_list() {} 38 | hittable_list(shared_ptr object) { add(object); } 39 | 40 | void clear() { objects.clear(); } 41 | void add(shared_ptr object) { objects.push_back(std::move(object)); } 42 | 43 | virtual bool hit( 44 | const ray& r, double t_min, double t_max, hit_record& rec) const override; 45 | 46 | public: 47 | std::vector> objects; 48 | }; 49 | 50 | bool hittable_list::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 51 | hit_record temp_rec; 52 | bool hit_anything = false; 53 | auto closest_so_far = t_max; 54 | 55 | for (const auto& object : objects) { 56 | if (object->hit(r, t_min, closest_so_far, temp_rec)) { 57 | hit_anything = true; 58 | closest_so_far = temp_rec.t; 59 | rec = temp_rec; 60 | } 61 | } 62 | 63 | return hit_anything; 64 | } 65 | 66 | class material { 67 | public: 68 | virtual ~material() = default; 69 | 70 | virtual bool scatter( 71 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 72 | ) const = 0; 73 | }; 74 | 75 | } 76 | -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/scene.ixx: -------------------------------------------------------------------------------- 1 | export module RaytracingLib:scene; 2 | 3 | import std; 4 | 5 | import :algebra; 6 | import :hittable; 7 | import :material; 8 | import :sphere; 9 | import :ray; 10 | 11 | // public view of the module 12 | export namespace RaytracingLib { 13 | 14 | hittable_list random_scene() { 15 | using namespace std; 16 | 17 | hittable_list world; 18 | 19 | auto ground_material = make_shared(color(0.5, 0.5, 0.5)); 20 | world.add(make_shared(point3(0, -1000, 0), 1000, ground_material)); 21 | 22 | for (int a = -11; a < 11; a++) { 23 | for (int b = -11; b < 11; b++) { 24 | auto choose_mat = random_double(); 25 | point3 center(a + 0.9 * random_double(), 0.2, b + 0.9 * random_double()); 26 | 27 | if ((center - point3(4, 0.2, 0)).length() > 0.9) { 28 | shared_ptr sphere_material; 29 | 30 | if (choose_mat < 0.8) { 31 | // diffuse 32 | auto albedo = color::random() * color::random(); 33 | sphere_material = make_shared(albedo); 34 | world.add(make_shared(center, 0.2, sphere_material)); 35 | } 36 | else if (choose_mat < 0.95) { 37 | // metal 38 | auto albedo = color::random(0.5, 1); 39 | auto fuzz = random_double(0, 0.5); 40 | sphere_material = make_shared(albedo, fuzz); 41 | world.add(make_shared(center, 0.2, sphere_material)); 42 | } 43 | else { 44 | // glass 45 | sphere_material = make_shared(1.5); 46 | world.add(make_shared(center, 0.2, sphere_material)); 47 | } 48 | } 49 | } 50 | } 51 | 52 | auto material1 = make_shared(1.5); 53 | world.add(make_shared(point3(0, 1, 0), 1.0, material1)); 54 | 55 | auto material2 = make_shared(color(0.4, 0.2, 0.1)); 56 | world.add(make_shared(point3(-4, 1, 0), 1.0, material2)); 57 | 58 | auto material3 = make_shared(color(0.7, 0.6, 0.5), 0.0); 59 | world.add(make_shared(point3(4, 1, 0), 1.0, material3)); 60 | 61 | return world; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /OneWeekend/Raytracing.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.0.31912.275 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RaytracingLib", "RaytracingLib\RaytracingLib.vcxproj", "{0977CA7B-DF59-49C8-A0AB-2B3A47405908}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{745E5151-6712-426B-8829-C23B5463BA55}" 9 | ProjectSection(SolutionItems) = preProject 10 | Readme.md = Readme.md 11 | EndProjectSection 12 | EndProject 13 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Raytracing", "Raytracing\Raytracing.vcxproj", "{C696869F-5D7D-4444-818A-249917DBDB46}" 14 | EndProject 15 | Global 16 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 17 | Debug|x64 = Debug|x64 18 | Debug|x86 = Debug|x86 19 | Release|x64 = Release|x64 20 | Release|x86 = Release|x86 21 | EndGlobalSection 22 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 23 | {0977CA7B-DF59-49C8-A0AB-2B3A47405908}.Debug|x64.ActiveCfg = Debug|x64 24 | {0977CA7B-DF59-49C8-A0AB-2B3A47405908}.Debug|x64.Build.0 = Debug|x64 25 | {0977CA7B-DF59-49C8-A0AB-2B3A47405908}.Debug|x86.ActiveCfg = Debug|Win32 26 | {0977CA7B-DF59-49C8-A0AB-2B3A47405908}.Debug|x86.Build.0 = Debug|Win32 27 | {0977CA7B-DF59-49C8-A0AB-2B3A47405908}.Release|x64.ActiveCfg = Release|x64 28 | {0977CA7B-DF59-49C8-A0AB-2B3A47405908}.Release|x64.Build.0 = Release|x64 29 | {0977CA7B-DF59-49C8-A0AB-2B3A47405908}.Release|x86.ActiveCfg = Release|Win32 30 | {0977CA7B-DF59-49C8-A0AB-2B3A47405908}.Release|x86.Build.0 = Release|Win32 31 | {C696869F-5D7D-4444-818A-249917DBDB46}.Debug|x64.ActiveCfg = Debug|x64 32 | {C696869F-5D7D-4444-818A-249917DBDB46}.Debug|x64.Build.0 = Debug|x64 33 | {C696869F-5D7D-4444-818A-249917DBDB46}.Debug|x86.ActiveCfg = Debug|Win32 34 | {C696869F-5D7D-4444-818A-249917DBDB46}.Debug|x86.Build.0 = Debug|Win32 35 | {C696869F-5D7D-4444-818A-249917DBDB46}.Release|x64.ActiveCfg = Release|x64 36 | {C696869F-5D7D-4444-818A-249917DBDB46}.Release|x64.Build.0 = Release|x64 37 | {C696869F-5D7D-4444-818A-249917DBDB46}.Release|x86.ActiveCfg = Release|Win32 38 | {C696869F-5D7D-4444-818A-249917DBDB46}.Release|x86.Build.0 = Release|Win32 39 | EndGlobalSection 40 | GlobalSection(SolutionProperties) = preSolution 41 | HideSolutionNode = FALSE 42 | EndGlobalSection 43 | GlobalSection(ExtensibilityGlobals) = postSolution 44 | SolutionGuid = {7CCFB5DF-75FB-4E17-98E4-A16F425CA344} 45 | EndGlobalSection 46 | EndGlobal 47 | -------------------------------------------------------------------------------- /OneWeekend/Raytracing/main.cpp: -------------------------------------------------------------------------------- 1 | import std; 2 | 3 | import RaytracingLib; 4 | 5 | using namespace RaytracingLib; 6 | 7 | color ray_color(const ray& r, const hittable& world, int depth) { 8 | hit_record rec; 9 | 10 | // If we've exceeded the ray bounce limit, no more light is gathered. 11 | if (depth <= 0) { 12 | return color(0, 0, 0); 13 | } 14 | 15 | if (world.hit(r, 0.001, infinity, rec)) { 16 | ray scattered; 17 | color attenuation; 18 | if (rec.mat_ptr->scatter(r, rec, attenuation, scattered)) 19 | return attenuation * ray_color(scattered, world, depth - 1); 20 | return color(0, 0, 0); 21 | } 22 | 23 | vec3 unit_direction = unit_vector(r.direction()); 24 | auto t = 0.5 * (unit_direction.y() + 1.0); 25 | 26 | return (1.0 - t) * color(1.0, 1.0, 1.0) + t * color(0.5, 0.7, 1.0); 27 | } 28 | 29 | int main() { 30 | 31 | // Image 32 | constexpr auto aspect_ratio = 3.0 / 2.0; 33 | constexpr int image_width = 1200; 34 | constexpr int image_height = static_cast(image_width / aspect_ratio); 35 | constexpr int samples_per_pixel = 500; 36 | constexpr int max_depth = 50; 37 | 38 | ImageBuffer buffer(image_width, image_height, PixelFormat::RGB); 39 | 40 | // World 41 | hittable_list world = random_scene(); 42 | 43 | // Camera 44 | point3 lookfrom(13, 2, 3); 45 | point3 lookat(0, 0, 0); 46 | vec3 vup(0, 1, 0); 47 | auto dist_to_focus = 10.0; 48 | auto aperture = 0.1; 49 | 50 | camera cam(lookfrom, lookat, vup, 20, aspect_ratio, aperture, dist_to_focus); 51 | 52 | // Render 53 | std::mutex output_mutex; 54 | std::atomic counter = size_t(image_height); 55 | 56 | auto data_range = std::ranges::iota_view(size_t(0), size_t(image_height)); 57 | std::for_each(std::execution::par, data_range.begin(), data_range.end(), [&](size_t index) { 58 | auto current = counter.fetch_sub(1); 59 | auto msg = std::format("\rProcessing scanline: {} from {}", current, image_height); 60 | 61 | { 62 | // basic way to serialize output on task creation 63 | std::lock_guard guard(output_mutex); 64 | std::cerr << msg << std::flush; 65 | } 66 | 67 | int j = static_cast(image_height - index - 1); 68 | for (int i = 0; i < image_width; ++i) { 69 | color pixel_color(0, 0, 0); 70 | for (int s = 0; s < samples_per_pixel; ++s) { 71 | auto u = (i + random_double()) / (image_width - 1); 72 | auto v = (j + random_double()) / (image_height - 1); 73 | ray r = cam.get_ray(u, v); 74 | pixel_color += ray_color(r, world, max_depth); 75 | } 76 | buffer.set_color(i, j, pixel_color, samples_per_pixel); 77 | } 78 | }); 79 | 80 | buffer.save("img.png"); 81 | std::cerr << "\nDone.\n"; 82 | } 83 | -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/material.ixx: -------------------------------------------------------------------------------- 1 | export module RaytracingLib:material; 2 | 3 | import std; 4 | 5 | import :algebra; 6 | import :ray; 7 | import :hittable; 8 | 9 | // public view of the module 10 | export namespace RaytracingLib { 11 | class lambertian : public material { 12 | public: 13 | lambertian(const color& a) : albedo(a) {} 14 | virtual ~lambertian() = default; 15 | 16 | virtual bool scatter( 17 | const ray&, const hit_record& rec, color& attenuation, ray& scattered 18 | ) const override { 19 | auto scatter_direction = rec.normal + random_unit_vector(); 20 | 21 | // Catch degenerate scatter direction 22 | if (scatter_direction.near_zero()) { 23 | scatter_direction = rec.normal; 24 | } 25 | 26 | scattered = ray(rec.p, scatter_direction); 27 | attenuation = albedo; 28 | return true; 29 | } 30 | 31 | public: 32 | color albedo; 33 | }; 34 | 35 | class metal : public material { 36 | public: 37 | metal(const color& a, double f) : albedo(a), fuzz(f < 1 ? f : 1) {} 38 | virtual ~metal() = default; 39 | 40 | virtual bool scatter( 41 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 42 | ) const override { 43 | vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal); 44 | scattered = ray(rec.p, reflected + fuzz * random_in_unit_sphere()); 45 | attenuation = albedo; 46 | return (dot(scattered.direction(), rec.normal) > 0); 47 | } 48 | 49 | public: 50 | color albedo; 51 | double fuzz; 52 | }; 53 | 54 | class dielectric : public material { 55 | public: 56 | dielectric(double index_of_refraction) : ir(index_of_refraction) {} 57 | 58 | virtual bool scatter( 59 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 60 | ) const override { 61 | attenuation = color(1.0, 1.0, 1.0); 62 | double refraction_ratio = rec.front_face ? (1.0 / ir) : ir; 63 | 64 | vec3 unit_direction = unit_vector(r_in.direction()); 65 | 66 | double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0); 67 | double sin_theta = std::sqrt(1.0 - cos_theta * cos_theta); 68 | 69 | bool cannot_refract = refraction_ratio * sin_theta > 1.0; 70 | vec3 direction; 71 | 72 | if (cannot_refract || reflectance(cos_theta, refraction_ratio) > random_double()) 73 | direction = reflect(unit_direction, rec.normal); 74 | else 75 | direction = refract(unit_direction, rec.normal, refraction_ratio); 76 | 77 | scattered = ray(rec.p, direction); 78 | 79 | return true; 80 | } 81 | 82 | public: 83 | double ir; // Index of Refraction 84 | 85 | private: 86 | static double reflectance(double cosine, double ref_idx) { 87 | // Use Schlick's approximation for reflectance. 88 | auto r0 = (1 - ref_idx) / (1 + ref_idx); 89 | r0 = r0 * r0; 90 | return r0 + (1 - r0) * pow((1 - cosine), 5); 91 | } 92 | }; 93 | } 94 | -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/algebra.ixx: -------------------------------------------------------------------------------- 1 | export module RaytracingLib:algebra; 2 | 3 | import std; 4 | 5 | // public view of the module 6 | export namespace RaytracingLib { 7 | 8 | // forward declarations 9 | double random_double(); 10 | double random_double(double min, double max); 11 | 12 | class vec3 final { 13 | public: 14 | vec3() : e{ 0,0,0 } {} 15 | vec3(double e0, double e1, double e2) : e{ e0, e1, e2 } {} 16 | 17 | double x() const { return e[0]; } 18 | double y() const { return e[1]; } 19 | double z() const { return e[2]; } 20 | 21 | vec3 operator-() const { return vec3(-e[0], -e[1], -e[2]); } 22 | double operator[](int i) const { return e[i]; } 23 | double& operator[](int i) { return e[i]; } 24 | 25 | vec3& operator+=(const vec3& v) { 26 | e[0] += v.e[0]; 27 | e[1] += v.e[1]; 28 | e[2] += v.e[2]; 29 | return *this; 30 | } 31 | 32 | vec3& operator*=(const double t) { 33 | e[0] *= t; 34 | e[1] *= t; 35 | e[2] *= t; 36 | return *this; 37 | } 38 | 39 | vec3& operator/=(const double t) { 40 | return *this *= 1 / t; 41 | } 42 | 43 | double length() const { 44 | return std::sqrt(length_squared()); 45 | } 46 | 47 | double length_squared() const { 48 | return e[0] * e[0] + e[1] * e[1] + e[2] * e[2]; 49 | } 50 | 51 | bool near_zero() const { 52 | // Return true if the vector is close to zero in all dimensions. 53 | constexpr auto s = 1e-8; 54 | return (std::fabs(e[0]) < s) && (std::fabs(e[1]) < s) && (std::fabs(e[2]) < s); 55 | } 56 | 57 | inline static vec3 random() { 58 | return vec3(random_double(), random_double(), random_double()); 59 | } 60 | 61 | inline static vec3 random(double min, double max) { 62 | return vec3(random_double(min, max), random_double(min, max), random_double(min, max)); 63 | } 64 | 65 | public: 66 | double e[3]; 67 | }; 68 | 69 | // Type aliases for vec3 70 | using point3 = vec3; // 3D point 71 | using color = vec3; 72 | 73 | // vec3 Utility Functions 74 | inline std::ostream& operator<<(std::ostream& out, const vec3& v) { 75 | return out << v.e[0] << ' ' << v.e[1] << ' ' << v.e[2]; 76 | } 77 | 78 | inline vec3 operator+(const vec3& u, const vec3& v) { 79 | return vec3(u.e[0] + v.e[0], u.e[1] + v.e[1], u.e[2] + v.e[2]); 80 | } 81 | 82 | inline vec3 operator-(const vec3& u, const vec3& v) { 83 | return vec3(u.e[0] - v.e[0], u.e[1] - v.e[1], u.e[2] - v.e[2]); 84 | } 85 | 86 | inline vec3 operator*(const vec3& u, const vec3& v) { 87 | return vec3(u.e[0] * v.e[0], u.e[1] * v.e[1], u.e[2] * v.e[2]); 88 | } 89 | 90 | inline vec3 operator*(double t, const vec3& v) { 91 | return vec3(t * v.e[0], t * v.e[1], t * v.e[2]); 92 | } 93 | 94 | inline vec3 operator*(const vec3& v, double t) { 95 | return t * v; 96 | } 97 | 98 | inline vec3 operator/(vec3 v, double t) { 99 | return (1 / t) * v; 100 | } 101 | 102 | inline double dot(const vec3& u, const vec3& v) { 103 | return u.e[0] * v.e[0] 104 | + u.e[1] * v.e[1] 105 | + u.e[2] * v.e[2]; 106 | } 107 | 108 | inline vec3 cross(const vec3& u, const vec3& v) { 109 | return vec3(u.e[1] * v.e[2] - u.e[2] * v.e[1], 110 | u.e[2] * v.e[0] - u.e[0] * v.e[2], 111 | u.e[0] * v.e[1] - u.e[1] * v.e[0]); 112 | } 113 | 114 | inline vec3 unit_vector(vec3 v) { 115 | return v / v.length(); 116 | } 117 | 118 | vec3 reflect(const vec3& v, const vec3& n) { 119 | return v - 2 * dot(v, n) * n; 120 | } 121 | 122 | vec3 random_in_unit_sphere() { 123 | while (true) { 124 | auto p = vec3::random(-1, 1); 125 | if (p.length_squared() >= 1) continue; 126 | return p; 127 | } 128 | } 129 | 130 | vec3 refract(const vec3& uv, const vec3& n, double etai_over_etat) { 131 | auto cos_theta = fmin(dot(-uv, n), 1.0); 132 | vec3 r_out_perp = etai_over_etat * (uv + cos_theta * n); 133 | vec3 r_out_parallel = -std::sqrt(fabs(1.0 - r_out_perp.length_squared())) * n; 134 | return r_out_perp + r_out_parallel; 135 | } 136 | 137 | 138 | // Constants 139 | constinit double infinity = std::numeric_limits::infinity(); 140 | constinit double pi = 3.1415926535897932385; 141 | 142 | // Utility Functions 143 | 144 | inline double degrees_to_radians(double degrees) { 145 | return degrees * pi / 180.0; 146 | } 147 | 148 | inline double random_double() { 149 | static std::uniform_real_distribution distribution(0.0, 1.0); 150 | static std::mt19937 generator; 151 | return distribution(generator); 152 | } 153 | 154 | inline double random_double(double min, double max) { 155 | // Returns a random real in [min,max). 156 | return min + (max - min) * random_double(); 157 | } 158 | 159 | vec3 random_unit_vector() { 160 | return unit_vector(random_in_unit_sphere()); 161 | } 162 | 163 | vec3 random_in_unit_disk() { 164 | while (true) { 165 | auto p = vec3(random_double(-1, 1), random_double(-1, 1), 0); 166 | if (p.length_squared() >= 1) continue; 167 | return p; 168 | } 169 | } 170 | 171 | vec3 random_in_hemisphere(const vec3& normal) { 172 | vec3 in_unit_sphere = random_in_unit_sphere(); 173 | if (dot(in_unit_sphere, normal) > 0.0) // In the same hemisphere as the normal 174 | return in_unit_sphere; 175 | else 176 | return -in_unit_sphere; 177 | } 178 | 179 | inline double clamp(double x, double min, double max) { 180 | if (x < min) return min; 181 | if (x > max) return max; 182 | return x; 183 | } 184 | 185 | } 186 | -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/images.ixx: -------------------------------------------------------------------------------- 1 | module; 2 | 3 | // for sprintf_s and friends 4 | #ifdef _WIN32 5 | #define __STDC_LIB_EXT1__ 6 | #endif 7 | 8 | #ifdef __clang__ 9 | #pragma clang diagnostic push 10 | #pragma clang diagnostic ignored "-Wmissing-field-initializers" 11 | #endif 12 | 13 | #define STB_IMAGE_WRITE_IMPLEMENTATION 14 | #include "stb_image_write.h" 15 | 16 | #ifdef __clang__ 17 | #pragma clang diagnostic pop 18 | #endif 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | export module RaytracingLib:images; 27 | 28 | import :algebra; 29 | 30 | // public view of the module 31 | export namespace RaytracingLib { 32 | /** 33 | * @brief Set of available pixel formats to export. 34 | */ 35 | enum class PixelFormat : int { RGB = 3, RGBA = 4 }; 36 | 37 | /** 38 | * @brief Allows writing a data buffer representing an image as a PNG. 39 | * @param filename The complete path to the filename being written. 40 | * @param width The image width. 41 | * @param height The image height. 42 | * @param buffer The image contents, it must match the desired size. 43 | * @exception std::logic_error if there is an error saving the file. 44 | * @exception std::out_of_range if there is an error saving the file. 45 | */ 46 | void write_image(const std::string& filename, int width, int height, PixelFormat format, std::span buffer) { 47 | auto bpp = static_cast(format); 48 | if (static_cast(width * height * bpp) > buffer.size()) { 49 | throw std::out_of_range("Image buffer isn't the expected size"); 50 | } 51 | 52 | stbi_flip_vertically_on_write(true); 53 | int res = stbi_write_png(filename.c_str(), width, height, bpp, buffer.data(), bpp * width); 54 | if (res == 0) { 55 | throw std::logic_error("Failed to write the image file"); 56 | } 57 | } 58 | 59 | /** 60 | * @brief Provides a type safe abstraction of an image data buffer. 61 | */ 62 | class ImageBuffer final { 63 | public: 64 | ImageBuffer(int width, int height) : imgWidth(width), imgHeight(height), imgFormat(PixelFormat::RGB) 65 | { 66 | buffer.resize(width * height * static_cast(PixelFormat::RGB)); 67 | } 68 | 69 | ImageBuffer(int width, int height, PixelFormat format): imgWidth(width), imgHeight(height), imgFormat(format) 70 | { 71 | buffer.resize(width * height * static_cast(imgFormat)); 72 | } 73 | 74 | int width() const noexcept { return imgWidth; } 75 | int height() const noexcept { return imgHeight; } 76 | PixelFormat format() const noexcept { return imgFormat; } 77 | 78 | void set_color(int x, int y, std::uint8_t r, std::uint8_t g, std::uint8_t b) { 79 | const int bpp = static_cast(imgFormat); 80 | const int index = (y * imgHeight + x) * bpp; 81 | if (static_cast(index + bpp) > buffer.size()) { 82 | throw std::out_of_range("Image buffer isn't the expected size"); 83 | } 84 | 85 | buffer[index ] = r; 86 | buffer[index + 1] = g; 87 | buffer[index + 2] = b; 88 | } 89 | 90 | void set_color(int x, int y, color pixel_color) { 91 | const int bpp = static_cast(imgFormat); 92 | const int index = (y * imgWidth + x) * bpp; 93 | if (static_cast(index + bpp) > buffer.size()) { 94 | throw std::out_of_range("Image buffer isn't the expected size"); 95 | } 96 | 97 | // Write the translated [0,255] value of each color component. 98 | buffer[index] = static_cast(255.999 * pixel_color.x()); 99 | buffer[index + 1] = static_cast(255.999 * pixel_color.y()); 100 | buffer[index + 2] = static_cast(255.999 * pixel_color.z()); 101 | } 102 | 103 | void set_color(int x, int y, color pixel_color, int samples_per_pixel) { 104 | const int bpp = static_cast(imgFormat); 105 | const int index = (y * imgWidth + x) * bpp; 106 | if (static_cast(index + bpp) > buffer.size()) { 107 | throw std::out_of_range("Image buffer isn't the expected size"); 108 | } 109 | 110 | auto r = pixel_color.x(); 111 | auto g = pixel_color.y(); 112 | auto b = pixel_color.z(); 113 | 114 | // Divide the color by the number of samples and gamma-correct for gamma=2.0. 115 | auto scale = 1.0 / samples_per_pixel; 116 | r = sqrt(scale * r); 117 | g = sqrt(scale * g); 118 | b = sqrt(scale * b); 119 | 120 | // Write the translated [0,255] value of each color component. 121 | buffer[index] = static_cast(256 * clamp(r, 0.0, 0.999)); 122 | buffer[index + 1] = static_cast(256 * clamp(g, 0.0, 0.999)); 123 | buffer[index + 2] = static_cast(256 * clamp(b, 0.0, 0.999)); 124 | } 125 | 126 | void set_color(int x, int y, std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a) { 127 | constexpr int bpp = static_cast(PixelFormat::RGBA); 128 | const int index = (y * imgWidth + x) * bpp; 129 | if (static_cast(index + bpp) > buffer.size()) { 130 | throw std::out_of_range("Image buffer isn't the expected size"); 131 | } 132 | 133 | buffer[index] = r; 134 | buffer[index + 1] = g; 135 | buffer[index + 2] = b; 136 | buffer[index + 3] = a; 137 | } 138 | 139 | void save(const std::string& filename) { 140 | write_image(filename, imgWidth, imgHeight, imgFormat, buffer); 141 | } 142 | 143 | private: 144 | const int imgWidth; 145 | const int imgHeight; 146 | 147 | PixelFormat imgFormat; 148 | std::vector buffer; 149 | }; 150 | } 151 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | -------------------------------------------------------------------------------- /OneWeekend/Raytracing/Raytracing.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | {0977ca7b-df59-49c8-a0ab-2b3a47405908} 27 | 28 | 29 | 30 | 16.0 31 | Win32Proj 32 | {C696869F-5D7D-4444-818A-249917DBDB46} 33 | Raytracing 34 | 10.0 35 | 36 | 37 | 38 | Application 39 | true 40 | v143 41 | Unicode 42 | 43 | 44 | Application 45 | false 46 | v143 47 | true 48 | Unicode 49 | 50 | 51 | Application 52 | true 53 | v143 54 | Unicode 55 | 56 | 57 | Application 58 | false 59 | v143 60 | true 61 | Unicode 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | true 83 | 84 | 85 | false 86 | 87 | 88 | true 89 | 90 | 91 | false 92 | 93 | 94 | 95 | Level3 96 | true 97 | WIN32;_DEBUG;_CONSOLE;_MSVC_STL_HARDENING=1;%(PreprocessorDefinitions) 98 | true 99 | stdcpplatest 100 | true 101 | true 102 | 103 | 104 | Console 105 | true 106 | 107 | 108 | 109 | 110 | Level3 111 | true 112 | true 113 | true 114 | WIN32;NDEBUG;_CONSOLE;_MSVC_STL_HARDENING=1;%(PreprocessorDefinitions) 115 | true 116 | stdcpplatest 117 | true 118 | true 119 | 120 | 121 | Console 122 | true 123 | true 124 | true 125 | 126 | 127 | 128 | 129 | Level3 130 | true 131 | _DEBUG;_CONSOLE;_MSVC_STL_HARDENING=1;%(PreprocessorDefinitions) 132 | true 133 | stdcpplatest 134 | true 135 | true 136 | 137 | 138 | Console 139 | true 140 | 141 | 142 | 143 | 144 | Level3 145 | true 146 | true 147 | true 148 | NDEBUG;_CONSOLE;_MSVC_STL_HARDENING=1;%(PreprocessorDefinitions) 149 | true 150 | stdcpplatest 151 | true 152 | true 153 | 154 | 155 | Console 156 | true 157 | true 158 | true 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /OneWeekend/RaytracingLib/RaytracingLib.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 16.0 23 | Win32Proj 24 | {0977ca7b-df59-49c8-a0ab-2b3a47405908} 25 | RaytracingLib 26 | 10.0 27 | 28 | 29 | 30 | StaticLibrary 31 | true 32 | v143 33 | Unicode 34 | 35 | 36 | StaticLibrary 37 | false 38 | v143 39 | true 40 | Unicode 41 | 42 | 43 | StaticLibrary 44 | true 45 | v143 46 | Unicode 47 | 48 | 49 | StaticLibrary 50 | false 51 | v143 52 | true 53 | Unicode 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | true 75 | 76 | 77 | false 78 | 79 | 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | true 87 | 88 | 89 | 90 | Level3 91 | true 92 | WIN32;_DEBUG;_LIB;_MSVC_STL_HARDENING=1;%(PreprocessorDefinitions) 93 | true 94 | NotUsing 95 | pch.h 96 | stdcpplatest 97 | true 98 | true 99 | 100 | 101 | 102 | 103 | true 104 | 105 | 106 | 107 | 108 | Level3 109 | true 110 | true 111 | true 112 | WIN32;NDEBUG;_LIB;_MSVC_STL_HARDENING=1;%(PreprocessorDefinitions) 113 | true 114 | NotUsing 115 | pch.h 116 | stdcpplatest 117 | true 118 | true 119 | 120 | 121 | 122 | 123 | true 124 | true 125 | true 126 | 127 | 128 | 129 | 130 | Level3 131 | true 132 | _DEBUG;_LIB;_MSVC_STL_HARDENING=1;%(PreprocessorDefinitions) 133 | true 134 | NotUsing 135 | pch.h 136 | stdcpplatest 137 | true 138 | true 139 | 140 | 141 | 142 | 143 | true 144 | 145 | 146 | 147 | 148 | Level3 149 | true 150 | true 151 | true 152 | NDEBUG;_LIB;_MSVC_STL_HARDENING=1;%(PreprocessorDefinitions) 153 | true 154 | NotUsing 155 | pch.h 156 | stdcpplatest 157 | true 158 | true 159 | 160 | 161 | 162 | 163 | true 164 | true 165 | true 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | --------------------------------------------------------------------------------