├── 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 | 
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 |
--------------------------------------------------------------------------------