├── .gitignore ├── images ├── earthmap.jpg ├── fig.lerp.jpg ├── fig.rotz.jpg ├── RTNextWeek.jpg ├── fig.2daabb.jpg ├── fig.cam-up.jpg ├── fig.circ-sq.jpg ├── fig.jitter.jpg ├── fig.ray-box.jpg ├── fig.ray-vol.jpg ├── fig.rstio.jpg ├── RTOneWeekend.jpg ├── fig.cam-geom.jpg ├── fig.cam-lens.jpg ├── fig.cam-look.jpg ├── fig.histogram.jpg ├── fig.light-pdf.jpg ├── fig.ray-rect.jpg ├── fig.ray-slab.jpg ├── img.antialias.png ├── img.view-zoom.png ├── img.wide-view.png ├── RTNextWeek-small.jpg ├── RTRestOfYourLife.jpg ├── fig.light-bounce.jpg ├── fig.linear-pdf.jpg ├── fig.rand-vector.jpg ├── fig.ray-reflect.jpg ├── fig.ray-refract.jpg ├── fig.ray-sphere.jpg ├── fig.solid-angle.jpg ├── fig.sphere-cone.jpg ├── img.book1-final.jpg ├── img.book2-final.jpg ├── img.book3-final.jpg ├── img.cornell-box.jpg ├── img.earth-sphere.jpg ├── img.glass-first.png ├── img.glass-hollow.png ├── img.hash-random.jpg ├── img.metal-fuzz.png ├── img.metal-shiny.png ├── img.perlin-shift.jpg ├── img.perlin-turb.jpg ├── img.ppm-example.jpg ├── img.rect-light.jpg ├── img.red-sphere.png ├── img.tile-random.jpg ├── img.view-distant.png ├── img.white-noise.jpg ├── RTOneWeekend-small.jpg ├── fig.bvol-hierarchy.jpg ├── fig.cam-film-plane.jpg ├── fig.cam-view-geom.jpg ├── fig.pixel-samples.jpg ├── fig.pt-uni-sphere.jpg ├── fig.reflect-fuzzy.jpg ├── fig.sphere-normal.jpg ├── img.blue-to-white.png ├── img.checker-ground.jpg ├── img.cornell-blocks.jpg ├── img.cornell-cospdf.jpg ├── img.cornell-empty.jpg ├── img.cornell-first.jpg ├── img.cornell-glass.jpg ├── img.cornell-ortho.jpg ├── img.cornell-smoke.jpg ├── img.depth-of-field.png ├── img.first-diffuse.jpg ├── img.gamma-correct.jpg ├── img.normals-sphere.png ├── img.perlin-hifreq.jpg ├── img.perlin-marble.jpg ├── img.perlin-trilerp.jpg ├── img.rect-sph-light.jpg ├── fig.rand-unitvector.png ├── img.bouncing-spheres.jpg ├── img.checker-spheres.jpg ├── img.cornell-coslight.jpg ├── img.cornell-flexpdf.jpg ├── img.cornell-lightdown.jpg ├── img.cornell-refactor1.jpg ├── img.cornell-refactor2.jpg ├── img.cornell-samphit.jpg ├── img.cornell-samplight.jpg ├── img.first-ppm-image.png ├── img.glass-no-reflect.png ├── img.white-noise-blur.jpg ├── RTRestOfYourLife-small.jpg ├── img.cornell-glasslight.jpg ├── img.correct-lambertian.png ├── img.perlin-tlerp-smooth.jpg ├── img.rand-hemispherical.png ├── fig.normal-possibilities.jpg ├── img.glass-always-refract.png ├── img.normals-sphere-ground.png └── img.glass-sometimes-refract.png ├── src ├── common │ ├── rtw_stb_image.h │ ├── ray.h │ ├── color.h │ ├── rtweekend.h │ ├── camera.h │ ├── aabb.h │ ├── perlin.h │ ├── texture.h │ └── vec3.h ├── TheRestOfYourLife │ ├── sphere_plot.cc │ ├── sphere_importance.cc │ ├── integrate_x_sq.cc │ ├── cos_cubed.cc │ ├── cos_density.cc │ ├── onb.h │ ├── pi.cc │ ├── README.md │ ├── box.h │ ├── hittable_list.h │ ├── pdf.h │ ├── sphere.h │ ├── bvh.h │ ├── main.cc │ ├── aarect.h │ ├── material.h │ └── hittable.h ├── InOneWeekend │ ├── hittable.h │ ├── hittable_list.h │ ├── README.md │ ├── sphere.h │ ├── material.h │ └── main.cc └── TheNextWeek │ ├── box.h │ ├── hittable_list.h │ ├── README.md │ ├── sphere.h │ ├── constant_medium.h │ ├── moving_sphere.h │ ├── bvh.h │ ├── material.h │ ├── aarect.h │ └── hittable.h ├── style ├── website.css └── book.css ├── books └── acknowledgments.md.html ├── CMakeLists.txt ├── CONTRIBUTING.md ├── index.html ├── README.md ├── COPYING.txt └── CHANGELOG.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Git Ignore Rules for raytracing.github.io 2 | 3 | /build/ 4 | -------------------------------------------------------------------------------- /images/earthmap.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/earthmap.jpg -------------------------------------------------------------------------------- /images/fig.lerp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.lerp.jpg -------------------------------------------------------------------------------- /images/fig.rotz.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.rotz.jpg -------------------------------------------------------------------------------- /images/RTNextWeek.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/RTNextWeek.jpg -------------------------------------------------------------------------------- /images/fig.2daabb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.2daabb.jpg -------------------------------------------------------------------------------- /images/fig.cam-up.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.cam-up.jpg -------------------------------------------------------------------------------- /images/fig.circ-sq.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.circ-sq.jpg -------------------------------------------------------------------------------- /images/fig.jitter.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.jitter.jpg -------------------------------------------------------------------------------- /images/fig.ray-box.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.ray-box.jpg -------------------------------------------------------------------------------- /images/fig.ray-vol.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.ray-vol.jpg -------------------------------------------------------------------------------- /images/fig.rstio.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.rstio.jpg -------------------------------------------------------------------------------- /images/RTOneWeekend.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/RTOneWeekend.jpg -------------------------------------------------------------------------------- /images/fig.cam-geom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.cam-geom.jpg -------------------------------------------------------------------------------- /images/fig.cam-lens.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.cam-lens.jpg -------------------------------------------------------------------------------- /images/fig.cam-look.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.cam-look.jpg -------------------------------------------------------------------------------- /images/fig.histogram.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.histogram.jpg -------------------------------------------------------------------------------- /images/fig.light-pdf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.light-pdf.jpg -------------------------------------------------------------------------------- /images/fig.ray-rect.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.ray-rect.jpg -------------------------------------------------------------------------------- /images/fig.ray-slab.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.ray-slab.jpg -------------------------------------------------------------------------------- /images/img.antialias.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.antialias.png -------------------------------------------------------------------------------- /images/img.view-zoom.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.view-zoom.png -------------------------------------------------------------------------------- /images/img.wide-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.wide-view.png -------------------------------------------------------------------------------- /images/RTNextWeek-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/RTNextWeek-small.jpg -------------------------------------------------------------------------------- /images/RTRestOfYourLife.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/RTRestOfYourLife.jpg -------------------------------------------------------------------------------- /images/fig.light-bounce.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.light-bounce.jpg -------------------------------------------------------------------------------- /images/fig.linear-pdf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.linear-pdf.jpg -------------------------------------------------------------------------------- /images/fig.rand-vector.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.rand-vector.jpg -------------------------------------------------------------------------------- /images/fig.ray-reflect.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.ray-reflect.jpg -------------------------------------------------------------------------------- /images/fig.ray-refract.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.ray-refract.jpg -------------------------------------------------------------------------------- /images/fig.ray-sphere.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.ray-sphere.jpg -------------------------------------------------------------------------------- /images/fig.solid-angle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.solid-angle.jpg -------------------------------------------------------------------------------- /images/fig.sphere-cone.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.sphere-cone.jpg -------------------------------------------------------------------------------- /images/img.book1-final.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.book1-final.jpg -------------------------------------------------------------------------------- /images/img.book2-final.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.book2-final.jpg -------------------------------------------------------------------------------- /images/img.book3-final.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.book3-final.jpg -------------------------------------------------------------------------------- /images/img.cornell-box.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-box.jpg -------------------------------------------------------------------------------- /images/img.earth-sphere.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.earth-sphere.jpg -------------------------------------------------------------------------------- /images/img.glass-first.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.glass-first.png -------------------------------------------------------------------------------- /images/img.glass-hollow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.glass-hollow.png -------------------------------------------------------------------------------- /images/img.hash-random.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.hash-random.jpg -------------------------------------------------------------------------------- /images/img.metal-fuzz.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.metal-fuzz.png -------------------------------------------------------------------------------- /images/img.metal-shiny.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.metal-shiny.png -------------------------------------------------------------------------------- /images/img.perlin-shift.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.perlin-shift.jpg -------------------------------------------------------------------------------- /images/img.perlin-turb.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.perlin-turb.jpg -------------------------------------------------------------------------------- /images/img.ppm-example.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.ppm-example.jpg -------------------------------------------------------------------------------- /images/img.rect-light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.rect-light.jpg -------------------------------------------------------------------------------- /images/img.red-sphere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.red-sphere.png -------------------------------------------------------------------------------- /images/img.tile-random.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.tile-random.jpg -------------------------------------------------------------------------------- /images/img.view-distant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.view-distant.png -------------------------------------------------------------------------------- /images/img.white-noise.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.white-noise.jpg -------------------------------------------------------------------------------- /images/RTOneWeekend-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/RTOneWeekend-small.jpg -------------------------------------------------------------------------------- /images/fig.bvol-hierarchy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.bvol-hierarchy.jpg -------------------------------------------------------------------------------- /images/fig.cam-film-plane.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.cam-film-plane.jpg -------------------------------------------------------------------------------- /images/fig.cam-view-geom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.cam-view-geom.jpg -------------------------------------------------------------------------------- /images/fig.pixel-samples.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.pixel-samples.jpg -------------------------------------------------------------------------------- /images/fig.pt-uni-sphere.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.pt-uni-sphere.jpg -------------------------------------------------------------------------------- /images/fig.reflect-fuzzy.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.reflect-fuzzy.jpg -------------------------------------------------------------------------------- /images/fig.sphere-normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.sphere-normal.jpg -------------------------------------------------------------------------------- /images/img.blue-to-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.blue-to-white.png -------------------------------------------------------------------------------- /images/img.checker-ground.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.checker-ground.jpg -------------------------------------------------------------------------------- /images/img.cornell-blocks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-blocks.jpg -------------------------------------------------------------------------------- /images/img.cornell-cospdf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-cospdf.jpg -------------------------------------------------------------------------------- /images/img.cornell-empty.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-empty.jpg -------------------------------------------------------------------------------- /images/img.cornell-first.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-first.jpg -------------------------------------------------------------------------------- /images/img.cornell-glass.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-glass.jpg -------------------------------------------------------------------------------- /images/img.cornell-ortho.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-ortho.jpg -------------------------------------------------------------------------------- /images/img.cornell-smoke.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-smoke.jpg -------------------------------------------------------------------------------- /images/img.depth-of-field.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.depth-of-field.png -------------------------------------------------------------------------------- /images/img.first-diffuse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.first-diffuse.jpg -------------------------------------------------------------------------------- /images/img.gamma-correct.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.gamma-correct.jpg -------------------------------------------------------------------------------- /images/img.normals-sphere.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.normals-sphere.png -------------------------------------------------------------------------------- /images/img.perlin-hifreq.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.perlin-hifreq.jpg -------------------------------------------------------------------------------- /images/img.perlin-marble.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.perlin-marble.jpg -------------------------------------------------------------------------------- /images/img.perlin-trilerp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.perlin-trilerp.jpg -------------------------------------------------------------------------------- /images/img.rect-sph-light.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.rect-sph-light.jpg -------------------------------------------------------------------------------- /images/fig.rand-unitvector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.rand-unitvector.png -------------------------------------------------------------------------------- /images/img.bouncing-spheres.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.bouncing-spheres.jpg -------------------------------------------------------------------------------- /images/img.checker-spheres.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.checker-spheres.jpg -------------------------------------------------------------------------------- /images/img.cornell-coslight.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-coslight.jpg -------------------------------------------------------------------------------- /images/img.cornell-flexpdf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-flexpdf.jpg -------------------------------------------------------------------------------- /images/img.cornell-lightdown.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-lightdown.jpg -------------------------------------------------------------------------------- /images/img.cornell-refactor1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-refactor1.jpg -------------------------------------------------------------------------------- /images/img.cornell-refactor2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-refactor2.jpg -------------------------------------------------------------------------------- /images/img.cornell-samphit.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-samphit.jpg -------------------------------------------------------------------------------- /images/img.cornell-samplight.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-samplight.jpg -------------------------------------------------------------------------------- /images/img.first-ppm-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.first-ppm-image.png -------------------------------------------------------------------------------- /images/img.glass-no-reflect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.glass-no-reflect.png -------------------------------------------------------------------------------- /images/img.white-noise-blur.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.white-noise-blur.jpg -------------------------------------------------------------------------------- /images/RTRestOfYourLife-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/RTRestOfYourLife-small.jpg -------------------------------------------------------------------------------- /images/img.cornell-glasslight.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.cornell-glasslight.jpg -------------------------------------------------------------------------------- /images/img.correct-lambertian.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.correct-lambertian.png -------------------------------------------------------------------------------- /images/img.perlin-tlerp-smooth.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.perlin-tlerp-smooth.jpg -------------------------------------------------------------------------------- /images/img.rand-hemispherical.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.rand-hemispherical.png -------------------------------------------------------------------------------- /images/fig.normal-possibilities.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/fig.normal-possibilities.jpg -------------------------------------------------------------------------------- /images/img.glass-always-refract.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.glass-always-refract.png -------------------------------------------------------------------------------- /images/img.normals-sphere-ground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.normals-sphere-ground.png -------------------------------------------------------------------------------- /images/img.glass-sometimes-refract.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/D-K-E/raytracing.github.io/master/images/img.glass-sometimes-refract.png -------------------------------------------------------------------------------- /src/common/rtw_stb_image.h: -------------------------------------------------------------------------------- 1 | #ifndef RTWEEKEND_STB_IMAGE_H 2 | #define RTWEEKEND_STB_IMAGE_H 3 | 4 | 5 | // Disable pedantic warnings for this external library. 6 | #ifdef _MSC_VER 7 | // Microsoft Visual C++ Compiler 8 | #pragma warning (push, 0) 9 | #endif 10 | 11 | 12 | 13 | #define STB_IMAGE_IMPLEMENTATION 14 | #include "external/stb_image.h" 15 | 16 | 17 | // Restore warning levels. 18 | #ifdef _MSC_VER 19 | // Microsoft Visual C++ Compiler 20 | #pragma warning (pop) 21 | #endif 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /style/website.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 3em 8%; 3 | font-family: Helvetica, Arial, sans-serif; 4 | color: black; 5 | } 6 | 7 | a { 8 | text-decoration: none; 9 | color: #00f; 10 | } 11 | 12 | a:visited { 13 | color: #90c; 14 | } 15 | 16 | a:hover { 17 | text-decoration: underline; 18 | } 19 | 20 | div.content { 21 | max-width: 40em; 22 | margin: 0 auto; 23 | } 24 | 25 | h1, h2, h3 { 26 | font-family: Copperplate Gothic, Georgia, serif; 27 | } 28 | 29 | h1 { 30 | font-weight: 900; 31 | margin: 1.5em 0 0 0; 32 | padding-left: 1ex; 33 | background: #2c2c2c; 34 | color: white; 35 | } 36 | 37 | h1.title { 38 | font-variant: small-caps; 39 | text-align: center; 40 | font-size: 260%; 41 | margin: 2em 0 0.5em 0; 42 | padding: .25em 0; 43 | } 44 | 45 | div.books { 46 | display: flex; 47 | flex-direction: row; 48 | justify-content: space-between; 49 | margin-bottom: 4em; 50 | } 51 | 52 | div.books a { 53 | text-decoration: none; 54 | } 55 | 56 | p { 57 | line-height: 140%; 58 | } 59 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/sphere_plot.cc: -------------------------------------------------------------------------------- 1 | //============================================================================================== 2 | // Originally written in 2016 by Peter Shirley 3 | // 4 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 5 | // neighboring rights to this software to the public domain worldwide. This software is 6 | // distributed without any warranty. 7 | // 8 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 9 | // along with this software. If not, see . 10 | //============================================================================================== 11 | 12 | #include "rtweekend.h" 13 | 14 | #include 15 | #include 16 | 17 | 18 | int main() { 19 | for (int i = 0; i < 2000; i++) { 20 | auto r1 = random_double(); 21 | auto r2 = random_double(); 22 | auto x = cos(2*pi*r1)*2*sqrt(r2*(1-r2)); 23 | auto y = sin(2*pi*r1)*2*sqrt(r2*(1-r2)); 24 | auto z = 1 - 2*r2; 25 | 26 | std::cout << x << " " << y << " " << z << '\n'; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/sphere_importance.cc: -------------------------------------------------------------------------------- 1 | //============================================================================================== 2 | // Originally written in 2016 by Peter Shirley 3 | // 4 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 5 | // neighboring rights to this software to the public domain worldwide. This software is 6 | // distributed without any warranty. 7 | // 8 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 9 | // along with this software. If not, see . 10 | //============================================================================================== 11 | 12 | #include "rtweekend.h" 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | 20 | inline double pdf(const vec3& p) { 21 | return 1.0 / (4.0*pi); 22 | } 23 | 24 | 25 | int main() { 26 | int N = 1000000; 27 | auto sum = 0.0; 28 | for (int i = 0; i < N; i++) { 29 | vec3 d = random_unit_vector(); 30 | auto cosine_squared = d.z()*d.z(); 31 | sum += cosine_squared / pdf(d); 32 | } 33 | std::cout << std::fixed << std::setprecision(12); 34 | std::cout << "I = " << sum/N << '\n'; 35 | } 36 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/integrate_x_sq.cc: -------------------------------------------------------------------------------- 1 | //============================================================================================== 2 | // Originally written in 2016 by Peter Shirley 3 | // 4 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 5 | // neighboring rights to this software to the public domain worldwide. This software is 6 | // distributed without any warranty. 7 | // 8 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 9 | // along with this software. If not, see . 10 | //============================================================================================== 11 | 12 | #include "rtweekend.h" 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | 20 | inline double pdf(double x) { 21 | return 3*x*x/8; 22 | } 23 | 24 | int main() { 25 | int inside_circle = 0; 26 | int inside_circle_stratified = 0; 27 | int N = 1; 28 | 29 | auto sum = 0.0; 30 | for (int i = 0; i < N; i++) { 31 | auto x = pow(random_double(0,8), 1./3.); 32 | sum += x*x / pdf(x); 33 | } 34 | 35 | std::cout << std::fixed << std::setprecision(12); 36 | std::cout << "I = " << sum/N << '\n'; 37 | } 38 | -------------------------------------------------------------------------------- /src/InOneWeekend/hittable.h: -------------------------------------------------------------------------------- 1 | #ifndef HITTABLE_H 2 | #define HITTABLE_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | 17 | class material; 18 | 19 | struct hit_record { 20 | point3 p; 21 | vec3 normal; 22 | shared_ptr mat_ptr; 23 | double t; 24 | bool front_face; 25 | 26 | inline void set_face_normal(const ray& r, const vec3& outward_normal) { 27 | front_face = dot(r.direction(), outward_normal) < 0; 28 | normal = front_face ? outward_normal :-outward_normal; 29 | } 30 | }; 31 | 32 | 33 | class hittable { 34 | public: 35 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const = 0; 36 | }; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/cos_cubed.cc: -------------------------------------------------------------------------------- 1 | //============================================================================================== 2 | // Originally written in 2016 by Peter Shirley 3 | // 4 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 5 | // neighboring rights to this software to the public domain worldwide. This software is 6 | // distributed without any warranty. 7 | // 8 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 9 | // along with this software. If not, see . 10 | //============================================================================================== 11 | 12 | #include "rtweekend.h" 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | int main() { 20 | int N = 1000000; 21 | 22 | auto sum = 0.0; 23 | for (int i = 0; i < N; i++) { 24 | auto r1 = random_double(); 25 | auto r2 = random_double(); 26 | auto x = cos(2*pi*r1)*2*sqrt(r2*(1-r2)); 27 | auto y = sin(2*pi*r1)*2*sqrt(r2*(1-r2)); 28 | auto z = 1 - r2; 29 | 30 | sum += z*z*z / (1.0/(2.0*pi)); 31 | } 32 | 33 | std::cout << std::fixed << std::setprecision(12); 34 | std::cout << "PI/2 = " << pi/2 << '\n'; 35 | std::cout << "Estimate = " << sum/N << '\n'; 36 | } 37 | -------------------------------------------------------------------------------- /src/common/ray.h: -------------------------------------------------------------------------------- 1 | #ifndef RAY_H 2 | #define RAY_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "vec3.h" 15 | 16 | 17 | class ray 18 | { 19 | public: 20 | ray() {} 21 | ray(const point3& origin, const vec3& direction) 22 | : orig(origin), dir(direction), tm(0) 23 | {} 24 | 25 | ray(const point3& origin, const vec3& direction, double time) 26 | : orig(origin), dir(direction), tm(time) 27 | {} 28 | 29 | point3 origin() const { return orig; } 30 | vec3 direction() const { return dir; } 31 | double time() const { return tm; } 32 | 33 | point3 at(double t) const { 34 | return orig + t*dir; 35 | } 36 | 37 | public: 38 | point3 orig; 39 | vec3 dir; 40 | double tm; 41 | }; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/cos_density.cc: -------------------------------------------------------------------------------- 1 | //============================================================================================== 2 | // Originally written in 2016 by Peter Shirley 3 | // 4 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 5 | // neighboring rights to this software to the public domain worldwide. This software is 6 | // distributed without any warranty. 7 | // 8 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 9 | // along with this software. If not, see . 10 | //============================================================================================== 11 | 12 | #include "rtweekend.h" 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | 19 | inline vec3 random_cosine_direction() { 20 | auto r1 = random_double(); 21 | auto r2 = random_double(); 22 | auto z = sqrt(1-r2); 23 | auto phi = 2*pi*r1; 24 | auto x = cos(phi)*sqrt(r2); 25 | auto y = sin(phi)*sqrt(r2); 26 | 27 | return vec3(x, y, z); 28 | } 29 | 30 | 31 | int main() { 32 | int N = 1000000; 33 | 34 | auto sum = 0.0; 35 | for (int i = 0; i < N; i++) { 36 | auto v = random_cosine_direction(); 37 | sum += v.z()*v.z()*v.z() / (v.z()/(pi)); 38 | } 39 | 40 | std::cout << std::fixed << std::setprecision(12); 41 | std::cout << "PI/2 = " << pi/2 << '\n'; 42 | std::cout << "Estimate = " << sum/N << '\n'; 43 | } 44 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/onb.h: -------------------------------------------------------------------------------- 1 | #ifndef ONB_H 2 | #define ONB_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | 17 | class onb 18 | { 19 | public: 20 | onb() {} 21 | 22 | inline vec3 operator[](int i) const { return axis[i]; } 23 | 24 | vec3 u() const { return axis[0]; } 25 | vec3 v() const { return axis[1]; } 26 | vec3 w() const { return axis[2]; } 27 | 28 | vec3 local(double a, double b, double c) const { 29 | return a*u() + b*v() + c*w(); 30 | } 31 | 32 | vec3 local(const vec3& a) const { 33 | return a.x()*u() + a.y()*v() + a.z()*w(); 34 | } 35 | 36 | void build_from_w(const vec3&); 37 | 38 | public: 39 | vec3 axis[3]; 40 | }; 41 | 42 | 43 | void onb::build_from_w(const vec3& n) { 44 | axis[2] = unit_vector(n); 45 | vec3 a = (fabs(w().x()) > 0.9) ? vec3(0,1,0) : vec3(1,0,0); 46 | axis[1] = unit_vector(cross(w(), a)); 47 | axis[0] = cross(w(), v()); 48 | } 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/common/color.h: -------------------------------------------------------------------------------- 1 | #ifndef COLOR_H 2 | #define COLOR_H 3 | //============================================================================================== 4 | // Originally written in 2020 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "vec3.h" 15 | 16 | #include 17 | 18 | 19 | void write_color(std::ostream &out, color pixel_color, int samples_per_pixel) { 20 | auto r = pixel_color.x(); 21 | auto g = pixel_color.y(); 22 | auto b = pixel_color.z(); 23 | 24 | // Replace NaN components with zero. See explanation in Ray Tracing: The Rest of Your Life. 25 | if (r != r) r = 0.0; 26 | if (g != g) g = 0.0; 27 | if (b != b) b = 0.0; 28 | 29 | // Divide the color by the number of samples and gamma-correct for gamma=2.0. 30 | auto scale = 1.0 / samples_per_pixel; 31 | r = sqrt(scale * r); 32 | g = sqrt(scale * g); 33 | b = sqrt(scale * b); 34 | 35 | // Write the translated [0,255] value of each color component. 36 | out << static_cast(256 * clamp(r, 0.0, 0.999)) << ' ' 37 | << static_cast(256 * clamp(g, 0.0, 0.999)) << ' ' 38 | << static_cast(256 * clamp(b, 0.0, 0.999)) << '\n'; 39 | } 40 | 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/common/rtweekend.h: -------------------------------------------------------------------------------- 1 | #ifndef RTWEEKEND_H 2 | #define RTWEEKEND_H 3 | //============================================================================================== 4 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 5 | // neighboring rights to this software to the public domain worldwide. This software is 6 | // distributed without any warranty. 7 | // 8 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 9 | // along with this software. If not, see . 10 | //============================================================================================== 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | // Usings 19 | 20 | using std::shared_ptr; 21 | using std::make_shared; 22 | using std::sqrt; 23 | 24 | // Constants 25 | 26 | const double infinity = std::numeric_limits::infinity(); 27 | const double pi = 3.1415926535897932385; 28 | 29 | // Utility Functions 30 | 31 | inline double degrees_to_radians(double degrees) { 32 | return degrees * pi / 180.0; 33 | } 34 | 35 | inline double clamp(double x, double min, double max) { 36 | if (x < min) return min; 37 | if (x > max) return max; 38 | return x; 39 | } 40 | 41 | inline double random_double() { 42 | return rand() / (RAND_MAX + 1.0); 43 | } 44 | 45 | inline double random_double(double min, double max) { 46 | // Returns a random real in [min,max). 47 | return min + (max-min)*random_double(); 48 | } 49 | 50 | inline int random_int(int min, int max) { 51 | // Returns a random integer in [min,max]. 52 | return static_cast(random_double(min, max+1)); 53 | } 54 | 55 | // Common Headers 56 | 57 | #include "ray.h" 58 | #include "vec3.h" 59 | 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/pi.cc: -------------------------------------------------------------------------------- 1 | //============================================================================================== 2 | // Originally written in 2016 by Peter Shirley 3 | // 4 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 5 | // neighboring rights to this software to the public domain worldwide. This software is 6 | // distributed without any warranty. 7 | // 8 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 9 | // along with this software. If not, see . 10 | //============================================================================================== 11 | 12 | #include "rtweekend.h" 13 | 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | 20 | int main() { 21 | int inside_circle = 0; 22 | int inside_circle_stratified = 0; 23 | int sqrt_N = 10000; 24 | 25 | for (int i = 0; i < sqrt_N; i++) { 26 | for (int j = 0; j < sqrt_N; j++) { 27 | auto x = random_double(-1,1); 28 | auto y = random_double(-1,1); 29 | 30 | if (x*x + y*y < 1) 31 | inside_circle++; 32 | 33 | x = 2*((i + random_double()) / sqrt_N) - 1; 34 | y = 2*((j + random_double()) / sqrt_N) - 1; 35 | 36 | if (x*x + y*y < 1) 37 | inside_circle_stratified++; 38 | } 39 | } 40 | 41 | auto N = static_cast(sqrt_N) * sqrt_N; 42 | std::cout << std::fixed << std::setprecision(12); 43 | std::cout << "Regular Estimate of Pi = " 44 | << 4 * double(inside_circle) / (sqrt_N*sqrt_N) << '\n'; 45 | std::cout << "Stratified Estimate of Pi = " 46 | << 4 * double(inside_circle_stratified) / (sqrt_N*sqrt_N) << '\n'; 47 | } 48 | -------------------------------------------------------------------------------- /src/InOneWeekend/hittable_list.h: -------------------------------------------------------------------------------- 1 | #ifndef HITTABLE_LIST_H 2 | #define HITTABLE_LIST_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "hittable.h" 17 | 18 | #include 19 | #include 20 | 21 | 22 | class hittable_list: public hittable { 23 | public: 24 | hittable_list() {} 25 | hittable_list(shared_ptr object) { add(object); } 26 | 27 | void clear() { objects.clear(); } 28 | void add(shared_ptr object) { objects.push_back(object); } 29 | 30 | virtual bool hit(const ray& r, double tmin, double tmax, hit_record& rec) const; 31 | 32 | public: 33 | std::vector> objects; 34 | }; 35 | 36 | 37 | bool hittable_list::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 38 | hit_record temp_rec; 39 | auto hit_anything = false; 40 | auto closest_so_far = t_max; 41 | 42 | for (const auto& object : objects) { 43 | if (object->hit(r, t_min, closest_so_far, temp_rec)) { 44 | hit_anything = true; 45 | closest_so_far = temp_rec.t; 46 | rec = temp_rec; 47 | } 48 | } 49 | 50 | return hit_anything; 51 | } 52 | 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /books/acknowledgments.md.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Acknowledgments 5 | ==================================================================================================== 6 | 7 |
**Original Manuscript Help** 8 | 9 | - Dave Hart 10 | - Jean Buckley 11 |
12 | 13 |
**Web Release** 14 | 15 | - Berna Kabadayı 16 | - Lorenzo Mancini 17 | - Lori Whippler Hollasch 18 | - Ronald Wotzlaw 19 |
20 | 21 |
**Corrections and Improvements** 22 | 23 | - Aaryaman Vasishta 24 | - Andrew Kensler 25 | - Apoorva Joshi 26 | - Aras Pranckevičius 27 | - Becker 28 | - Ben Kerl 29 | - Benjamin Summerton 30 | - Bennett Hardwick 31 | - Dan Drummond 32 | - David Chambers 33 | - David Hart 34 | - Eric Haines 35 | - Fabio Sancinetti 36 | - Filipe Scur 37 | - Frank He 38 | - Gerrit Wessendorf 39 | - Grue Debry 40 | - Ingo Wald 41 | - Jason Stone 42 | - Jean Buckley 43 | - Joey Cho 44 | - Lorenzo Mancini 45 | - Marcus Ottosson 46 | - Matthew Heimlich 47 | - Nakata Daisuke 48 | - Paul Melis 49 | - Phil Cristensen 50 | - Ronald Wotzlaw 51 | - Shaun P. Lee 52 | - Tatsuya Ogawa 53 | - Thiago Ize 54 | - Vahan Sosoyan 55 | - ZeHao Chen 56 |
57 | 58 |
**Tools** 59 | 60 |
61 | Thanks to the team at [Limnu](https://limnu.com/) for help on the figures. 62 | 63 | These books are entirely written in Morgan McGuire's fantastic and free 64 | [Markdeep](https://casual-effects.com/markdeep/) library. To see what this looks like, view the 65 | page source from your browser. 66 | 67 |
68 |
69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /src/InOneWeekend/README.md: -------------------------------------------------------------------------------- 1 | Ray Tracing in One Weekend - Source 2 | ==================================================================================================== 3 | 4 | Content 5 | -------- 6 | This folder contains the finished code for _Ray Tracing in One Weekend_ ([local][] / [online][]). 7 | 8 | 9 | Intent 10 | ------- 11 | This folder is not meant to act as its own tutorial. The source presented here is provided so you 12 | can compare your work when progressing through the book. We strongly recommend reading and following 13 | along with the book to understand the source. 14 | 15 | 16 | Programming Language 17 | --------------------- 18 | This book is written in C++, and uses some modern features of C++11. The language and features were 19 | chosen to be broadly understood by the largest collection of programmers. It is not meant to 20 | represent ideal C++ code. 21 | 22 | 23 | Building 24 | --------- 25 | As the source is intended for illustration & comparison only, it does not include any mechanism for 26 | building a final program. As far as possible, the code is privately tested on multiple platforms to 27 | ensure that it is generally usable on any OS (primarily Windows, OSX, and Linux), compiler, or build 28 | environment. 29 | 30 | It is therefore necessary for you to create your own build tooling. However, the source begins as a 31 | single main file, and uses only a small collection of additional header files. 32 | 33 | The _Ray Tracing in One Weekend_ series has a long history of implementations in other programming 34 | languages (see [_Implementations in Other Languages_][implementations]), and across all three 35 | primary operating systems. Feel free to add your own implementation to the list! 36 | 37 | 38 | Corrections & Contributions 39 | ---------------------------- 40 | If you spot errors, have suggested corrections, or would like to help out with the project, please 41 | review the [CONTRIBUTING][] guidelines for the most effective way to proceed. 42 | 43 | 44 | 45 | [online]: https://raytracing.github.com/books/RayTracingInOneWeekend.html 46 | [local]: ../../books/RayTracingInOneWeekend.html 47 | [implementations]: https://github.com/RayTracing/raytracing.github.io/wiki/Implementations-in-Other-Languages 48 | [CONTRIBUTING]: ../../CONTRIBUTING.md 49 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/README.md: -------------------------------------------------------------------------------- 1 | Ray Tracing: The Rest Of Your Life - Source 2 | ==================================================================================================== 3 | 4 | Content 5 | -------- 6 | This folder contains the finished code for _Ray Tracing: The Rest Of Your Life_ ([local][] / 7 | [online][]). 8 | 9 | 10 | Intent 11 | ------- 12 | This folder is not meant to act as its own tutorial. The source presented here is provided so you 13 | can compare your work when progressing through the book. We strongly recommend reading and following 14 | along with the book to understand the source. 15 | 16 | 17 | Programming Language 18 | --------------------- 19 | This book is written in C++, and uses some modern features of C++11. The language and features were 20 | chosen to be broadly understood by the largest collection of programmers. It is not meant to 21 | represent ideal C++ code. 22 | 23 | 24 | Building 25 | --------- 26 | As the source is intended for illustration & comparison only, it does not include any mechanism for 27 | building a final program. As far as possible, the code is privately tested on multiple platforms to 28 | ensure that it is generally usable on any OS (primarily Windows, OSX, and Linux), compiler, or build 29 | environment. 30 | 31 | It is therefore necessary for you to create your own build tooling. However, the source begins as a 32 | single main file, and uses only a small collection of additional header files. 33 | 34 | The _Ray Tracing in One Weekend_ series has a long history of implementations in other programming 35 | languages (see [_Implementations in Other Languages_][implementations]), and across all three 36 | primary operating systems. Feel free to add your own implementation to the list! 37 | 38 | 39 | Corrections & Contributions 40 | ---------------------------- 41 | If you spot errors, have suggested corrections, or would like to help out with the project, please 42 | review the [CONTRIBUTING][] guidelines for the most effective way to proceed. 43 | 44 | 45 | 46 | [online]: https://raytracing.github.com/books/RayTracingTheRestOfYourLife.html 47 | [local]: ../../books/RayTracingTheRestOfYourLife.html 48 | [implementations]: https://github.com/RayTracing/raytracing.github.io/wiki/Implementations-in-Other-Languages 49 | [CONTRIBUTING]: ../../CONTRIBUTING.md 50 | -------------------------------------------------------------------------------- /src/TheNextWeek/box.h: -------------------------------------------------------------------------------- 1 | #ifndef BOX_H 2 | #define BOX_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "aarect.h" 17 | #include "hittable_list.h" 18 | 19 | 20 | class box: public hittable { 21 | public: 22 | box() {} 23 | box(const point3& p0, const point3& p1, shared_ptr ptr); 24 | 25 | virtual bool hit(const ray& r, double t0, double t1, hit_record& rec) const; 26 | 27 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const { 28 | output_box = aabb(box_min, box_max); 29 | return true; 30 | } 31 | 32 | public: 33 | point3 box_min; 34 | point3 box_max; 35 | hittable_list sides; 36 | }; 37 | 38 | 39 | box::box(const point3& p0, const point3& p1, shared_ptr ptr) { 40 | box_min = p0; 41 | box_max = p1; 42 | 43 | sides.add(make_shared(p0.x(), p1.x(), p0.y(), p1.y(), p1.z(), ptr)); 44 | sides.add(make_shared( 45 | make_shared(p0.x(), p1.x(), p0.y(), p1.y(), p0.z(), ptr))); 46 | 47 | sides.add(make_shared(p0.x(), p1.x(), p0.z(), p1.z(), p1.y(), ptr)); 48 | sides.add(make_shared( 49 | make_shared(p0.x(), p1.x(), p0.z(), p1.z(), p0.y(), ptr))); 50 | 51 | sides.add(make_shared(p0.y(), p1.y(), p0.z(), p1.z(), p1.x(), ptr)); 52 | sides.add(make_shared( 53 | make_shared(p0.y(), p1.y(), p0.z(), p1.z(), p0.x(), ptr))); 54 | } 55 | 56 | bool box::hit(const ray& r, double t0, double t1, hit_record& rec) const { 57 | return sides.hit(r, t0, t1, rec); 58 | } 59 | 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/box.h: -------------------------------------------------------------------------------- 1 | #ifndef BOX_H 2 | #define BOX_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "aarect.h" 17 | #include "hittable_list.h" 18 | 19 | 20 | class box: public hittable { 21 | public: 22 | box() {} 23 | box(const point3& p0, const point3& p1, shared_ptr ptr); 24 | 25 | virtual bool hit(const ray& r, double t0, double t1, hit_record& rec) const; 26 | 27 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const { 28 | output_box = aabb(box_min, box_max); 29 | return true; 30 | } 31 | 32 | public: 33 | point3 box_min; 34 | point3 box_max; 35 | hittable_list sides; 36 | }; 37 | 38 | 39 | box::box(const point3& p0, const point3& p1, shared_ptr ptr) { 40 | box_min = p0; 41 | box_max = p1; 42 | 43 | sides.add(make_shared(p0.x(), p1.x(), p0.y(), p1.y(), p1.z(), ptr)); 44 | sides.add(make_shared( 45 | make_shared(p0.x(), p1.x(), p0.y(), p1.y(), p0.z(), ptr))); 46 | 47 | sides.add(make_shared(p0.x(), p1.x(), p0.z(), p1.z(), p1.y(), ptr)); 48 | sides.add(make_shared( 49 | make_shared(p0.x(), p1.x(), p0.z(), p1.z(), p0.y(), ptr))); 50 | 51 | sides.add(make_shared(p0.y(), p1.y(), p0.z(), p1.z(), p1.x(), ptr)); 52 | sides.add(make_shared( 53 | make_shared(p0.y(), p1.y(), p0.z(), p1.z(), p0.x(), ptr))); 54 | } 55 | 56 | bool box::hit(const ray& r, double t0, double t1, hit_record& rec) const { 57 | return sides.hit(r, t0, t1, rec); 58 | } 59 | 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/TheNextWeek/hittable_list.h: -------------------------------------------------------------------------------- 1 | #ifndef HITTABLE_LIST_H 2 | #define HITTABLE_LIST_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "hittable.h" 17 | 18 | #include 19 | 20 | 21 | class hittable_list: public hittable { 22 | public: 23 | hittable_list() {} 24 | hittable_list(shared_ptr object) { add(object); } 25 | 26 | void clear() { objects.clear(); } 27 | void add(shared_ptr object) { objects.push_back(object); } 28 | 29 | virtual bool hit(const ray& r, double tmin, double tmax, hit_record& rec) const; 30 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const; 31 | 32 | public: 33 | std::vector> objects; 34 | }; 35 | 36 | 37 | bool hittable_list::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 38 | hit_record temp_rec; 39 | auto hit_anything = false; 40 | auto closest_so_far = t_max; 41 | 42 | for (const auto& object : objects) { 43 | if (object->hit(r, t_min, closest_so_far, temp_rec)) { 44 | hit_anything = true; 45 | closest_so_far = temp_rec.t; 46 | rec = temp_rec; 47 | } 48 | } 49 | 50 | return hit_anything; 51 | } 52 | 53 | 54 | bool hittable_list::bounding_box(double t0, double t1, aabb& output_box) const { 55 | if (objects.empty()) return false; 56 | 57 | aabb temp_box; 58 | bool first_box = true; 59 | 60 | for (const auto& object : objects) { 61 | if (!object->bounding_box(t0, t1, temp_box)) return false; 62 | output_box = first_box ? temp_box : surrounding_box(output_box, temp_box); 63 | first_box = false; 64 | } 65 | 66 | return true; 67 | } 68 | 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/InOneWeekend/sphere.h: -------------------------------------------------------------------------------- 1 | #ifndef SPHERE_H 2 | #define SPHERE_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "hittable.h" 17 | 18 | 19 | class sphere: public hittable { 20 | public: 21 | sphere() {} 22 | 23 | sphere(point3 cen, double r, shared_ptr m) 24 | : center(cen), radius(r), mat_ptr(m) {}; 25 | 26 | virtual bool hit(const ray& r, double tmin, double tmax, hit_record& rec) const; 27 | 28 | public: 29 | point3 center; 30 | double radius; 31 | shared_ptr mat_ptr; 32 | }; 33 | 34 | 35 | bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 36 | vec3 oc = r.origin() - center; 37 | auto a = r.direction().length_squared(); 38 | auto half_b = dot(oc, r.direction()); 39 | auto c = oc.length_squared() - radius*radius; 40 | auto discriminant = half_b*half_b - a*c; 41 | 42 | if (discriminant > 0) { 43 | auto root = sqrt(discriminant); 44 | 45 | auto temp = (-half_b - root)/a; 46 | if (temp < t_max && temp > t_min) { 47 | rec.t = temp; 48 | rec.p = r.at(rec.t); 49 | vec3 outward_normal = (rec.p - center) / radius; 50 | rec.set_face_normal(r, outward_normal); 51 | rec.mat_ptr = mat_ptr; 52 | return true; 53 | } 54 | 55 | temp = (-half_b + root) / a; 56 | if (temp < t_max && temp > t_min) { 57 | rec.t = temp; 58 | rec.p = r.at(rec.t); 59 | vec3 outward_normal = (rec.p - center) / radius; 60 | rec.set_face_normal(r, outward_normal); 61 | rec.mat_ptr = mat_ptr; 62 | return true; 63 | } 64 | } 65 | return false; 66 | } 67 | 68 | #endif 69 | -------------------------------------------------------------------------------- /src/TheNextWeek/README.md: -------------------------------------------------------------------------------- 1 | Ray Tracing: The Next Week - Source 2 | ==================================================================================================== 3 | 4 | Content 5 | -------- 6 | This folder contains the finished code for _Ray Tracing: The Next Week_ ([local][] / [online][]). 7 | 8 | Every chapter of the book acts as its own mini tutorial, and each chapter is largely independent of 9 | other chapters. Every chapter ends with an example render, and in the source, [main.cc][] contains a 10 | render function specific to each chapter. The source presented here represents the simplest superset 11 | of the code from all chapters. 12 | 13 | 14 | Intent 15 | ------- 16 | This folder is not meant to act as its own tutorial. The source presented here is provided so you 17 | can compare your work when progressing through the book. We strongly recommend reading and following 18 | along with the book to understand the source. 19 | 20 | 21 | Programming Language 22 | --------------------- 23 | This book is written in C++, and uses some modern features of C++11. The language and features were 24 | chosen to be broadly understood by the largest collection of programmers. It is not meant to 25 | represent ideal C++ code. 26 | 27 | 28 | Building 29 | --------- 30 | As the source is intended for illustration & comparison only, it does not include any mechanism for 31 | building a final program. As far as possible, the code is privately tested on multiple platforms to 32 | ensure that it is generally usable on any OS (primarily Windows, OSX, and Linux), compiler, or build 33 | environment. 34 | 35 | It is therefore necessary for you to create your own build tooling. However, the source begins as a 36 | single main file, and uses only a small collection of additional header files. 37 | 38 | The _Ray Tracing in One Weekend_ series has a long history of implementations in other programming 39 | languages (see [_Implementations in Other Languages_][implementations]), and across all three 40 | primary operating systems. Feel free to add your own implementation to the list! 41 | 42 | 43 | Corrections & Contributions 44 | ---------------------------- 45 | If you spot errors, have suggested corrections, or would like to help out with the project, please 46 | review the [CONTRIBUTING][] guidelines for the most effective way to proceed. 47 | 48 | 49 | 50 | [online]: https://raytracing.github.com/books/RayTracingTheNextWeek.html 51 | [local]: ../../books/RayTracingTheNextWeek.html 52 | [main.cc]: ./main.cc 53 | [implementations]: https://github.com/RayTracing/raytracing.github.io/wiki/Implementations-in-Other-Languages 54 | [CONTRIBUTING]: ../../CONTRIBUTING.md 55 | -------------------------------------------------------------------------------- /src/common/camera.h: -------------------------------------------------------------------------------- 1 | #ifndef CAMERA_H 2 | #define CAMERA_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | 17 | class camera { 18 | public: 19 | camera() : camera(point3(0,0,-1), point3(0,0,0), vec3(0,1,0), 40, 1, 0, 10) {} 20 | 21 | camera( 22 | point3 lookfrom, point3 lookat, vec3 vup, 23 | double vfov, // vertical field-of-view in degrees 24 | double aspect_ratio, double aperture, double focus_dist, 25 | double t0 = 0, double t1 = 0 26 | ) { 27 | origin = lookfrom; 28 | lens_radius = aperture / 2; 29 | time0 = t0; 30 | time1 = t1; 31 | 32 | auto theta = degrees_to_radians(vfov); 33 | auto half_height = tan(theta/2); 34 | auto half_width = aspect_ratio * half_height; 35 | 36 | w = unit_vector(lookfrom - lookat); 37 | u = unit_vector(cross(vup, w)); 38 | v = cross(w, u); 39 | 40 | lower_left_corner = origin 41 | - half_width*focus_dist*u 42 | - half_height*focus_dist*v 43 | - focus_dist*w; 44 | 45 | horizontal = 2*half_width*focus_dist*u; 46 | vertical = 2*half_height*focus_dist*v; 47 | } 48 | 49 | ray get_ray(double s, double t) const { 50 | vec3 rd = lens_radius * random_in_unit_disk(); 51 | vec3 offset = u * rd.x() + v * rd.y(); 52 | return ray( 53 | origin + offset, 54 | lower_left_corner + s*horizontal + t*vertical - origin - offset, 55 | random_double(time0, time1) 56 | ); 57 | } 58 | 59 | private: 60 | point3 origin; 61 | point3 lower_left_corner; 62 | vec3 horizontal; 63 | vec3 vertical; 64 | vec3 u, v, w; 65 | double lens_radius; 66 | double time0, time1; // shutter open/close times 67 | }; 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #--------------------------------------------------------------------------------------------------- 2 | # CMake Build Configuration for the Ray Tracing Weekend Series 3 | # 4 | # See README.md for guidance. 5 | #--------------------------------------------------------------------------------------------------- 6 | 7 | cmake_minimum_required ( VERSION 3.1.0 ) 8 | 9 | project ( RTWeekend 10 | VERSION 3.0.0 11 | LANGUAGES CXX 12 | ) 13 | 14 | # Set to c++11 15 | set ( CMAKE_CXX_STANDARD 11 ) 16 | 17 | # Source 18 | set ( COMMON_ALL 19 | src/common/rtweekend.h 20 | src/common/camera.h 21 | src/common/ray.h 22 | src/common/vec3.h 23 | ) 24 | 25 | set ( SOURCE_ONE_WEEKEND 26 | ${COMMON_ALL} 27 | src/InOneWeekend/hittable.h 28 | src/InOneWeekend/hittable_list.h 29 | src/InOneWeekend/material.h 30 | src/InOneWeekend/sphere.h 31 | src/InOneWeekend/main.cc 32 | ) 33 | 34 | set ( SOURCE_NEXT_WEEK 35 | ${COMMON_ALL} 36 | src/common/aabb.h 37 | src/common/external/stb_image.h 38 | src/common/perlin.h 39 | src/common/rtw_stb_image.h 40 | src/common/texture.h 41 | src/TheNextWeek/aarect.h 42 | src/TheNextWeek/box.h 43 | src/TheNextWeek/bvh.h 44 | src/TheNextWeek/constant_medium.h 45 | src/TheNextWeek/hittable.h 46 | src/TheNextWeek/hittable_list.h 47 | src/TheNextWeek/material.h 48 | src/TheNextWeek/moving_sphere.h 49 | src/TheNextWeek/sphere.h 50 | src/TheNextWeek/main.cc 51 | ) 52 | 53 | set ( SOURCE_REST_OF_YOUR_LIFE 54 | ${COMMON_ALL} 55 | src/common/aabb.h 56 | src/common/external/stb_image.h 57 | src/common/perlin.h 58 | src/common/rtw_stb_image.h 59 | src/common/texture.h 60 | src/TheRestOfYourLife/aarect.h 61 | src/TheRestOfYourLife/box.h 62 | src/TheRestOfYourLife/bvh.h 63 | src/TheRestOfYourLife/hittable.h 64 | src/TheRestOfYourLife/hittable_list.h 65 | src/TheRestOfYourLife/material.h 66 | src/TheRestOfYourLife/onb.h 67 | src/TheRestOfYourLife/pdf.h 68 | src/TheRestOfYourLife/sphere.h 69 | src/TheRestOfYourLife/main.cc 70 | ) 71 | 72 | # Executables 73 | add_executable(inOneWeekend ${SOURCE_ONE_WEEKEND}) 74 | add_executable(theNextWeek ${SOURCE_NEXT_WEEK}) 75 | add_executable(theRestOfYourLife ${SOURCE_REST_OF_YOUR_LIFE}) 76 | add_executable(cos_cubed src/TheRestOfYourLife/cos_cubed.cc ${COMMON_ALL}) 77 | add_executable(cos_density src/TheRestOfYourLife/cos_density.cc ${COMMON_ALL}) 78 | add_executable(integrate_x_sq src/TheRestOfYourLife/integrate_x_sq.cc ${COMMON_ALL}) 79 | add_executable(pi src/TheRestOfYourLife/pi.cc ${COMMON_ALL}) 80 | add_executable(sphere_importance src/TheRestOfYourLife/sphere_importance.cc ${COMMON_ALL}) 81 | add_executable(sphere_plot src/TheRestOfYourLife/sphere_plot.cc ${COMMON_ALL}) 82 | 83 | include_directories(src/common) 84 | -------------------------------------------------------------------------------- /src/common/aabb.h: -------------------------------------------------------------------------------- 1 | #ifndef AABB_H 2 | #define AABB_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | 17 | class aabb { 18 | public: 19 | aabb() {} 20 | aabb(const point3& a, const point3& b) { _min = a; _max = b; } 21 | 22 | point3 min() const {return _min; } 23 | point3 max() const {return _max; } 24 | 25 | bool hit(const ray& r, double tmin, double tmax) const { 26 | for (int a = 0; a < 3; a++) { 27 | auto t0 = fmin((_min[a] - r.origin()[a]) / r.direction()[a], 28 | (_max[a] - r.origin()[a]) / r.direction()[a]); 29 | auto t1 = fmax((_min[a] - r.origin()[a]) / r.direction()[a], 30 | (_max[a] - r.origin()[a]) / r.direction()[a]); 31 | tmin = fmax(t0, tmin); 32 | tmax = fmin(t1, tmax); 33 | if (tmax <= tmin) 34 | return false; 35 | } 36 | return true; 37 | } 38 | 39 | double area() const { 40 | auto a = _max.x() - _min.x(); 41 | auto b = _max.y() - _min.y(); 42 | auto c = _max.z() - _min.z(); 43 | return 2*(a*b + b*c + c*a); 44 | } 45 | 46 | int longest_axis() const { 47 | auto a = _max.x() - _min.x(); 48 | auto b = _max.y() - _min.y(); 49 | auto c = _max.z() - _min.z(); 50 | if (a > b && a > c) 51 | return 0; 52 | else if (b > c) 53 | return 1; 54 | else 55 | return 2; 56 | } 57 | 58 | public: 59 | point3 _min; 60 | point3 _max; 61 | }; 62 | 63 | aabb surrounding_box(aabb box0, aabb box1) { 64 | vec3 small(fmin(box0.min().x(), box1.min().x()), 65 | fmin(box0.min().y(), box1.min().y()), 66 | fmin(box0.min().z(), box1.min().z())); 67 | 68 | vec3 big (fmax(box0.max().x(), box1.max().x()), 69 | fmax(box0.max().y(), box1.max().y()), 70 | fmax(box0.max().z(), box1.max().z())); 71 | 72 | return aabb(small,big); 73 | } 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/TheNextWeek/sphere.h: -------------------------------------------------------------------------------- 1 | #ifndef SPHERE_H 2 | #define SPHERE_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "hittable.h" 17 | 18 | 19 | class sphere: public hittable { 20 | public: 21 | sphere() {} 22 | sphere(point3 cen, double r, shared_ptr m) 23 | : center(cen), radius(r), mat_ptr(m) {}; 24 | virtual bool hit(const ray& r, double tmin, double tmax, hit_record& rec) const; 25 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const; 26 | 27 | public: 28 | point3 center; 29 | double radius; 30 | shared_ptr mat_ptr; 31 | }; 32 | 33 | 34 | bool sphere::bounding_box(double t0, double t1, aabb& output_box) const { 35 | output_box = aabb( 36 | center - vec3(radius, radius, radius), 37 | center + vec3(radius, radius, radius)); 38 | return true; 39 | } 40 | 41 | bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 42 | vec3 oc = r.origin() - center; 43 | auto a = r.direction().length_squared(); 44 | auto half_b = dot(oc, r.direction()); 45 | auto c = oc.length_squared() - radius*radius; 46 | 47 | auto discriminant = half_b*half_b - a*c; 48 | 49 | if (discriminant > 0) { 50 | auto root = sqrt(discriminant); 51 | 52 | auto temp = (-half_b - root)/a; 53 | if (temp < t_max && temp > t_min) { 54 | rec.t = temp; 55 | rec.p = r.at(rec.t); 56 | vec3 outward_normal = (rec.p - center) / radius; 57 | rec.set_face_normal(r, outward_normal); 58 | get_sphere_uv((rec.p-center)/radius, rec.u, rec.v); 59 | rec.mat_ptr = mat_ptr; 60 | return true; 61 | } 62 | 63 | temp = (-half_b + root)/a; 64 | if (temp < t_max && temp > t_min) { 65 | rec.t = temp; 66 | rec.p = r.at(rec.t); 67 | vec3 outward_normal = (rec.p - center) / radius; 68 | rec.set_face_normal(r, outward_normal); 69 | get_sphere_uv((rec.p-center)/radius, rec.u, rec.v); 70 | rec.mat_ptr = mat_ptr; 71 | return true; 72 | } 73 | } 74 | 75 | return false; 76 | } 77 | 78 | #endif 79 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/hittable_list.h: -------------------------------------------------------------------------------- 1 | #ifndef HITTABLE_LIST_H 2 | #define HITTABLE_LIST_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "hittable.h" 17 | 18 | #include 19 | 20 | 21 | class hittable_list: public hittable { 22 | public: 23 | hittable_list() {} 24 | hittable_list(shared_ptr object) { add(object); } 25 | 26 | void clear() { objects.clear(); } 27 | void add(shared_ptr object) { objects.push_back(object); } 28 | 29 | virtual bool hit(const ray& r, double tmin, double tmax, hit_record& rec) const; 30 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const; 31 | virtual double pdf_value(const vec3 &o, const vec3 &v) const; 32 | virtual vec3 random(const vec3 &o) const; 33 | 34 | public: 35 | std::vector> objects; 36 | }; 37 | 38 | 39 | bool hittable_list::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 40 | hit_record temp_rec; 41 | auto hit_anything = false; 42 | auto closest_so_far = t_max; 43 | 44 | for (const auto& object : objects) { 45 | if (object->hit(r, t_min, closest_so_far, temp_rec)) { 46 | hit_anything = true; 47 | closest_so_far = temp_rec.t; 48 | rec = temp_rec; 49 | } 50 | } 51 | 52 | return hit_anything; 53 | } 54 | 55 | 56 | bool hittable_list::bounding_box(double t0, double t1, aabb& output_box) const { 57 | if (objects.empty()) return false; 58 | 59 | aabb temp_box; 60 | bool first_true = objects[0]->bounding_box(t0, t1, temp_box); 61 | 62 | if (!first_true) 63 | return false; 64 | 65 | output_box = temp_box; 66 | 67 | for (const auto& object : objects) { 68 | if (!object->bounding_box(t0, t1, temp_box)) 69 | return false; 70 | output_box = surrounding_box(output_box, temp_box); 71 | } 72 | 73 | return true; 74 | } 75 | 76 | 77 | double hittable_list::pdf_value(const point3& o, const vec3& v) const { 78 | auto weight = 1.0/objects.size(); 79 | auto sum = 0.0; 80 | 81 | for (const auto& object : objects) 82 | sum += weight * object->pdf_value(o, v); 83 | 84 | return sum; 85 | } 86 | 87 | 88 | vec3 hittable_list::random(const vec3 &o) const { 89 | auto int_size = static_cast(objects.size()); 90 | return objects[random_int(0, int_size-1)]->random(o); 91 | } 92 | 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /src/TheNextWeek/constant_medium.h: -------------------------------------------------------------------------------- 1 | #ifndef CONSTANT_MEDIUM_H 2 | #define CONSTANT_MEDIUM_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "hittable.h" 17 | #include "material.h" 18 | #include "texture.h" 19 | 20 | 21 | class constant_medium : public hittable { 22 | public: 23 | constant_medium(shared_ptr b, double d, shared_ptr a) 24 | : boundary(b), neg_inv_density(-1/d) 25 | { 26 | phase_function = make_shared(a); 27 | } 28 | 29 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const; 30 | 31 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const { 32 | return boundary->bounding_box(t0, t1, output_box); 33 | } 34 | 35 | public: 36 | shared_ptr boundary; 37 | shared_ptr phase_function; 38 | double neg_inv_density; 39 | }; 40 | 41 | 42 | bool constant_medium::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 43 | // Print occasional samples when debugging. To enable, set enableDebug true. 44 | const bool enableDebug = false; 45 | const bool debugging = enableDebug && random_double() < 0.00001; 46 | 47 | hit_record rec1, rec2; 48 | 49 | if (!boundary->hit(r, -infinity, infinity, rec1)) 50 | return false; 51 | 52 | if (!boundary->hit(r, rec1.t+0.0001, infinity, rec2)) 53 | return false; 54 | 55 | if (debugging) std::cerr << "\nt0=" << rec1.t << ", t1=" << rec2.t << '\n'; 56 | 57 | if (rec1.t < t_min) rec1.t = t_min; 58 | if (rec2.t > t_max) rec2.t = t_max; 59 | 60 | if (rec1.t >= rec2.t) 61 | return false; 62 | 63 | if (rec1.t < 0) 64 | rec1.t = 0; 65 | 66 | const auto ray_length = r.direction().length(); 67 | const auto distance_inside_boundary = (rec2.t - rec1.t) * ray_length; 68 | const auto hit_distance = neg_inv_density * log(random_double()); 69 | 70 | if (hit_distance > distance_inside_boundary) 71 | return false; 72 | 73 | rec.t = rec1.t + hit_distance / ray_length; 74 | rec.p = r.at(rec.t); 75 | 76 | if (debugging) { 77 | std::cerr << "hit_distance = " << hit_distance << '\n' 78 | << "rec.t = " << rec.t << '\n' 79 | << "rec.p = " << rec.p << '\n'; 80 | } 81 | 82 | rec.normal = vec3(1,0,0); // arbitrary 83 | rec.front_face = true; // also arbitrary 84 | rec.mat_ptr = phase_function; 85 | 86 | return true; 87 | } 88 | 89 | #endif 90 | -------------------------------------------------------------------------------- /src/TheNextWeek/moving_sphere.h: -------------------------------------------------------------------------------- 1 | #ifndef MOVING_SPHERE_H 2 | #define MOVING_SPHERE_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "hittable.h" 17 | 18 | 19 | class moving_sphere : public hittable { 20 | public: 21 | moving_sphere() {} 22 | moving_sphere( 23 | point3 cen0, point3 cen1, double t0, double t1, double r, shared_ptr m) 24 | : center0(cen0), center1(cen1), time0(t0), time1(t1), radius(r), mat_ptr(m) 25 | {}; 26 | 27 | virtual bool hit(const ray& r, double tmin, double tmax, hit_record& rec) const; 28 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const; 29 | 30 | point3 center(double time) const; 31 | 32 | public: 33 | point3 center0, center1; 34 | double time0, time1; 35 | double radius; 36 | shared_ptr mat_ptr; 37 | }; 38 | 39 | 40 | point3 moving_sphere::center(double time) const{ 41 | return center0 + ((time - time0) / (time1 - time0))*(center1 - center0); 42 | } 43 | 44 | 45 | bool moving_sphere::bounding_box(double t0, double t1, aabb& output_box) const { 46 | aabb box0( 47 | center(t0) - vec3(radius, radius, radius), 48 | center(t0) + vec3(radius, radius, radius)); 49 | aabb box1( 50 | center(t1) - vec3(radius, radius, radius), 51 | center(t1) + vec3(radius, radius, radius)); 52 | output_box = surrounding_box(box0, box1); 53 | return true; 54 | } 55 | 56 | 57 | // replace "center" with "center(r.time())" 58 | bool moving_sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 59 | vec3 oc = r.origin() - center(r.time()); 60 | auto a = r.direction().length_squared(); 61 | auto half_b = dot(oc, r.direction()); 62 | auto c = oc.length_squared() - radius*radius; 63 | 64 | auto discriminant = half_b*half_b - a*c; 65 | 66 | if (discriminant > 0) { 67 | auto root = sqrt(discriminant); 68 | 69 | auto temp = (-half_b - root)/a; 70 | if (temp < t_max && temp > t_min) { 71 | rec.t = temp; 72 | rec.p = r.at(rec.t); 73 | vec3 outward_normal = (rec.p - center(r.time())) / radius; 74 | rec.set_face_normal(r, outward_normal); 75 | rec.mat_ptr = mat_ptr; 76 | return true; 77 | } 78 | 79 | temp = (-half_b + root)/a; 80 | if (temp < t_max && temp > t_min) { 81 | rec.t = temp; 82 | rec.p = r.at(rec.t); 83 | vec3 outward_normal = (rec.p - center(r.time())) / radius; 84 | rec.set_face_normal(r, outward_normal); 85 | rec.mat_ptr = mat_ptr; 86 | return true; 87 | } 88 | } 89 | 90 | return false; 91 | } 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/pdf.h: -------------------------------------------------------------------------------- 1 | #ifndef PDF_H 2 | #define PDF_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "onb.h" 17 | 18 | 19 | inline vec3 random_cosine_direction() { 20 | auto r1 = random_double(); 21 | auto r2 = random_double(); 22 | auto z = sqrt(1-r2); 23 | 24 | auto phi = 2*pi*r1; 25 | auto x = cos(phi)*sqrt(r2); 26 | auto y = sin(phi)*sqrt(r2); 27 | 28 | return vec3(x, y, z); 29 | } 30 | 31 | 32 | inline vec3 random_to_sphere(double radius, double distance_squared) { 33 | auto r1 = random_double(); 34 | auto r2 = random_double(); 35 | auto z = 1 + r2*(sqrt(1-radius*radius/distance_squared) - 1); 36 | 37 | auto phi = 2*pi*r1; 38 | auto x = cos(phi)*sqrt(1-z*z); 39 | auto y = sin(phi)*sqrt(1-z*z); 40 | 41 | return vec3(x, y, z); 42 | } 43 | 44 | 45 | class pdf { 46 | public: 47 | virtual ~pdf() {} 48 | 49 | virtual double value(const vec3& direction) const = 0; 50 | virtual vec3 generate() const = 0; 51 | }; 52 | 53 | 54 | class cosine_pdf : public pdf { 55 | public: 56 | cosine_pdf(const vec3& w) { uvw.build_from_w(w); } 57 | 58 | virtual double value(const vec3& direction) const { 59 | auto cosine = dot(unit_vector(direction), uvw.w()); 60 | return (cosine <= 0) ? 0 : cosine/pi; 61 | } 62 | 63 | virtual vec3 generate() const { 64 | return uvw.local(random_cosine_direction()); 65 | } 66 | 67 | public: 68 | onb uvw; 69 | }; 70 | 71 | 72 | class hittable_pdf : public pdf { 73 | public: 74 | hittable_pdf(shared_ptr p, const point3& origin) : ptr(p), o(origin) {} 75 | 76 | virtual double value(const vec3& direction) const { 77 | return ptr->pdf_value(o, direction); 78 | } 79 | 80 | virtual vec3 generate() const { 81 | return ptr->random(o); 82 | } 83 | 84 | public: 85 | point3 o; 86 | shared_ptr ptr; 87 | }; 88 | 89 | 90 | class mixture_pdf : public pdf { 91 | public: 92 | mixture_pdf(shared_ptr p0, shared_ptr p1) { 93 | p[0] = p0; 94 | p[1] = p1; 95 | } 96 | 97 | virtual double value(const vec3& direction) const { 98 | return 0.5 * p[0]->value(direction) + 0.5 *p[1]->value(direction); 99 | } 100 | 101 | virtual vec3 generate() const { 102 | if (random_double() < 0.5) 103 | return p[0]->generate(); 104 | else 105 | return p[1]->generate(); 106 | } 107 | 108 | public: 109 | shared_ptr p[2]; 110 | }; 111 | 112 | 113 | #endif 114 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing To The Ray Tracing in One Weekend Series 2 | ==================================================================================================== 3 | 4 | The _Ray Tracing in One Weekend_ series is intended to be lightweight and accessible for all who 5 | want to learn about ray tracing and related graphics topics. To that end, we welcome feedback, 6 | proposals, and improvements. 7 | 8 | In particular, we are now a dedicated GitHub organization. The books are now available in HTML from 9 | https://raytracing.github.io/, so we can keep the content up-to-date with the latest corrections and 10 | improvements. 11 | 12 | 13 | Repository Organization 14 | ------------------------ 15 | This repository has the following organization 16 | 17 | ```bash 18 | raytracing.github.io/ # Repository root 19 | books/ # Book content 20 | images/ # All figures, renderings and other images used throughout the project 21 | src/ # Source code 22 | common/ # Source code that is common to two or more books 23 | InOneWeekend/ # The final form of source code for Ray Tracing in One Weekend 24 | TheNextWeek/ # The final form of source code for Ray Tracing: The Next Week 25 | TheRestOfYourLife/ # The final form of source code for Ray Tracing: The Rest of Your Life 26 | style/ # CSS for books and web site 27 | ``` 28 | 29 | The latest official release can be found in the `master` branch. All ongoing development work (and 30 | all of the latest changes) will be in the `dev-patch`, `dev-minor`, and `dev-major` branches. The 31 | appropriate target branch for any pull requests you want to make will be determined in the 32 | associated issue first (all PRs should have an associated issue). 33 | 34 | 35 | Issues 36 | ------- 37 | The easiest way to help out is to log any issues you find in the books. Unclear passages, errors of 38 | all kinds, even better ways to present something -- just go to the [issues page][]. 39 | 40 | **Before creating a new issue**, please review existing issues to see if someone has already 41 | submitted the same one. Odds are you're not the first to encounter something, so a little quick 42 | research can save everyone some hassle. It's also a good idea to verify that problems still exist in 43 | the `development` branch when creating new issues. 44 | 45 | When entering a new issue, please include all relevant information. For content issues, include the 46 | book or books this applies to, and specific locations that should be reviewed. Similarly for code: 47 | please include the file, function/class, and line number(s) if that applies. 48 | 49 | 50 | Pull Requests 51 | -------------- 52 | To contribute a change to the project, please follow these steps: 53 | 54 | 1. [Create a GitHub issue](https://github.com/RayTracing/raytracing.github.io/issues). 55 | 56 | 2. Participate in the discussion as needed. We'll ensure that the work doesn't conflict with or 57 | duplicate other work planned or in progress, and decide which development branch is correct 58 | for the release type and release schedule. 59 | 60 | 3. Create your changes in a feature branch (or fork) from the assigned development branch 61 | (probably `dev-patch`, `dev-minor`, `dev-major`, or `future`). 62 | 63 | 4. Follow existing code style. 64 | 65 | 5. When ready, create a pull request and request a review from "rt-contributors". 66 | 67 | New to GitHub? We'll walk you through the process above. Just mention that you'd like a little 68 | guidance in the proposal issue. 69 | 70 | 71 | Questions 72 | ---------- 73 | If you have any questions, feel free to ping me at steve@hollasch.net. 74 | 75 | 76 | 77 | [issues page]: https://github.com/RayTracing/raytracing.github.io/issues/ 78 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/sphere.h: -------------------------------------------------------------------------------- 1 | #ifndef SPHERE_H 2 | #define SPHERE_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "hittable.h" 17 | #include "onb.h" 18 | 19 | 20 | class sphere: public hittable { 21 | public: 22 | sphere() {} 23 | sphere(point3 cen, double r, shared_ptr m) 24 | : center(cen), radius(r), mat_ptr(m) {}; 25 | virtual bool hit(const ray& r, double tmin, double tmax, hit_record& rec) const; 26 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const; 27 | virtual double pdf_value(const point3& o, const vec3& v) const; 28 | virtual vec3 random(const point3& o) const; 29 | 30 | public: 31 | point3 center; 32 | double radius; 33 | shared_ptr mat_ptr; 34 | }; 35 | 36 | double sphere::pdf_value(const point3& o, const vec3& v) const { 37 | hit_record rec; 38 | if (!this->hit(ray(o, v), 0.001, infinity, rec)) 39 | return 0; 40 | 41 | auto cos_theta_max = sqrt(1 - radius*radius/(center-o).length_squared()); 42 | auto solid_angle = 2*pi*(1-cos_theta_max); 43 | 44 | return 1 / solid_angle; 45 | } 46 | 47 | vec3 sphere::random(const point3& o) const { 48 | vec3 direction = center - o; 49 | auto distance_squared = direction.length_squared(); 50 | onb uvw; 51 | uvw.build_from_w(direction); 52 | return uvw.local(random_to_sphere(radius, distance_squared)); 53 | } 54 | 55 | 56 | bool sphere::bounding_box(double t0, double t1, aabb& output_box) const { 57 | output_box = aabb( 58 | center - vec3(radius, radius, radius), 59 | center + vec3(radius, radius, radius)); 60 | return true; 61 | } 62 | 63 | bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 64 | vec3 oc = r.origin() - center; 65 | auto a = r.direction().length_squared(); 66 | auto half_b = dot(oc, r.direction()); 67 | auto c = oc.length_squared() - radius*radius; 68 | 69 | auto discriminant = half_b*half_b - a*c; 70 | 71 | if (discriminant > 0) { 72 | auto root = sqrt(discriminant); 73 | 74 | auto temp = (-half_b - root)/a; 75 | if (temp < t_max && temp > t_min) { 76 | rec.t = temp; 77 | rec.p = r.at(rec.t); 78 | vec3 outward_normal = (rec.p - center) / radius; 79 | rec.set_face_normal(r, outward_normal); 80 | get_sphere_uv((rec.p-center)/radius, rec.u, rec.v); 81 | rec.mat_ptr = mat_ptr; 82 | return true; 83 | } 84 | 85 | temp = (-half_b + root)/a; 86 | if (temp < t_max && temp > t_min) { 87 | rec.t = temp; 88 | rec.p = r.at(rec.t); 89 | vec3 outward_normal = (rec.p - center) / radius; 90 | rec.set_face_normal(r, outward_normal); 91 | get_sphere_uv((rec.p-center)/radius, rec.u, rec.v); 92 | rec.mat_ptr = mat_ptr; 93 | return true; 94 | } 95 | } 96 | 97 | return false; 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /src/InOneWeekend/material.h: -------------------------------------------------------------------------------- 1 | #ifndef MATERIAL_H 2 | #define MATERIAL_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | 17 | struct hit_record; 18 | 19 | 20 | double schlick(double cosine, double ref_idx) { 21 | auto r0 = (1-ref_idx) / (1+ref_idx); 22 | r0 = r0*r0; 23 | return r0 + (1-r0)*pow((1 - cosine),5); 24 | } 25 | 26 | 27 | class material { 28 | public: 29 | virtual bool scatter( 30 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 31 | ) const = 0; 32 | }; 33 | 34 | 35 | class dielectric : public material { 36 | public: 37 | dielectric(double ri) : ref_idx(ri) {} 38 | 39 | virtual bool scatter( 40 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 41 | ) const { 42 | attenuation = color(1.0, 1.0, 1.0); 43 | double etai_over_etat = (rec.front_face) ? (1.0 / ref_idx) : (ref_idx); 44 | 45 | vec3 unit_direction = unit_vector(r_in.direction()); 46 | double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0); 47 | double sin_theta = sqrt(1.0 - cos_theta*cos_theta); 48 | if (etai_over_etat * sin_theta > 1.0 ) { 49 | vec3 reflected = reflect(unit_direction, rec.normal); 50 | scattered = ray(rec.p, reflected); 51 | return true; 52 | } 53 | 54 | double reflect_prob = schlick(cos_theta, etai_over_etat); 55 | if (random_double() < reflect_prob) 56 | { 57 | vec3 reflected = reflect(unit_direction, rec.normal); 58 | scattered = ray(rec.p, reflected); 59 | return true; 60 | } 61 | 62 | vec3 refracted = refract(unit_direction, rec.normal, etai_over_etat); 63 | scattered = ray(rec.p, refracted); 64 | return true; 65 | } 66 | 67 | public: 68 | double ref_idx; 69 | }; 70 | 71 | 72 | class lambertian : public material { 73 | public: 74 | lambertian(const color& a) : albedo(a) {} 75 | 76 | virtual bool scatter( 77 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 78 | ) const { 79 | vec3 scatter_direction = rec.normal + random_unit_vector(); 80 | scattered = ray(rec.p, scatter_direction); 81 | attenuation = albedo; 82 | return true; 83 | } 84 | 85 | public: 86 | color albedo; 87 | }; 88 | 89 | 90 | class metal : public material { 91 | public: 92 | metal(const color& a, double f) : albedo(a), fuzz(f < 1 ? f : 1) {} 93 | 94 | virtual bool scatter( 95 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 96 | ) const { 97 | vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal); 98 | scattered = ray(rec.p, reflected + fuzz*random_in_unit_sphere()); 99 | attenuation = albedo; 100 | return (dot(scattered.direction(), rec.normal) > 0); 101 | } 102 | 103 | public: 104 | color albedo; 105 | double fuzz; 106 | }; 107 | 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /src/common/perlin.h: -------------------------------------------------------------------------------- 1 | #ifndef PERLIN_H 2 | #define PERLIN_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | 17 | 18 | class perlin { 19 | public: 20 | perlin() { 21 | ranvec = new vec3[point_count]; 22 | for (int i = 0; i < point_count; ++i) { 23 | ranvec[i] = unit_vector(vec3::random(-1,1)); 24 | } 25 | 26 | perm_x = perlin_generate_perm(); 27 | perm_y = perlin_generate_perm(); 28 | perm_z = perlin_generate_perm(); 29 | } 30 | 31 | ~perlin() { 32 | delete[] ranvec; 33 | delete[] perm_x; 34 | delete[] perm_y; 35 | delete[] perm_z; 36 | } 37 | 38 | double noise(const point3& p) const { 39 | auto u = p.x() - floor(p.x()); 40 | auto v = p.y() - floor(p.y()); 41 | auto w = p.z() - floor(p.z()); 42 | auto i = static_cast(floor(p.x())); 43 | auto j = static_cast(floor(p.y())); 44 | auto k = static_cast(floor(p.z())); 45 | vec3 c[2][2][2]; 46 | 47 | for (int di=0; di < 2; di++) 48 | for (int dj=0; dj < 2; dj++) 49 | for (int dk=0; dk < 2; dk++) 50 | c[di][dj][dk] = ranvec[ 51 | perm_x[(i+di) & 255] ^ 52 | perm_y[(j+dj) & 255] ^ 53 | perm_z[(k+dk) & 255] 54 | ]; 55 | 56 | return perlin_interp(c, u, v, w); 57 | } 58 | 59 | double turb(const point3& p, int depth=7) const { 60 | auto accum = 0.0; 61 | auto temp_p = p; 62 | auto weight = 1.0; 63 | 64 | for (int i = 0; i < depth; i++) { 65 | accum += weight * noise(temp_p); 66 | weight *= 0.5; 67 | temp_p *= 2; 68 | } 69 | 70 | return fabs(accum); 71 | } 72 | 73 | private: 74 | static const int point_count = 256; 75 | vec3* ranvec; 76 | int* perm_x; 77 | int* perm_y; 78 | int* perm_z; 79 | 80 | static int* perlin_generate_perm() { 81 | auto p = new int[point_count]; 82 | 83 | for (int i = 0; i < point_count; i++) 84 | p[i] = i; 85 | 86 | permute(p, point_count); 87 | 88 | return p; 89 | } 90 | 91 | static void permute(int* p, int n) { 92 | for (int i = n-1; i > 0; i--) { 93 | int target = random_int(0,i); 94 | int tmp = p[i]; 95 | p[i] = p[target]; 96 | p[target] = tmp; 97 | } 98 | } 99 | 100 | inline static double perlin_interp(vec3 c[2][2][2], double u, double v, double w) { 101 | auto uu = u*u*(3-2*u); 102 | auto vv = v*v*(3-2*v); 103 | auto ww = w*w*(3-2*w); 104 | auto accum = 0.0; 105 | 106 | for (int i=0; i < 2; i++) 107 | for (int j=0; j < 2; j++) 108 | for (int k=0; k < 2; k++) { 109 | vec3 weight_v(u-i, v-j, w-k); 110 | accum += (i*uu + (1-i)*(1-uu))* 111 | (j*vv + (1-j)*(1-vv))* 112 | (k*ww + (1-k)*(1-ww))*dot(c[i][j][k], weight_v); 113 | } 114 | 115 | return accum; 116 | } 117 | }; 118 | 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /src/TheNextWeek/bvh.h: -------------------------------------------------------------------------------- 1 | #ifndef BVH_H 2 | #define BVH_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "hittable.h" 17 | 18 | #include 19 | 20 | 21 | class bvh_node : public hittable { 22 | public: 23 | bvh_node(); 24 | 25 | bvh_node(hittable_list& list, double time0, double time1) 26 | : bvh_node(list.objects, 0, list.objects.size(), time0, time1) 27 | {} 28 | 29 | bvh_node( 30 | std::vector>& objects, 31 | size_t start, size_t end, double time0, double time1); 32 | 33 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const; 34 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const; 35 | 36 | public: 37 | shared_ptr left; 38 | shared_ptr right; 39 | aabb box; 40 | }; 41 | 42 | 43 | inline bool box_compare(const shared_ptr a, const shared_ptr b, int axis) { 44 | aabb box_a; 45 | aabb box_b; 46 | 47 | if (!a->bounding_box(0,0, box_a) || !b->bounding_box(0,0, box_b)) 48 | std::cerr << "No bounding box in bvh_node constructor.\n"; 49 | 50 | return box_a.min().e[axis] < box_b.min().e[axis]; 51 | } 52 | 53 | 54 | bool box_x_compare (const shared_ptr a, const shared_ptr b) { 55 | return box_compare(a, b, 0); 56 | } 57 | 58 | bool box_y_compare (const shared_ptr a, const shared_ptr b) { 59 | return box_compare(a, b, 1); 60 | } 61 | 62 | bool box_z_compare (const shared_ptr a, const shared_ptr b) { 63 | return box_compare(a, b, 2); 64 | } 65 | 66 | 67 | bvh_node::bvh_node( 68 | std::vector>& objects, 69 | size_t start, size_t end, double time0, double time1 70 | ) { 71 | int axis = random_int(0,2); 72 | auto comparator = (axis == 0) ? box_x_compare 73 | : (axis == 1) ? box_y_compare 74 | : box_z_compare; 75 | 76 | size_t object_span = end - start; 77 | 78 | if (object_span == 1) { 79 | left = right = objects[start]; 80 | } else if (object_span == 2) { 81 | if (comparator(objects[start], objects[start+1])) { 82 | left = objects[start]; 83 | right = objects[start+1]; 84 | } else { 85 | left = objects[start+1]; 86 | right = objects[start]; 87 | } 88 | } else { 89 | std::sort(objects.begin() + start, objects.begin() + end, comparator); 90 | 91 | auto mid = start + object_span/2; 92 | left = make_shared(objects, start, mid, time0, time1); 93 | right = make_shared(objects, mid, end, time0, time1); 94 | } 95 | 96 | aabb box_left, box_right; 97 | 98 | if ( !left->bounding_box (time0, time1, box_left) 99 | || !right->bounding_box(time0, time1, box_right) 100 | ) 101 | std::cerr << "No bounding box in bvh_node constructor.\n"; 102 | 103 | box = surrounding_box(box_left, box_right); 104 | } 105 | 106 | 107 | bool bvh_node::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 108 | if (!box.hit(r, t_min, t_max)) 109 | return false; 110 | 111 | bool hit_left = left->hit(r, t_min, t_max, rec); 112 | bool hit_right = right->hit(r, t_min, hit_left ? rec.t : t_max, rec); 113 | 114 | return hit_left || hit_right; 115 | } 116 | 117 | 118 | bool bvh_node::bounding_box(double t0, double t1, aabb& output_box) const { 119 | output_box = box; 120 | return true; 121 | } 122 | 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/bvh.h: -------------------------------------------------------------------------------- 1 | #ifndef BVH_H 2 | #define BVH_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "hittable.h" 17 | 18 | #include 19 | 20 | 21 | class bvh_node : public hittable { 22 | public: 23 | bvh_node(); 24 | 25 | bvh_node(hittable_list& list, double time0, double time1) 26 | : bvh_node(list.objects, 0, list.objects.size(), time0, time1) 27 | {} 28 | 29 | bvh_node( 30 | std::vector>& objects, 31 | size_t start, size_t end, double time0, double time1); 32 | 33 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const; 34 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const; 35 | 36 | public: 37 | shared_ptr left; 38 | shared_ptr right; 39 | aabb box; 40 | }; 41 | 42 | 43 | inline bool box_compare(const shared_ptr a, const shared_ptr b, int axis) { 44 | aabb box_a; 45 | aabb box_b; 46 | 47 | if (!a->bounding_box(0,0, box_a) || !b->bounding_box(0,0, box_b)) 48 | std::cerr << "No bounding box in bvh_node constructor.\n"; 49 | 50 | return box_a.min().e[axis] < box_b.min().e[axis]; 51 | } 52 | 53 | 54 | bool box_x_compare (const shared_ptr a, const shared_ptr b) { 55 | return box_compare(a, b, 0); 56 | } 57 | 58 | bool box_y_compare (const shared_ptr a, const shared_ptr b) { 59 | return box_compare(a, b, 1); 60 | } 61 | 62 | bool box_z_compare (const shared_ptr a, const shared_ptr b) { 63 | return box_compare(a, b, 2); 64 | } 65 | 66 | 67 | bvh_node::bvh_node( 68 | std::vector>& objects, 69 | size_t start, size_t end, double time0, double time1 70 | ) { 71 | int axis = random_int(0,2); 72 | auto comparator = (axis == 0) ? box_x_compare 73 | : (axis == 1) ? box_y_compare 74 | : box_z_compare; 75 | 76 | size_t object_span = end - start; 77 | 78 | if (object_span == 1) { 79 | left = right = objects[start]; 80 | } else if (object_span == 2) { 81 | if (comparator(objects[start], objects[start+1])) { 82 | left = objects[start]; 83 | right = objects[start+1]; 84 | } else { 85 | left = objects[start+1]; 86 | right = objects[start]; 87 | } 88 | } else { 89 | std::sort(objects.begin() + start, objects.begin() + end, comparator); 90 | 91 | auto mid = start + object_span/2; 92 | left = make_shared(objects, start, mid, time0, time1); 93 | right = make_shared(objects, mid, end, time0, time1); 94 | } 95 | 96 | aabb box_left, box_right; 97 | 98 | if ( !left->bounding_box (time0, time1, box_left) 99 | || !right->bounding_box(time0, time1, box_right) 100 | ) 101 | std::cerr << "No bounding box in bvh_node constructor.\n"; 102 | 103 | box = surrounding_box(box_left, box_right); 104 | } 105 | 106 | 107 | bool bvh_node::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 108 | if (!box.hit(r, t_min, t_max)) 109 | return false; 110 | 111 | bool hit_left = left->hit(r, t_min, t_max, rec); 112 | bool hit_right = right->hit(r, t_min, hit_left ? rec.t : t_max, rec); 113 | 114 | return hit_left || hit_right; 115 | } 116 | 117 | 118 | bool bvh_node::bounding_box(double t0, double t1, aabb& output_box) const { 119 | output_box = box; 120 | return true; 121 | } 122 | 123 | 124 | #endif 125 | -------------------------------------------------------------------------------- /src/common/texture.h: -------------------------------------------------------------------------------- 1 | #ifndef TEXTURE_H 2 | #define TEXTURE_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "perlin.h" 17 | #include "rtw_stb_image.h" 18 | 19 | #include 20 | 21 | 22 | class texture { 23 | public: 24 | virtual color value(double u, double v, const vec3& p) const = 0; 25 | }; 26 | 27 | 28 | class solid_color : public texture { 29 | public: 30 | solid_color() {} 31 | solid_color(color c) : color_value(c) {} 32 | 33 | solid_color(double red, double green, double blue) 34 | : solid_color(color(red,green,blue)) {} 35 | 36 | virtual color value(double u, double v, const vec3& p) const { 37 | return color_value; 38 | } 39 | 40 | private: 41 | color color_value; 42 | }; 43 | 44 | 45 | class checker_texture : public texture { 46 | public: 47 | checker_texture() {} 48 | checker_texture(shared_ptr t0, shared_ptr t1): even(t0), odd(t1) {} 49 | 50 | virtual color value(double u, double v, const vec3& p) const { 51 | auto sines = sin(10*p.x())*sin(10*p.y())*sin(10*p.z()); 52 | if (sines < 0) 53 | return odd->value(u, v, p); 54 | else 55 | return even->value(u, v, p); 56 | } 57 | 58 | public: 59 | shared_ptr odd; 60 | shared_ptr even; 61 | }; 62 | 63 | 64 | class noise_texture : public texture { 65 | public: 66 | noise_texture() {} 67 | noise_texture(double sc) : scale(sc) {} 68 | 69 | virtual color value(double u, double v, const vec3& p) const { 70 | // return color(1,1,1)*0.5*(1 + noise.turb(scale * p)); 71 | // return color(1,1,1)*noise.turb(scale * p); 72 | return color(1,1,1)*0.5*(1 + sin(scale*p.z() + 10*noise.turb(p))); 73 | } 74 | 75 | public: 76 | perlin noise; 77 | double scale; 78 | }; 79 | 80 | 81 | class image_texture : public texture { 82 | public: 83 | const static int bytes_per_pixel = 3; 84 | 85 | image_texture() 86 | : data(nullptr), width(0), height(0), bytes_per_scanline(0) {} 87 | 88 | image_texture(const char* filename) { 89 | auto components_per_pixel = bytes_per_pixel; 90 | 91 | data = stbi_load( 92 | filename, &width, &height, &components_per_pixel, components_per_pixel); 93 | 94 | if (!data) { 95 | std::cerr << "ERROR: Could not load texture image file '" << filename << "'.\n"; 96 | width = height = 0; 97 | } 98 | 99 | bytes_per_scanline = bytes_per_pixel * width; 100 | } 101 | 102 | ~image_texture() { 103 | delete data; 104 | } 105 | 106 | virtual color value(double u, double v, const vec3& p) const { 107 | // If we have no texture data, then return solid cyan as a debugging aid. 108 | if (data == nullptr) 109 | return color(0,1,1); 110 | 111 | // Clamp input texture coordinates to [0,1] x [1,0] 112 | u = clamp(u, 0.0, 1.0); 113 | v = 1.0 - clamp(v, 0.0, 1.0); // Flip V to image coordinates 114 | 115 | auto i = static_cast(u * width); 116 | auto j = static_cast(v * height); 117 | 118 | // Clamp integer mapping, since actual coordinates should be less than 1.0 119 | if (i >= width) i = width-1; 120 | if (j >= height) j = height-1; 121 | 122 | const auto color_scale = 1.0 / 255.0; 123 | auto pixel = data + j*bytes_per_scanline + i*bytes_per_pixel; 124 | 125 | return color(color_scale*pixel[0], color_scale*pixel[1], color_scale*pixel[2]); 126 | } 127 | 128 | private: 129 | unsigned char *data; 130 | int width, height; 131 | int bytes_per_scanline; 132 | }; 133 | 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Ray Tracing in One Weekend Series 4 | 5 | 6 | 7 |
8 | 9 |

Ray Tracing in One Weekend

The Book Series

10 | 11 |
12 | 13 | Ray Tracing in One Weekend 14 | 15 | 16 | 17 | Ray Tracing: The Next Week 18 | 19 | 20 | 21 | Ray Tracing: The Rest Of Your Life 22 | 23 |
24 | 25 | 26 |

Getting the Books

27 | 28 |

The Ray Tracing in One Weekend series of books are now available to the public for free online. They 29 | are now released under the CC0 30 | license. This means that they are as close to public domain as we can get. (While that also frees you from the 31 | requirement of providing attribution, it would help the overall project if you could point back to this web site as a 32 | service to other users.) 33 | 34 |

Hit any of the book cover images above to begin reading. These books are formatted for printing directly from your 35 | browser, where you can also (on most browsers) save them as PDF. 36 | 37 | 38 |

Overview

39 | 40 |

I’ve taught many graphics classes over the years. Often I do them in ray tracing, because you are forced to write 41 | all the code but you can still get cool images with no API. I decided to adapt my course notes into a how-to, to get 42 | you to a cool program as quickly as possible. It will not be a full-featured ray tracer, but it does have the indirect 43 | lighting which has made ray tracing a staple in movies. Follow these steps, and the architecture of the ray tracer you 44 | produce will be good for extending to a more extensive ray tracer if you get excited and want to pursue that. 45 | 46 |

When somebody says “ray tracing” it could mean many things. What I am going to describe is technically a path 47 | tracer, and a fairly general one. While the code will be pretty simple (let the computer do the work!) I think you’ll 48 | be very happy with the images you can make. 49 | 50 |

In Ray Tracing in One Weekend, you will build a simple brute-force path tracer. Continuing with 51 | Ray Tracing: The Next Week, you will add textures, volumes (like fog), rectangles, instances, lights, and 52 | support for lots of objects using a bounding volume hierarchy (BVH). Finally, with Ray Tracing: The Rest Of Your 53 | Life, we'll dive into the math of creating a very serious ray tracer. 54 | 55 |

When you are done, you should be ready to start messing with the many serious commercial ray tracers underlying the 56 | movie and product-design industries. 57 | 58 | 59 |

Source Code

60 | 61 |

Source code for each book may be found in the GitHub repository: 62 | https://github.com/RayTracing/raytracing.github.io. 63 | You can also directly download the latest version of the entire project (all three books) as a single archive file: 64 |

68 | 69 | 70 |

Issues

71 | 72 |

You can browse book suggestions and errors in 73 | GitHub issues. If you have a suggestion or 74 | believe you've found an error, please check these issues first (including closed ones) to ensure that it hasn't 75 | already been reported. If it hasn't, please create a new entry, describing the problem, book or source file, location, 76 | and whatever other information would be helpful in understanding why you think it's a problem. If possible, include 77 | ideas about what you think the fix should look like. 78 | 79 | 80 |

Contributing

81 |

Interested in helping out? Please read the guidelines in the 82 | CONTRIBUTING.md document 83 | first. Pull requests without associated issues, or submitted without coordination, are highly likely to be 84 | rejected. 85 | 86 |

87 | -------------------------------------------------------------------------------- /src/InOneWeekend/main.cc: -------------------------------------------------------------------------------- 1 | //============================================================================================== 2 | // Originally written in 2016 by Peter Shirley 3 | // 4 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 5 | // neighboring rights to this software to the public domain worldwide. This software is 6 | // distributed without any warranty. 7 | // 8 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 9 | // along with this software. If not, see . 10 | //============================================================================================== 11 | 12 | #include "rtweekend.h" 13 | 14 | #include "camera.h" 15 | #include "color.h" 16 | #include "hittable_list.h" 17 | #include "material.h" 18 | #include "sphere.h" 19 | 20 | #include 21 | 22 | 23 | color ray_color(const ray& r, const hittable& world, int depth) { 24 | hit_record rec; 25 | 26 | // If we've exceeded the ray bounce limit, no more light is gathered. 27 | if (depth <= 0) 28 | return color(0,0,0); 29 | 30 | if (world.hit(r, 0.001, infinity, rec)) { 31 | ray scattered; 32 | color attenuation; 33 | if (rec.mat_ptr->scatter(r, rec, attenuation, scattered)) 34 | return attenuation * ray_color(scattered, world, depth-1); 35 | return color(0,0,0); 36 | } 37 | 38 | vec3 unit_direction = unit_vector(r.direction()); 39 | auto t = 0.5*(unit_direction.y() + 1.0); 40 | return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5, 0.7, 1.0); 41 | } 42 | 43 | 44 | hittable_list random_scene() { 45 | hittable_list world; 46 | 47 | world.add( 48 | make_shared( 49 | point3(0,-1000,0), 1000, make_shared(color(0.5, 0.5, 0.5))) 50 | ); 51 | 52 | int i = 1; 53 | for (int a = -11; a < 11; a++) { 54 | for (int b = -11; b < 11; b++) { 55 | auto choose_mat = random_double(); 56 | point3 center(a + 0.9*random_double(), 0.2, b + 0.9*random_double()); 57 | if ((center - vec3(4, 0.2, 0)).length() > 0.9) { 58 | if (choose_mat < 0.8) { 59 | // diffuse 60 | auto albedo = color::random() * color::random(); 61 | world.add( 62 | make_shared(center, 0.2, make_shared(albedo))); 63 | } else if (choose_mat < 0.95) { 64 | // metal 65 | auto albedo = color::random(.5, 1); 66 | auto fuzz = random_double(0, .5); 67 | world.add( 68 | make_shared(center, 0.2, make_shared(albedo, fuzz))); 69 | } else { 70 | // glass 71 | world.add(make_shared(center, 0.2, make_shared(1.5))); 72 | } 73 | } 74 | } 75 | } 76 | 77 | world.add( 78 | make_shared( 79 | point3(0, 1, 0), 1.0, make_shared(1.5))); 80 | 81 | world.add( 82 | make_shared( 83 | point3(-4, 1, 0), 1.0, make_shared(color(0.4, 0.2, 0.1)))); 84 | 85 | world.add( 86 | make_shared( 87 | point3(4, 1, 0), 1.0, make_shared(color(0.7, 0.6, 0.5), 0.0))); 88 | 89 | return world; 90 | } 91 | 92 | 93 | int main() { 94 | const auto aspect_ratio = 16.0 / 9.0; 95 | const int image_width = 1200; 96 | const int image_height = static_cast(image_width / aspect_ratio); 97 | const int samples_per_pixel = 10; 98 | const int max_depth = 50; 99 | 100 | std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n"; 101 | 102 | auto world = random_scene(); 103 | 104 | point3 lookfrom(13,2,3); 105 | point3 lookat(0,0,0); 106 | vec3 vup(0,1,0); 107 | auto dist_to_focus = 10.0; 108 | auto aperture = 0.1; 109 | 110 | camera cam(lookfrom, lookat, vup, 20, aspect_ratio, aperture, dist_to_focus); 111 | 112 | for (int j = image_height-1; j >= 0; --j) { 113 | std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush; 114 | for (int i = 0; i < image_width; ++i) { 115 | color pixel_color; 116 | for (int s = 0; s < samples_per_pixel; ++s) { 117 | auto u = (i + random_double()) / (image_width-1); 118 | auto v = (j + random_double()) / (image_height-1); 119 | ray r = cam.get_ray(u, v); 120 | pixel_color += ray_color(r, world, max_depth); 121 | } 122 | write_color(std::cout, pixel_color, samples_per_pixel); 123 | } 124 | } 125 | 126 | std::cerr << "\nDone.\n"; 127 | } 128 | -------------------------------------------------------------------------------- /src/TheNextWeek/material.h: -------------------------------------------------------------------------------- 1 | #ifndef MATERIAL_H 2 | #define MATERIAL_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "hittable.h" 17 | #include "texture.h" 18 | 19 | 20 | double schlick(double cosine, double ref_idx) { 21 | double r0 = (1-ref_idx) / (1+ref_idx); 22 | r0 = r0*r0; 23 | return r0 + (1-r0)*pow((1 - cosine),5); 24 | } 25 | 26 | 27 | class material { 28 | public: 29 | virtual color emitted(double u, double v, const point3& p) const { 30 | return color(0,0,0); 31 | } 32 | 33 | virtual bool scatter( 34 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 35 | ) const = 0; 36 | }; 37 | 38 | 39 | class dielectric : public material { 40 | public: 41 | dielectric(double ri) : ref_idx(ri) {} 42 | 43 | virtual bool scatter( 44 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 45 | ) const { 46 | attenuation = color(1.0, 1.0, 1.0); 47 | double etai_over_etat = (rec.front_face) ? (1.0 / ref_idx) : (ref_idx); 48 | 49 | vec3 unit_direction = unit_vector(r_in.direction()); 50 | double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0); 51 | double sin_theta = sqrt(1.0 - cos_theta*cos_theta); 52 | if (etai_over_etat * sin_theta > 1.0 ) { 53 | vec3 reflected = reflect(unit_direction, rec.normal); 54 | scattered = ray(rec.p, reflected, r_in.time()); 55 | return true; 56 | } 57 | 58 | double reflect_prob = schlick(cos_theta, etai_over_etat); 59 | if (random_double() < reflect_prob) 60 | { 61 | vec3 reflected = reflect(unit_direction, rec.normal); 62 | scattered = ray(rec.p, reflected, r_in.time()); 63 | return true; 64 | } 65 | 66 | vec3 refracted = refract(unit_direction, rec.normal, etai_over_etat); 67 | scattered = ray(rec.p, refracted, r_in.time()); 68 | return true; 69 | } 70 | 71 | public: 72 | double ref_idx; 73 | }; 74 | 75 | 76 | class diffuse_light : public material { 77 | public: 78 | diffuse_light(shared_ptr a) : emit(a) {} 79 | 80 | virtual bool scatter( 81 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 82 | ) const { 83 | return false; 84 | } 85 | 86 | virtual color emitted(double u, double v, const point3& p) const { 87 | return emit->value(u, v, p); 88 | } 89 | 90 | public: 91 | shared_ptr emit; 92 | }; 93 | 94 | 95 | class isotropic : public material { 96 | public: 97 | isotropic(shared_ptr a) : albedo(a) {} 98 | 99 | virtual bool scatter( 100 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 101 | ) const { 102 | scattered = ray(rec.p, random_in_unit_sphere(), r_in.time()); 103 | attenuation = albedo->value(rec.u, rec.v, rec.p); 104 | return true; 105 | } 106 | 107 | public: 108 | shared_ptr albedo; 109 | }; 110 | 111 | 112 | class lambertian : public material { 113 | public: 114 | lambertian(shared_ptr a) : albedo(a) {} 115 | 116 | virtual bool scatter( 117 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 118 | ) const { 119 | vec3 scatter_direction = rec.normal + random_unit_vector(); 120 | scattered = ray(rec.p, scatter_direction, r_in.time()); 121 | attenuation = albedo->value(rec.u, rec.v, rec.p); 122 | return true; 123 | } 124 | 125 | public: 126 | shared_ptr albedo; 127 | }; 128 | 129 | 130 | class metal : public material { 131 | public: 132 | metal(const color& a, double f) : albedo(a), fuzz(f < 1 ? f : 1) {} 133 | 134 | virtual bool scatter( 135 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 136 | ) const { 137 | vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal); 138 | scattered = ray(rec.p, reflected + fuzz*random_in_unit_sphere(), r_in.time()); 139 | attenuation = albedo; 140 | return (dot(scattered.direction(), rec.normal) > 0); 141 | } 142 | 143 | public: 144 | color albedo; 145 | double fuzz; 146 | }; 147 | 148 | 149 | #endif 150 | -------------------------------------------------------------------------------- /src/TheNextWeek/aarect.h: -------------------------------------------------------------------------------- 1 | #ifndef AARECT_H 2 | #define AARECT_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "hittable.h" 17 | 18 | 19 | class xy_rect: public hittable { 20 | public: 21 | xy_rect() {} 22 | 23 | xy_rect( 24 | double _x0, double _x1, double _y0, double _y1, double _k, shared_ptr mat 25 | ) : x0(_x0), x1(_x1), y0(_y0), y1(_y1), k(_k), mp(mat) {}; 26 | 27 | virtual bool hit(const ray& r, double t0, double t1, hit_record& rec) const; 28 | 29 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const { 30 | // The bounding box must have non-zero width in each dimension, so pad the Z 31 | // dimension a small amount. 32 | output_box = aabb(point3(x0,y0, k-0.0001), point3(x1, y1, k+0.0001)); 33 | return true; 34 | } 35 | 36 | public: 37 | shared_ptr mp; 38 | double x0, x1, y0, y1, k; 39 | }; 40 | 41 | class xz_rect: public hittable { 42 | public: 43 | xz_rect() {} 44 | 45 | xz_rect( 46 | double _x0, double _x1, double _z0, double _z1, double _k, shared_ptr mat 47 | ) : x0(_x0), x1(_x1), z0(_z0), z1(_z1), k(_k), mp(mat) {}; 48 | 49 | virtual bool hit(const ray& r, double t0, double t1, hit_record& rec) const; 50 | 51 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const { 52 | // The bounding box must have non-zero width in each dimension, so pad the Y 53 | // dimension a small amount. 54 | output_box = aabb(point3(x0,k-0.0001,z0), point3(x1, k+0.0001, z1)); 55 | return true; 56 | } 57 | 58 | public: 59 | shared_ptr mp; 60 | double x0, x1, z0, z1, k; 61 | }; 62 | 63 | class yz_rect: public hittable { 64 | public: 65 | yz_rect() {} 66 | 67 | yz_rect( 68 | double _y0, double _y1, double _z0, double _z1, double _k, shared_ptr mat 69 | ) : y0(_y0), y1(_y1), z0(_z0), z1(_z1), k(_k), mp(mat) {}; 70 | 71 | virtual bool hit(const ray& r, double t0, double t1, hit_record& rec) const; 72 | 73 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const { 74 | // The bounding box must have non-zero width in each dimension, so pad the X 75 | // dimension a small amount. 76 | output_box = aabb(point3(k-0.0001, y0, z0), point3(k+0.0001, y1, z1)); 77 | return true; 78 | } 79 | 80 | public: 81 | shared_ptr mp; 82 | double y0, y1, z0, z1, k; 83 | }; 84 | 85 | bool xy_rect::hit(const ray& r, double t0, double t1, hit_record& rec) const { 86 | auto t = (k-r.origin().z()) / r.direction().z(); 87 | if (t < t0 || t > t1) 88 | return false; 89 | 90 | auto x = r.origin().x() + t*r.direction().x(); 91 | auto y = r.origin().y() + t*r.direction().y(); 92 | if (x < x0 || x > x1 || y < y0 || y > y1) 93 | return false; 94 | 95 | rec.u = (x-x0)/(x1-x0); 96 | rec.v = (y-y0)/(y1-y0); 97 | rec.t = t; 98 | auto outward_normal = vec3(0, 0, 1); 99 | rec.set_face_normal(r, outward_normal); 100 | rec.mat_ptr = mp; 101 | rec.p = r.at(t); 102 | 103 | return true; 104 | } 105 | 106 | bool xz_rect::hit(const ray& r, double t0, double t1, hit_record& rec) const { 107 | auto t = (k-r.origin().y()) / r.direction().y(); 108 | if (t < t0 || t > t1) 109 | return false; 110 | 111 | auto x = r.origin().x() + t*r.direction().x(); 112 | auto z = r.origin().z() + t*r.direction().z(); 113 | if (x < x0 || x > x1 || z < z0 || z > z1) 114 | return false; 115 | 116 | rec.u = (x-x0)/(x1-x0); 117 | rec.v = (z-z0)/(z1-z0); 118 | rec.t = t; 119 | auto outward_normal = vec3(0, 1, 0); 120 | rec.set_face_normal(r, outward_normal); 121 | rec.mat_ptr = mp; 122 | rec.p = r.at(t); 123 | 124 | return true; 125 | } 126 | 127 | bool yz_rect::hit(const ray& r, double t0, double t1, hit_record& rec) const { 128 | auto t = (k-r.origin().x()) / r.direction().x(); 129 | if (t < t0 || t > t1) 130 | return false; 131 | 132 | auto y = r.origin().y() + t*r.direction().y(); 133 | auto z = r.origin().z() + t*r.direction().z(); 134 | if (y < y0 || y > y1 || z < z0 || z > z1) 135 | return false; 136 | 137 | rec.u = (y-y0)/(y1-y0); 138 | rec.v = (z-z0)/(z1-z0); 139 | rec.t = t; 140 | auto outward_normal = vec3(1, 0, 0); 141 | rec.set_face_normal(r, outward_normal); 142 | rec.mat_ptr = mp; 143 | rec.p = r.at(t); 144 | 145 | return true; 146 | } 147 | 148 | #endif 149 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/main.cc: -------------------------------------------------------------------------------- 1 | //============================================================================================== 2 | // Originally written in 2016 by Peter Shirley 3 | // 4 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 5 | // neighboring rights to this software to the public domain worldwide. This software is 6 | // distributed without any warranty. 7 | // 8 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 9 | // along with this software. If not, see . 10 | //============================================================================================== 11 | 12 | #include "rtweekend.h" 13 | 14 | #include "aarect.h" 15 | #include "box.h" 16 | #include "camera.h" 17 | #include "color.h" 18 | #include "hittable_list.h" 19 | #include "material.h" 20 | #include "sphere.h" 21 | 22 | #include 23 | 24 | 25 | color ray_color( 26 | const ray& r, 27 | const color& background, 28 | const hittable& world, 29 | shared_ptr lights, 30 | int depth 31 | ) { 32 | hit_record rec; 33 | 34 | // If we've exceeded the ray bounce limit, no more light is gathered. 35 | if (depth <= 0) 36 | return color(0,0,0); 37 | 38 | // If the ray hits nothing, return the background color. 39 | if (!world.hit(r, 0.001, infinity, rec)) 40 | return background; 41 | 42 | scatter_record srec; 43 | color emitted = rec.mat_ptr->emitted(r, rec, rec.u, rec.v, rec.p); 44 | 45 | if (!rec.mat_ptr->scatter(r, rec, srec)) 46 | return emitted; 47 | 48 | if (srec.is_specular) { 49 | return srec.attenuation 50 | * ray_color(srec.specular_ray, background, world, lights, depth-1); 51 | } 52 | 53 | auto light_ptr = make_shared(lights, rec.p); 54 | mixture_pdf p(light_ptr, srec.pdf_ptr); 55 | ray scattered = ray(rec.p, p.generate(), r.time()); 56 | auto pdf_val = p.value(scattered.direction()); 57 | 58 | return emitted 59 | + srec.attenuation * rec.mat_ptr->scattering_pdf(r, rec, scattered) 60 | * ray_color(scattered, background, world, lights, depth-1) 61 | / pdf_val; 62 | } 63 | 64 | 65 | hittable_list cornell_box(camera& cam, double aspect) { 66 | hittable_list world; 67 | 68 | auto red = make_shared(make_shared(.65, .05, .05)); 69 | auto white = make_shared(make_shared(.73, .73, .73)); 70 | auto green = make_shared(make_shared(.12, .45, .15)); 71 | auto light = make_shared(make_shared(15, 15, 15)); 72 | 73 | world.add(make_shared(make_shared(0, 555, 0, 555, 555, green))); 74 | world.add(make_shared(0, 555, 0, 555, 0, red)); 75 | world.add(make_shared(make_shared(213, 343, 227, 332, 554, light))); 76 | world.add(make_shared(make_shared(0, 555, 0, 555, 555, white))); 77 | world.add(make_shared(0, 555, 0, 555, 0, white)); 78 | world.add(make_shared(make_shared(0, 555, 0, 555, 555, white))); 79 | 80 | shared_ptr box1 = make_shared(point3(0,0,0), point3(165,330,165), white); 81 | box1 = make_shared(box1, 15); 82 | box1 = make_shared(box1, vec3(265,0,295)); 83 | world.add(box1); 84 | 85 | auto glass = make_shared(1.5); 86 | world.add(make_shared(point3(190,90,190), 90 , glass)); 87 | 88 | point3 lookfrom(278, 278, -800); 89 | point3 lookat(278, 278, 0); 90 | vec3 up(0, 1, 0); 91 | auto dist_to_focus = 10.0; 92 | auto aperture = 0.0; 93 | auto vfov = 40.0; 94 | auto t0 = 0.0; 95 | auto t1 = 1.0; 96 | 97 | cam = camera(lookfrom, lookat, up, vfov, aspect, aperture, dist_to_focus, t0, t1); 98 | 99 | return world; 100 | } 101 | 102 | 103 | int main() { 104 | const auto aspect_ratio = 1.0 / 1.0; 105 | const int image_width = 600; 106 | const int image_height = static_cast(image_width / aspect_ratio); 107 | const int samples_per_pixel = 100; 108 | const int max_depth = 50; 109 | 110 | std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n"; 111 | 112 | color background(0,0,0); 113 | 114 | camera cam; 115 | auto world = cornell_box(cam, aspect_ratio); 116 | 117 | auto lights = make_shared(); 118 | lights->add(make_shared(213, 343, 227, 332, 554, shared_ptr())); 119 | lights->add(make_shared(point3(190, 90, 190), 90, shared_ptr())); 120 | 121 | for (int j = image_height-1; j >= 0; --j) { 122 | std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush; 123 | for (int i = 0; i < image_width; ++i) { 124 | color pixel_color; 125 | for (int s = 0; s < samples_per_pixel; ++s) { 126 | auto u = (i + random_double()) / (image_width-1); 127 | auto v = (j + random_double()) / (image_height-1); 128 | ray r = cam.get_ray(u, v); 129 | pixel_color += ray_color(r, background, world, lights, max_depth); 130 | } 131 | write_color(std::cout, pixel_color, samples_per_pixel); 132 | } 133 | } 134 | 135 | std::cerr << "\nDone.\n"; 136 | } 137 | -------------------------------------------------------------------------------- /style/book.css: -------------------------------------------------------------------------------- 1 | /* ------------------------------------------------------------------------------------------------- 2 | ** General Body Styles 3 | ** -----------------------------------------------------------------------------------------------*/ 4 | 5 | body { 6 | font-family: sans-serif; 7 | } 8 | 9 | .md a { 10 | font-family: sans-serif; 11 | } 12 | 13 | div.indented { 14 | margin-left: 5ex; 15 | } 16 | 17 | 18 | /* ------------------------------------------------------------------------------------------------- 19 | ** Table of Contents 20 | ** -----------------------------------------------------------------------------------------------*/ 21 | 22 | .md .longTOC, .md .mediumTOC, .md .shortTOC { 23 | font-family: sans-serif; 24 | } 25 | 26 | .md .longTOC { 27 | width: 72%; 28 | margin: 2em auto 0 auto; 29 | padding: 0 4ex 1em 4ex; 30 | border: solid 4px #e0e0d0; 31 | background: #e4e4d8; 32 | } 33 | 34 | .md .tocHeader { 35 | font-size: 165%; 36 | margin-bottom: -1em; 37 | border-bottom: solid 4px #777; 38 | } 39 | 40 | .md .longTOC, .md .mediumTOC, .md .shortTOC { 41 | font-family: sans-serif; 42 | } 43 | 44 | 45 | /* ------------------------------------------------------------------------------------------------- 46 | ** Titles & Headers 47 | ** -----------------------------------------------------------------------------------------------*/ 48 | 49 | .md div.title { 50 | font-size: 220%; 51 | letter-spacing: -0.06em; 52 | } 53 | 54 | .md .subtitle { 55 | font-size: 100%; 56 | font-style: italic; 57 | } 58 | 59 | .md h1 { 60 | font-size: 165%; 61 | letter-spacing: -0.05ex; 62 | margin-top: 2em; 63 | padding-top: 0.25em; 64 | border-bottom: solid 4px #777; 65 | text-align: left; 66 | } 67 | 68 | .md h1::before { 69 | content: counter(h1) ". "; 70 | } 71 | 72 | .md h2::before { 73 | content: counter(h1) "." counter(h2) ". "; 74 | } 75 | 76 | 77 | /* ------------------------------------------------------------------------------------------------- 78 | ** Code 79 | ** -----------------------------------------------------------------------------------------------*/ 80 | 81 | .md pre.listing.tilde { 82 | border: solid 3px #d4d4d4; 83 | padding: 1.5ex; 84 | width: 96%; 85 | overflow: visible; 86 | background: #e4e4e0; 87 | } 88 | 89 | .md code { 90 | /* All code, both in fenced blocks and inline. */ 91 | font-family: Consolas, Menlo, monospace; 92 | font-size: 86%; 93 | background: #e0e0dc; 94 | } 95 | 96 | .md pre.listing.tilde code { 97 | /* Only code in fenced blocks. */ 98 | letter-spacing: -0.20; 99 | background: #e4e4e0; 100 | } 101 | 102 | /* Hilight.js Syntax Coloring */ 103 | 104 | .hljs-comment { 105 | color: #40f; 106 | } 107 | 108 | .hljs-keyword { 109 | color: #a62; 110 | } 111 | 112 | .hljs-meta { 113 | color: #f40; 114 | } 115 | 116 | .hljs-function .hljs-title { 117 | font-weight: normal; 118 | } 119 | 120 | .hljs-number { 121 | color: #009944; 122 | } 123 | 124 | /* Code Line Types */ 125 | 126 | .md code > .highlight { 127 | background-color: #ccdbc8; 128 | } 129 | 130 | .md code > .delete { 131 | text-decoration: line-through; 132 | background-color: #ffcccc; 133 | color: #a0a0a0; 134 | } 135 | 136 | .md div.listingcaption { 137 | text-align: center; 138 | margin-top: 0; 139 | margin-bottom: 1em; 140 | } 141 | 142 | .md div.listingcaption kbd { 143 | font-style: normal; 144 | } 145 | 146 | /* ------------------------------------------------------------------------------------------------- 147 | ** Images & Figures 148 | ** -----------------------------------------------------------------------------------------------*/ 149 | 150 | .md img { 151 | margin-top: 1.0em; 152 | width: 72ex; 153 | } 154 | 155 | .md div.image { 156 | margin-bottom: 1em; 157 | } 158 | 159 | .md span.imagecaption { 160 | text-align: center; 161 | margin-top: 0; 162 | margin-bottom: 1em; 163 | } 164 | 165 | /* ------------------------------------------------------------------------------------------------- 166 | ** Acknowledgments 167 | ** -----------------------------------------------------------------------------------------------*/ 168 | 169 | div.credit-list ul { 170 | margin-top: 0; 171 | list-style-type: none; 172 | column-count: 3; 173 | } 174 | 175 | 176 | 177 | /* ------------------------------------------------------------------------------------------------- 178 | ** Print Styling 179 | ** -----------------------------------------------------------------------------------------------*/ 180 | 181 | @media print { 182 | 183 | @page { 184 | margin: 1.5cm 2.5cm 1.0cm 2.5cm; 185 | size: letter portrait; 186 | } 187 | 188 | body { 189 | line-height: 110%; 190 | } 191 | 192 | div.together { 193 | page-break-inside: avoid; 194 | } 195 | 196 | .md { 197 | font-size: 80%; 198 | } 199 | 200 | .md h1 { 201 | page-break-before: always; 202 | } 203 | 204 | .md img { 205 | page-break-before: avoid; 206 | } 207 | 208 | .md code { 209 | font-size: 86%; 210 | } 211 | 212 | .md p code { 213 | padding: 0; 214 | color: #b63; 215 | background: none; 216 | } 217 | 218 | .md pre.listing.tilde { 219 | margin: 0 auto; 220 | width: 86%; 221 | } 222 | 223 | .md pre.listing.tilde code { 224 | font-size: 65%; 225 | } 226 | } 227 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Ray Tracing in One Weekend Book Series 2 | ==================================================================================================== 3 | 4 | | ![RT in One Weekend][cover1] | ![RT The Next Week][cover2] | ![RT The Rest of Your Life][cover3] | 5 | |:----------------------------:|:---------------------------:|:-----------------------------------:| 6 | | [In One Weekend][book1] | [The Next Week][book2] | [The Rest of Your Life][book3] | 7 | 8 | 9 | Getting the Books 10 | ------------------ 11 | The _Ray Tracing in One Weekend_ series of books are now available to the public for free directly 12 | from the web: 13 | 14 | - [Ray Tracing in One Weekend][web1] 15 | - [Ray Tracing: The Next Week][web2] 16 | - [Ray Tracing: The Rest of Your Life][web3] 17 | 18 | These books have been formatted for both screen and print. For printed copies, or to create PDF 19 | versions, use the print function in your browser. 20 | 21 | 22 | News 23 | ----- 24 | 2020-March-23 — v3.0.0 is out! Following the major v2.0.0 release, we finally had the chance to dig 25 | into some of the larger changes we'd been wanting to make for a long time. This is a large change 26 | across the books and entire source code. The new source code now builds using CMake, for most 27 | platforms and build systems. We've refactored a good deal of the project source, cleaning things up, 28 | refactoring, adding new functionality where it made sense, and generally trying to simplify the code 29 | with the goal of making it easier to understand and modify. Finally, this release includes a number 30 | of changes to areas of the book that have given readers difficulties. Enjoy! 31 | 32 | 33 | Branches 34 | --------- 35 | The `master` branch contains the code at latest release. All ongoing development, with all of the 36 | latest changes, can be found in the `dev-patch`, `dev-minor`, and `dev-major` branches. 37 | 38 | 39 | Downloading The Source Code 40 | ---------------------------- 41 | The [GitHub home][] for this project contains all source and documentation associated with the _Ray 42 | Tracing in One Weekend_ series of books. To clone or download the source code, see the green "Clone 43 | or download" button in the upper right of the project home page. 44 | 45 | 46 | Building and Running 47 | --------------------- 48 | Copies of source are provided for you to check your work and compare against. If you wish to build 49 | the provided source, the project uses CMake. At the root of the project directory, run the following 50 | commands to build the debug version of every executable: 51 | 52 | $ cmake -B build 53 | $ cmake --build build 54 | 55 | You can specify the target with the `--target ` option, where the program may be 56 | `inOneWeekend`, `theNextWeek`, `theRestOfYourLife`, or any of the demonstration programs. By default 57 | (with no `--target` option), CMake will build all targets. 58 | 59 | On Windows, you can build either `debug` (the default) or `release` (the optimized version). To 60 | specify this, use the `--config ` option. 61 | 62 | ### CMake GUI on Windows 63 | You may choose to use the CMake GUI when building on windows. 64 | 65 | 1. Open CMake GUI on Windows 66 | 2. For "Where is the source code:", set to location of the copied directory. For example, 67 | `C:\Users\Peter\raytracing.github.io`. 68 | 3. Add the folder "build" within the location of the copied directory. For example, 69 | `C:\Users\Peter\raytracing.github.io\build`. 70 | 4. For "Where to build the binaries", set this to the newly-created build directory. 71 | 5. Click "Configure". 72 | 6. For "Specify the generator for this project", set this to your version of Visual Studio. 73 | 7. Click "Done". 74 | 8. Click "Configure" again. 75 | 9. Click "Generate". 76 | 10. In File Explorer, navigate to build directory and double click the newly-created `.sln` project. 77 | 11. Build in Visual Studio. 78 | 79 | If the project is succesfully cloned and built, you can then use the native terminal of your 80 | operating system to simply print the image to file. 81 | 82 | ### Running The Programs 83 | 84 | On Linux or OSX, from the terminal, run like this: 85 | 86 | $ build/inOneWeekend > image.ppm 87 | 88 | On Windows, run like this: 89 | 90 | build\debug\inOneWeekend > image.ppm 91 | 92 | or, run the optimized version (if you've built with `--config release`): 93 | 94 | build\release\inOneWeekend > image.ppm 95 | 96 | The generated PPM file can be viewed directly as a regular computer image, if your operating system 97 | supports this image type. If your system doesn't handle PPM files, then you should be able to find 98 | PPM file viewers online. We like [ImageMagick][]. 99 | 100 | 101 | Corrections & Contributions 102 | ---------------------------- 103 | If you spot errors, have suggested corrections, or would like to help out with the project, please 104 | review the [CONTRIBUTING][] document for the most effective way to proceed. 105 | 106 | 107 | 108 | [book1]: books/RayTracingInOneWeekend.html 109 | [book2]: books/RayTracingTheNextWeek.html 110 | [book3]: books/RayTracingTheRestOfYourLife.html 111 | [CONTRIBUTING]: ./CONTRIBUTING.md 112 | [cover1]: images/RTOneWeekend-small.jpg 113 | [cover2]: images/RTNextWeek-small.jpg 114 | [cover3]: images/RTRestOfYourLife-small.jpg 115 | [GitHub home]: https://github.com/RayTracing/raytracing.github.io/ 116 | [ImageMagick]: https://imagemagick.org/ 117 | [web1]: https://raytracing.github.io/books/RayTracingInOneWeekend.html 118 | [web2]: https://raytracing.github.io/books/RayTracingTheNextWeek.html 119 | [web3]: https://raytracing.github.io/books/RayTracingTheRestOfYourLife.html 120 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/aarect.h: -------------------------------------------------------------------------------- 1 | #ifndef AARECT_H 2 | #define AARECT_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "hittable.h" 17 | 18 | 19 | class xy_rect: public hittable { 20 | public: 21 | xy_rect() {} 22 | 23 | xy_rect( 24 | double _x0, double _x1, double _y0, double _y1, double _k, shared_ptr mat 25 | ) : x0(_x0), x1(_x1), y0(_y0), y1(_y1), k(_k), mp(mat) {}; 26 | 27 | virtual bool hit(const ray& r, double t0, double t1, hit_record& rec) const; 28 | 29 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const { 30 | // The bounding box must have non-zero width in each dimension, so pad the Z 31 | // dimension a small amount. 32 | output_box = aabb(point3(x0,y0, k-0.0001), point3(x1, y1, k+0.0001)); 33 | return true; 34 | } 35 | 36 | public: 37 | shared_ptr mp; 38 | double x0, x1, y0, y1, k; 39 | }; 40 | 41 | class xz_rect: public hittable { 42 | public: 43 | xz_rect() {} 44 | 45 | xz_rect( 46 | double _x0, double _x1, double _z0, double _z1, double _k, shared_ptr mat 47 | ) : x0(_x0), x1(_x1), z0(_z0), z1(_z1), k(_k), mp(mat) {}; 48 | 49 | virtual bool hit(const ray& r, double t0, double t1, hit_record& rec) const; 50 | 51 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const { 52 | // The bounding box must have non-zero width in each dimension, so pad the Y 53 | // dimension a small amount. 54 | output_box = aabb(point3(x0,k-0.0001,z0), point3(x1, k+0.0001, z1)); 55 | return true; 56 | } 57 | 58 | virtual double pdf_value(const point3& origin, const vec3& v) const { 59 | hit_record rec; 60 | if (!this->hit(ray(origin, v), 0.001, infinity, rec)) 61 | return 0; 62 | 63 | auto area = (x1-x0)*(z1-z0); 64 | auto distance_squared = rec.t * rec.t * v.length_squared(); 65 | auto cosine = fabs(dot(v, rec.normal) / v.length()); 66 | 67 | return distance_squared / (cosine * area); 68 | } 69 | 70 | virtual vec3 random(const point3& origin) const { 71 | auto random_point = point3(random_double(x0,x1), k, random_double(z0,z1)); 72 | return random_point - origin; 73 | } 74 | 75 | public: 76 | shared_ptr mp; 77 | double x0, x1, z0, z1, k; 78 | }; 79 | 80 | class yz_rect: public hittable { 81 | public: 82 | yz_rect() {} 83 | 84 | yz_rect( 85 | double _y0, double _y1, double _z0, double _z1, double _k, shared_ptr mat 86 | ) : y0(_y0), y1(_y1), z0(_z0), z1(_z1), k(_k), mp(mat) {}; 87 | 88 | virtual bool hit(const ray& r, double t0, double t1, hit_record& rec) const; 89 | 90 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const { 91 | // The bounding box must have non-zero width in each dimension, so pad the X 92 | // dimension a small amount. 93 | output_box = aabb(point3(k-0.0001, y0, z0), point3(k+0.0001, y1, z1)); 94 | return true; 95 | } 96 | 97 | public: 98 | shared_ptr mp; 99 | double y0, y1, z0, z1, k; 100 | }; 101 | 102 | bool xy_rect::hit(const ray& r, double t0, double t1, hit_record& rec) const { 103 | auto t = (k-r.origin().z()) / r.direction().z(); 104 | if (t < t0 || t > t1) 105 | return false; 106 | 107 | auto x = r.origin().x() + t*r.direction().x(); 108 | auto y = r.origin().y() + t*r.direction().y(); 109 | if (x < x0 || x > x1 || y < y0 || y > y1) 110 | return false; 111 | 112 | rec.u = (x-x0)/(x1-x0); 113 | rec.v = (y-y0)/(y1-y0); 114 | rec.t = t; 115 | auto outward_normal = vec3(0, 0, 1); 116 | rec.set_face_normal(r, outward_normal); 117 | rec.mat_ptr = mp; 118 | rec.p = r.at(t); 119 | 120 | return true; 121 | } 122 | 123 | bool xz_rect::hit(const ray& r, double t0, double t1, hit_record& rec) const { 124 | auto t = (k-r.origin().y()) / r.direction().y(); 125 | if (t < t0 || t > t1) 126 | return false; 127 | 128 | auto x = r.origin().x() + t*r.direction().x(); 129 | auto z = r.origin().z() + t*r.direction().z(); 130 | if (x < x0 || x > x1 || z < z0 || z > z1) 131 | return false; 132 | 133 | rec.u = (x-x0)/(x1-x0); 134 | rec.v = (z-z0)/(z1-z0); 135 | rec.t = t; 136 | auto outward_normal = vec3(0, 1, 0); 137 | rec.set_face_normal(r, outward_normal); 138 | rec.mat_ptr = mp; 139 | rec.p = r.at(t); 140 | 141 | return true; 142 | } 143 | 144 | bool yz_rect::hit(const ray& r, double t0, double t1, hit_record& rec) const { 145 | auto t = (k-r.origin().x()) / r.direction().x(); 146 | if (t < t0 || t > t1) 147 | return false; 148 | 149 | auto y = r.origin().y() + t*r.direction().y(); 150 | auto z = r.origin().z() + t*r.direction().z(); 151 | if (y < y0 || y > y1 || z < z0 || z > z1) 152 | return false; 153 | 154 | rec.u = (y-y0)/(y1-y0); 155 | rec.v = (z-z0)/(z1-z0); 156 | rec.t = t; 157 | auto outward_normal = vec3(1, 0, 0); 158 | rec.set_face_normal(r, outward_normal); 159 | rec.mat_ptr = mp; 160 | rec.p = r.at(t); 161 | 162 | return true; 163 | } 164 | 165 | #endif 166 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/material.h: -------------------------------------------------------------------------------- 1 | #ifndef MATERIAL_H 2 | #define MATERIAL_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "pdf.h" 17 | #include "texture.h" 18 | 19 | 20 | double schlick(double cosine, double ref_idx) { 21 | double r0 = (1-ref_idx) / (1+ref_idx); 22 | r0 = r0*r0; 23 | return r0 + (1-r0)*pow((1 - cosine),5); 24 | } 25 | 26 | 27 | struct scatter_record 28 | { 29 | ray specular_ray; 30 | bool is_specular; 31 | color attenuation; 32 | shared_ptr pdf_ptr; 33 | }; 34 | 35 | 36 | class material { 37 | public: 38 | virtual color emitted( 39 | const ray& r_in, const hit_record& rec, double u, double v, const point3& p 40 | ) const { 41 | return color(0,0,0); 42 | } 43 | 44 | virtual bool scatter( 45 | const ray& r_in, const hit_record& rec, scatter_record& srec 46 | ) const { 47 | return false; 48 | } 49 | 50 | virtual double scattering_pdf( 51 | const ray& r_in, const hit_record& rec, const ray& scattered 52 | ) const { 53 | return 0; 54 | } 55 | }; 56 | 57 | 58 | class dielectric : public material { 59 | public: 60 | dielectric(double ri) : ref_idx(ri) {} 61 | 62 | virtual bool scatter( 63 | const ray& r_in, const hit_record& rec, scatter_record& srec 64 | ) const { 65 | srec.is_specular = true; 66 | srec.pdf_ptr = nullptr; 67 | srec.attenuation = color(1.0, 1.0, 1.0); 68 | double etai_over_etat = (rec.front_face) ? (1.0 / ref_idx) : (ref_idx); 69 | 70 | vec3 unit_direction = unit_vector(r_in.direction()); 71 | double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0); 72 | double sin_theta = sqrt(1.0 - cos_theta*cos_theta); 73 | if (etai_over_etat * sin_theta > 1.0 ) { 74 | vec3 reflected = reflect(unit_direction, rec.normal); 75 | srec.specular_ray = ray(rec.p, reflected, r_in.time()); 76 | return true; 77 | } 78 | 79 | double reflect_prob = schlick(cos_theta, etai_over_etat); 80 | if (random_double() < reflect_prob) 81 | { 82 | vec3 reflected = reflect(unit_direction, rec.normal); 83 | srec.specular_ray = ray(rec.p, reflected, r_in.time()); 84 | return true; 85 | } 86 | 87 | vec3 refracted = refract(unit_direction, rec.normal, etai_over_etat); 88 | srec.specular_ray = ray(rec.p, refracted, r_in.time()); 89 | return true; 90 | } 91 | 92 | public: 93 | double ref_idx; 94 | }; 95 | 96 | 97 | class diffuse_light : public material { 98 | public: 99 | diffuse_light(shared_ptr a) : emit(a) {} 100 | 101 | virtual color emitted( 102 | const ray& r_in, const hit_record& rec, double u, double v, const point3& p 103 | ) const { 104 | if (!rec.front_face) 105 | return color(0,0,0); 106 | return emit->value(u, v, p); 107 | } 108 | 109 | public: 110 | shared_ptr emit; 111 | }; 112 | 113 | 114 | class isotropic : public material { 115 | public: 116 | isotropic(shared_ptr a) : albedo(a) {} 117 | 118 | virtual bool scatter( 119 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered 120 | ) const { 121 | scattered = ray(rec.p, random_in_unit_sphere(), r_in.time()); 122 | attenuation = albedo->value(rec.u, rec.v, rec.p); 123 | return true; 124 | } 125 | 126 | public: 127 | shared_ptr albedo; 128 | }; 129 | 130 | 131 | class lambertian : public material { 132 | public: 133 | lambertian(shared_ptr a) : albedo(a) {} 134 | 135 | virtual bool scatter( 136 | const ray& r_in, const hit_record& rec, scatter_record& srec 137 | ) const { 138 | srec.is_specular = false; 139 | srec.attenuation = albedo->value(rec.u, rec.v, rec.p); 140 | srec.pdf_ptr = make_shared(rec.normal); 141 | return true; 142 | } 143 | 144 | double scattering_pdf( 145 | const ray& r_in, const hit_record& rec, const ray& scattered 146 | ) const { 147 | auto cosine = dot(rec.normal, unit_vector(scattered.direction())); 148 | return cosine < 0 ? 0 : cosine/pi; 149 | } 150 | 151 | public: 152 | shared_ptr albedo; 153 | }; 154 | 155 | 156 | class metal : public material { 157 | public: 158 | metal(const color& a, double f) : albedo(a), fuzz(f < 1 ? f : 1) {} 159 | 160 | virtual bool scatter( 161 | const ray& r_in, const hit_record& rec, scatter_record& srec 162 | ) const { 163 | vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal); 164 | srec.specular_ray = 165 | ray(rec.p, reflected + fuzz*random_in_unit_sphere(), r_in.time()); 166 | srec.attenuation = albedo; 167 | srec.is_specular = true; 168 | srec.pdf_ptr = nullptr; 169 | return true; 170 | } 171 | 172 | public: 173 | color albedo; 174 | double fuzz; 175 | }; 176 | 177 | 178 | #endif 179 | -------------------------------------------------------------------------------- /src/common/vec3.h: -------------------------------------------------------------------------------- 1 | #ifndef VEC3_H 2 | #define VEC3_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include 15 | #include 16 | 17 | using std::sqrt; 18 | 19 | class vec3 { 20 | public: 21 | vec3() : e{0,0,0} {} 22 | vec3(double e0, double e1, double e2) : e{e0, e1, e2} {} 23 | 24 | double x() const { return e[0]; } 25 | double y() const { return e[1]; } 26 | double z() const { return e[2]; } 27 | 28 | vec3 operator-() const { return vec3(-e[0], -e[1], -e[2]); } 29 | double operator[](int i) const { return e[i]; } 30 | double& operator[](int i) { return e[i]; } 31 | 32 | vec3& operator+=(const vec3 &v) { 33 | e[0] += v.e[0]; 34 | e[1] += v.e[1]; 35 | e[2] += v.e[2]; 36 | return *this; 37 | } 38 | 39 | vec3& operator*=(const double t) { 40 | e[0] *= t; 41 | e[1] *= t; 42 | e[2] *= t; 43 | return *this; 44 | } 45 | 46 | vec3& operator/=(const double t) { 47 | return *this *= 1/t; 48 | } 49 | 50 | double length() const { 51 | return sqrt(length_squared()); 52 | } 53 | 54 | double length_squared() const { 55 | return e[0]*e[0] + e[1]*e[1] + e[2]*e[2]; 56 | } 57 | 58 | void write_color(std::ostream &out, int samples_per_pixel) { 59 | // Replace NaN component values with zero. 60 | // See explanation in Ray Tracing: The Rest of Your Life. 61 | if (e[0] != e[0]) e[0] = 0.0; 62 | if (e[1] != e[1]) e[1] = 0.0; 63 | if (e[2] != e[2]) e[2] = 0.0; 64 | 65 | // Divide the color total by the number of samples and gamma-correct 66 | // for a gamma value of 2.0. 67 | auto scale = 1.0 / samples_per_pixel; 68 | auto r = sqrt(scale * e[0]); 69 | auto g = sqrt(scale * e[1]); 70 | auto b = sqrt(scale * e[2]); 71 | 72 | // Write the translated [0,255] value of each color component. 73 | out << static_cast(256 * clamp(r, 0.0, 0.999)) << ' ' 74 | << static_cast(256 * clamp(g, 0.0, 0.999)) << ' ' 75 | << static_cast(256 * clamp(b, 0.0, 0.999)) << '\n'; 76 | } 77 | 78 | inline static vec3 random() { 79 | return vec3(random_double(), random_double(), random_double()); 80 | } 81 | 82 | inline static vec3 random(double min, double max) { 83 | return vec3(random_double(min,max), random_double(min,max), random_double(min,max)); 84 | } 85 | 86 | public: 87 | double e[3]; 88 | }; 89 | 90 | 91 | // Type aliases for vec3 92 | using point3 = vec3; // 3D point 93 | using color = vec3; // RGB color 94 | 95 | 96 | // vec3 Utility Functions 97 | 98 | inline std::ostream& operator<<(std::ostream &out, const vec3 &v) { 99 | return out << v.e[0] << ' ' << v.e[1] << ' ' << v.e[2]; 100 | } 101 | 102 | inline vec3 operator+(const vec3 &u, const vec3 &v) { 103 | return vec3(u.e[0] + v.e[0], u.e[1] + v.e[1], u.e[2] + v.e[2]); 104 | } 105 | 106 | inline vec3 operator-(const vec3 &u, const vec3 &v) { 107 | return vec3(u.e[0] - v.e[0], u.e[1] - v.e[1], u.e[2] - v.e[2]); 108 | } 109 | 110 | inline vec3 operator*(const vec3 &u, const vec3 &v) { 111 | return vec3(u.e[0] * v.e[0], u.e[1] * v.e[1], u.e[2] * v.e[2]); 112 | } 113 | 114 | inline vec3 operator*(double t, const vec3 &v) { 115 | return vec3(t*v.e[0], t*v.e[1], t*v.e[2]); 116 | } 117 | 118 | inline vec3 operator*(const vec3 &v, double t) { 119 | return t * v; 120 | } 121 | 122 | inline vec3 operator/(vec3 v, double t) { 123 | return (1/t) * v; 124 | } 125 | 126 | inline double dot(const vec3 &u, const vec3 &v) { 127 | return u.e[0] * v.e[0] 128 | + u.e[1] * v.e[1] 129 | + u.e[2] * v.e[2]; 130 | } 131 | 132 | inline vec3 cross(const vec3 &u, const vec3 &v) { 133 | return vec3(u.e[1] * v.e[2] - u.e[2] * v.e[1], 134 | u.e[2] * v.e[0] - u.e[0] * v.e[2], 135 | u.e[0] * v.e[1] - u.e[1] * v.e[0]); 136 | } 137 | 138 | inline vec3 unit_vector(vec3 v) { 139 | return v / v.length(); 140 | } 141 | 142 | vec3 random_in_unit_disk() { 143 | while (true) { 144 | auto p = vec3(random_double(-1,1), random_double(-1,1), 0); 145 | if (p.length_squared() >= 1) continue; 146 | return p; 147 | } 148 | } 149 | 150 | vec3 random_unit_vector() { 151 | auto a = random_double(0, 2*pi); 152 | auto z = random_double(-1, 1); 153 | auto r = sqrt(1 - z*z); 154 | return vec3(r*cos(a), r*sin(a), z); 155 | } 156 | 157 | vec3 random_in_unit_sphere() { 158 | while (true) { 159 | auto p = vec3::random(-1,1); 160 | if (p.length_squared() >= 1) continue; 161 | return p; 162 | } 163 | } 164 | 165 | vec3 random_in_hemisphere(const vec3& normal) { 166 | vec3 in_unit_sphere = random_in_unit_sphere(); 167 | if (dot(in_unit_sphere, normal) > 0.0) // In the same hemisphere as the normal 168 | return in_unit_sphere; 169 | else 170 | return -in_unit_sphere; 171 | } 172 | 173 | vec3 reflect(const vec3& v, const vec3& n) { 174 | return v - 2*dot(v,n)*n; 175 | } 176 | 177 | vec3 refract(const vec3& uv, const vec3& n, double etai_over_etat) { 178 | auto cos_theta = fmin(dot(-uv, n), 1.0); 179 | vec3 r_out_parallel = etai_over_etat * (uv + cos_theta*n); 180 | vec3 r_out_perp = -sqrt(1.0 - r_out_parallel.length_squared()) * n; 181 | return r_out_parallel + r_out_perp; 182 | } 183 | 184 | #endif 185 | -------------------------------------------------------------------------------- /src/TheNextWeek/hittable.h: -------------------------------------------------------------------------------- 1 | #ifndef HITTABLE_H 2 | #define HITTABLE_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "aabb.h" 17 | 18 | 19 | class material; 20 | 21 | void get_sphere_uv(const point3& p, double& u, double& v) { 22 | auto phi = atan2(p.z(), p.x()); 23 | auto theta = asin(p.y()); 24 | u = 1-(phi + pi) / (2*pi); 25 | v = (theta + pi/2) / pi; 26 | } 27 | 28 | 29 | struct hit_record { 30 | point3 p; 31 | vec3 normal; 32 | shared_ptr mat_ptr; 33 | double t; 34 | double u; 35 | double v; 36 | bool front_face; 37 | 38 | inline void set_face_normal(const ray& r, const vec3& outward_normal) { 39 | front_face = dot(r.direction(), outward_normal) < 0; 40 | normal = front_face ? outward_normal :-outward_normal; 41 | } 42 | }; 43 | 44 | 45 | class hittable { 46 | public: 47 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const = 0; 48 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const = 0; 49 | }; 50 | 51 | 52 | class flip_face : public hittable { 53 | public: 54 | flip_face(shared_ptr p) : ptr(p) {} 55 | 56 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 57 | if (!ptr->hit(r, t_min, t_max, rec)) 58 | return false; 59 | 60 | rec.front_face = !rec.front_face; 61 | return true; 62 | } 63 | 64 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const { 65 | return ptr->bounding_box(t0, t1, output_box); 66 | } 67 | 68 | public: 69 | shared_ptr ptr; 70 | }; 71 | 72 | 73 | class translate : public hittable { 74 | public: 75 | translate(shared_ptr p, const vec3& displacement) 76 | : ptr(p), offset(displacement) {} 77 | 78 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const; 79 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const; 80 | 81 | public: 82 | shared_ptr ptr; 83 | vec3 offset; 84 | }; 85 | 86 | 87 | bool translate::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 88 | ray moved_r(r.origin() - offset, r.direction(), r.time()); 89 | if (!ptr->hit(moved_r, t_min, t_max, rec)) 90 | return false; 91 | 92 | rec.p += offset; 93 | rec.set_face_normal(moved_r, rec.normal); 94 | 95 | return true; 96 | } 97 | 98 | 99 | bool translate::bounding_box(double t0, double t1, aabb& output_box) const { 100 | if (!ptr->bounding_box(t0, t1, output_box)) 101 | return false; 102 | 103 | output_box = aabb( 104 | output_box.min() + offset, 105 | output_box.max() + offset); 106 | 107 | return true; 108 | } 109 | 110 | 111 | class rotate_y : public hittable { 112 | public: 113 | rotate_y(shared_ptr p, double angle); 114 | 115 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const; 116 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const { 117 | output_box = bbox; 118 | return hasbox; 119 | } 120 | 121 | public: 122 | shared_ptr ptr; 123 | double sin_theta; 124 | double cos_theta; 125 | bool hasbox; 126 | aabb bbox; 127 | }; 128 | 129 | 130 | rotate_y::rotate_y(shared_ptr p, double angle) : ptr(p) { 131 | auto radians = degrees_to_radians(angle); 132 | sin_theta = sin(radians); 133 | cos_theta = cos(radians); 134 | hasbox = ptr->bounding_box(0, 1, bbox); 135 | 136 | point3 min( infinity, infinity, infinity); 137 | point3 max(-infinity, -infinity, -infinity); 138 | 139 | for (int i = 0; i < 2; i++) { 140 | for (int j = 0; j < 2; j++) { 141 | for (int k = 0; k < 2; k++) { 142 | auto x = i*bbox.max().x() + (1-i)*bbox.min().x(); 143 | auto y = j*bbox.max().y() + (1-j)*bbox.min().y(); 144 | auto z = k*bbox.max().z() + (1-k)*bbox.min().z(); 145 | 146 | auto newx = cos_theta*x + sin_theta*z; 147 | auto newz = -sin_theta*x + cos_theta*z; 148 | 149 | vec3 tester(newx, y, newz); 150 | 151 | for (int c = 0; c < 3; c++) { 152 | min[c] = fmin(min[c], tester[c]); 153 | max[c] = fmax(max[c], tester[c]); 154 | } 155 | } 156 | } 157 | } 158 | 159 | bbox = aabb(min, max); 160 | } 161 | 162 | 163 | bool rotate_y::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 164 | point3 origin = r.origin(); 165 | vec3 direction = r.direction(); 166 | 167 | origin[0] = cos_theta*r.origin()[0] - sin_theta*r.origin()[2]; 168 | origin[2] = sin_theta*r.origin()[0] + cos_theta*r.origin()[2]; 169 | 170 | direction[0] = cos_theta*r.direction()[0] - sin_theta*r.direction()[2]; 171 | direction[2] = sin_theta*r.direction()[0] + cos_theta*r.direction()[2]; 172 | 173 | ray rotated_r(origin, direction, r.time()); 174 | 175 | if (!ptr->hit(rotated_r, t_min, t_max, rec)) 176 | return false; 177 | 178 | point3 p = rec.p; 179 | vec3 normal = rec.normal; 180 | 181 | p[0] = cos_theta*rec.p[0] + sin_theta*rec.p[2]; 182 | p[2] = -sin_theta*rec.p[0] + cos_theta*rec.p[2]; 183 | 184 | normal[0] = cos_theta*rec.normal[0] + sin_theta*rec.normal[2]; 185 | normal[2] = -sin_theta*rec.normal[0] + cos_theta*rec.normal[2]; 186 | 187 | rec.p = p; 188 | rec.set_face_normal(rotated_r, normal); 189 | 190 | return true; 191 | } 192 | 193 | 194 | #endif 195 | -------------------------------------------------------------------------------- /src/TheRestOfYourLife/hittable.h: -------------------------------------------------------------------------------- 1 | #ifndef HITTABLE_H 2 | #define HITTABLE_H 3 | //============================================================================================== 4 | // Originally written in 2016 by Peter Shirley 5 | // 6 | // To the extent possible under law, the author(s) have dedicated all copyright and related and 7 | // neighboring rights to this software to the public domain worldwide. This software is 8 | // distributed without any warranty. 9 | // 10 | // You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication 11 | // along with this software. If not, see . 12 | //============================================================================================== 13 | 14 | #include "rtweekend.h" 15 | 16 | #include "aabb.h" 17 | 18 | 19 | class material; 20 | 21 | void get_sphere_uv(const point3& p, double& u, double& v) { 22 | auto phi = atan2(p.z(), p.x()); 23 | auto theta = asin(p.y()); 24 | u = 1-(phi + pi) / (2*pi); 25 | v = (theta + pi/2) / pi; 26 | } 27 | 28 | 29 | struct hit_record { 30 | point3 p; 31 | vec3 normal; 32 | shared_ptr mat_ptr; 33 | double t; 34 | double u; 35 | double v; 36 | bool front_face; 37 | 38 | inline void set_face_normal(const ray& r, const vec3& outward_normal) { 39 | front_face = dot(r.direction(), outward_normal) < 0; 40 | normal = front_face ? outward_normal :-outward_normal; 41 | } 42 | }; 43 | 44 | 45 | class hittable { 46 | public: 47 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const = 0; 48 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const = 0; 49 | 50 | virtual double pdf_value(const vec3& o, const vec3& v) const { 51 | return 0.0; 52 | } 53 | 54 | virtual vec3 random(const vec3& o) const { 55 | return vec3(1,0,0); 56 | } 57 | }; 58 | 59 | 60 | class flip_face : public hittable { 61 | public: 62 | flip_face(shared_ptr p) : ptr(p) {} 63 | 64 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 65 | if (!ptr->hit(r, t_min, t_max, rec)) 66 | return false; 67 | 68 | rec.front_face = !rec.front_face; 69 | return true; 70 | } 71 | 72 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const { 73 | return ptr->bounding_box(t0, t1, output_box); 74 | } 75 | 76 | public: 77 | shared_ptr ptr; 78 | }; 79 | 80 | 81 | class translate : public hittable { 82 | public: 83 | translate(shared_ptr p, const vec3& displacement) 84 | : ptr(p), offset(displacement) {} 85 | 86 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const; 87 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const; 88 | 89 | public: 90 | shared_ptr ptr; 91 | vec3 offset; 92 | }; 93 | 94 | 95 | bool translate::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 96 | ray moved_r(r.origin() - offset, r.direction(), r.time()); 97 | if (!ptr->hit(moved_r, t_min, t_max, rec)) 98 | return false; 99 | 100 | rec.p += offset; 101 | rec.set_face_normal(moved_r, rec.normal); 102 | 103 | return true; 104 | } 105 | 106 | 107 | bool translate::bounding_box(double t0, double t1, aabb& output_box) const { 108 | if (!ptr->bounding_box(t0, t1, output_box)) 109 | return false; 110 | 111 | output_box = aabb( 112 | output_box.min() + offset, 113 | output_box.max() + offset); 114 | 115 | return true; 116 | } 117 | 118 | 119 | class rotate_y : public hittable { 120 | public: 121 | rotate_y(shared_ptr p, double angle); 122 | 123 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const; 124 | virtual bool bounding_box(double t0, double t1, aabb& output_box) const { 125 | output_box = bbox; 126 | return hasbox; 127 | } 128 | 129 | public: 130 | shared_ptr ptr; 131 | double sin_theta; 132 | double cos_theta; 133 | bool hasbox; 134 | aabb bbox; 135 | }; 136 | 137 | 138 | rotate_y::rotate_y(shared_ptr p, double angle) : ptr(p) { 139 | auto radians = degrees_to_radians(angle); 140 | sin_theta = sin(radians); 141 | cos_theta = cos(radians); 142 | hasbox = ptr->bounding_box(0, 1, bbox); 143 | 144 | point3 min( infinity, infinity, infinity); 145 | point3 max(-infinity, -infinity, -infinity); 146 | 147 | for (int i = 0; i < 2; i++) { 148 | for (int j = 0; j < 2; j++) { 149 | for (int k = 0; k < 2; k++) { 150 | auto x = i*bbox.max().x() + (1-i)*bbox.min().x(); 151 | auto y = j*bbox.max().y() + (1-j)*bbox.min().y(); 152 | auto z = k*bbox.max().z() + (1-k)*bbox.min().z(); 153 | 154 | auto newx = cos_theta*x + sin_theta*z; 155 | auto newz = -sin_theta*x + cos_theta*z; 156 | 157 | vec3 tester(newx, y, newz); 158 | 159 | for (int c = 0; c < 3; c++) { 160 | min[c] = fmin(min[c], tester[c]); 161 | max[c] = fmax(max[c], tester[c]); 162 | } 163 | } 164 | } 165 | } 166 | 167 | bbox = aabb(min, max); 168 | } 169 | 170 | 171 | bool rotate_y::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { 172 | auto origin = r.origin(); 173 | auto direction = r.direction(); 174 | 175 | origin[0] = cos_theta*r.origin()[0] - sin_theta*r.origin()[2]; 176 | origin[2] = sin_theta*r.origin()[0] + cos_theta*r.origin()[2]; 177 | 178 | direction[0] = cos_theta*r.direction()[0] - sin_theta*r.direction()[2]; 179 | direction[2] = sin_theta*r.direction()[0] + cos_theta*r.direction()[2]; 180 | 181 | ray rotated_r(origin, direction, r.time()); 182 | 183 | if (!ptr->hit(rotated_r, t_min, t_max, rec)) 184 | return false; 185 | 186 | auto p = rec.p; 187 | auto normal = rec.normal; 188 | 189 | p[0] = cos_theta*rec.p[0] + sin_theta*rec.p[2]; 190 | p[2] = -sin_theta*rec.p[0] + cos_theta*rec.p[2]; 191 | 192 | normal[0] = cos_theta*rec.normal[0] + sin_theta*rec.normal[2]; 193 | normal[2] = -sin_theta*rec.normal[0] + cos_theta*rec.normal[2]; 194 | 195 | rec.p = p; 196 | rec.set_face_normal(rotated_r, normal); 197 | 198 | return true; 199 | } 200 | 201 | 202 | #endif 203 | -------------------------------------------------------------------------------- /COPYING.txt: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | Change Log -- Ray Tracing in One Weekend 2 | ==================================================================================================== 3 | 4 | # v3.1.0 (2020-05-03) 5 | 6 | This minor upgrade adds some fixes and changes that are a bit more than just patches. The text now 7 | has subchapter headings to help readers browse content and get a bit more context. We're introducing 8 | new type aliases `point3` and `color` for `vec3` to better indicate the underlying mathematical 9 | types of parameters and variables. Overall, a bunch of small improvements that we'd recommend 10 | adopting, but may warrant comparison with any current projects. 11 | 12 | ### Common 13 | - Fix: Include cmath in vec3.h (#501) 14 | - Fix: Scattered improvements to the text 15 | - New: Subchapters throughout all three books (#267) 16 | - New: Add explanation for padding `aarect` in the zero dimension (#488) 17 | - Change: Minor change to use new `point3` and `color` type aliases for `vec3` (#422) 18 | - Change: Renamed `constant_texture` to `solid_color`, add RGB constructor (#452) 19 | - Change: Moved `vec3::write_color()` method to utility function in `color.h` header (#502) 20 | - Change: Switch from `ffmin`/`ffmax` to standard `fmin`/`fmax` (#444, #491) 21 | - Change: Math notation to bold uppercase points, bold lowercase no-barb vectors (#412) 22 | - Change: Books use Markdeep's image class=pixel for rendered image fidelity (#498) 23 | 24 | ### _In One Weekend_ 25 | - Fix: Improve image size and aspect ratio calculation to make size changes easier 26 | - Fix: Added `t` parameter back into `hit_record` at correct place 27 | - Fix: image basic vectors off by one 28 | - Fix: Update image and size for first PPM image 29 | - Fix: Update image and size for blue-to-white gradient image 30 | - Fix: Update image and size for simple red sphere render 31 | - Fix: Update image and size for sphere with normal-vector coloring 32 | - Fix: Correct typo in "What's next?" list to rejoin split paragraph on "Lights." Adjust numbering 33 | in rest of list. 34 | - Change: Define image aspect ratio up front, then image height from that and the image width 35 | - Change: Default image sizes changed from 200x100 to 384x216 36 | - Change: First image size changed to 256x256 37 | 38 | ### _The Next Week_ 39 | - Change: Large rewrite of the `image_texture` class. Now handles image loading too. (#434) 40 | 41 | 42 | ---------------------------------------------------------------------------------------------------- 43 | # v3.0.2 (2020-04-11) 44 | 45 | ### Common 46 | - Fix: code styling for source code both inline and in fenced blocks (#430) 47 | - Change: Every book source now includes from a single common acknowledgments document 48 | 49 | ### _In One Weekend_ 50 | - Fix: Correct typo: "consine" to "cosine" 51 | 52 | ### _The Next Week_ 53 | - Fix: `shared_ptr` dereference and simplify code in `hittable_list::bounding_box()` (#435) 54 | - Fix: Erroneous en-dash in code block. Replace `–>` with `->` (#439) 55 | - Fix: Introduce `u`,`v` surface coordinates to `hit_record` (#441) 56 | - Fix: Add highlight to new `hittable::bounding_box()` method (#442) 57 | 58 | ### _The Rest of Your Life_ 59 | - Fix: unitialized variable in first version of `integrate_x_sq.cc` 60 | - Fix: remove unreferenced variables in several sample programs 61 | - Fix: correct program computation of the integral of x^2 (#438) 62 | 63 | 64 | ---------------------------------------------------------------------------------------------------- 65 | # v3.0.1 (2020-03-31) 66 | 67 | - Fix: Display rendered images as pixelated instead of smoothed (#179) 68 | - Deleted: delete old README files specific to each book (#410) 69 | 70 | ### _In One Weekend_ 71 | - Fix: Remove duplicated text and reword on the camera up vector (#420) 72 | 73 | 74 | ---------------------------------------------------------------------------------------------------- 75 | # v3.0.0 (2020-03-23) 76 | 77 | With the migration to a web format accomplished in v2.0.0, we immediately began work on a new major 78 | release: v3.0.0. This release tackles the following key themes: 79 | 80 | - Establishing a common build system for the three projects. We chose CMake for its broad support 81 | for multiple platforms, as well as multiple build tools and IDEs. This change includes a 82 | reorganization of the project source files, and unifying a lot of code across projects. 83 | 84 | - A major upgrade of the project source code, addressing a number of large changes that we had 85 | deferred for later. 86 | 87 | - A number of larger changes to the book content, refining some approaches and ideas, and 88 | addressing some areas in the text that needed improvement. 89 | 90 | Following this release, we expect to switch to a much more incremental approach, mostly with 91 | patch-level (fix) changes and some minor-level (addition) changes. 92 | 93 | ### Common to All Project Source 94 | - Change: Default floating-point type changed from `float` to `double` (#150) 95 | - Change: Materials are now referenced with `std::shared_ptr` pointers 96 | - Change: Complete elimination of bare pointers and `new`/`delete` 97 | - Change: `hittable_list` uses `std::vector` plus `std::shared_ptr` pointers 98 | - Change: Header cleanup across the source code (#218, #220) 99 | - Change: Cleaned up standard C++ header use (#19) 100 | - Change: Improved random number generator utilities 101 | - Change: Replace MAXFLOAT with (portable) infinity (#195, #216) 102 | - Change: A _lot_ of code cleanup, refactoring, renaming (#192) 103 | - Change: Disable compile warnings for external `stb_image.h` on Windows 104 | - Change: Replace pi with portable version (#207) 105 | - Change: `ray_color()` function now has max depth passed in, rather than hard-coding it (#143) 106 | - Change: Added `random_in_unit_sphere()`, `random_unit_vector()`, `random_in_hemisphere()` to 107 | vec3.h. Fixed places where we were using one but should have been using another. (#145) 108 | - Change: General rework of the `vec3` header (#153, #156, #215) 109 | - Change: Clarify sphere intersection code, plus slight perf improvement (#113) 110 | - Change: `ray::point_at_parameter()` renamed to `ray::at()` 111 | - Change: Moved `ffmin()`, `ffmax()` from `aabb.h` to `rtweekend.h` 112 | - Change: Move low-level utility functions to more appropriate headers 113 | - Change: `squared_length()` renamed to `length_squared()` 114 | - Change: Update `sphere::hit()` function. 115 | - Change: Refraction variables renamed to match reflection variable names 116 | - Change: Simplify lambertian scatter direction calculation 117 | - New: CMake configuration & build 118 | - New: Added progress output for main programs (#139) 119 | - New: `src/common` directory for code shared across books 120 | - New: Common project-wide header: `src/common/rtweekend.h` 121 | - New: File constants.h with portable math constants (#151) 122 | - New: `vec3::write_color` - provides a robust output method for color data (#93) 123 | - New: `degrees_to_radians()` utility function (#217) 124 | - New: `random_int()`, `random_double()`, and `vec3::random()` utility functions 125 | - New: Added safety value when surface texture has null data 126 | - New: Main programs now define and handle parameterized background color 127 | - Fix: Diffuse PDF computation uses random point _on_ sphere, rather than _inside_ 128 | - Fix: Improve color [0,1] -> [0,255] mapping 129 | 130 | ### Common to All Books 131 | - Change: Code in source and in book reformatted to a consistent 96-column line length (#219) 132 | - Change: Lots more highlighting of changed code in books to aid reading 133 | - Change: Math typesetting fixes throughout the books (#13) 134 | - Change: Books now use Markdeep's chapter indirection syntax 135 | - Change: Updated several output images to match code updates 136 | - Change: Books general styling improvements (#197) 137 | - Change: Refactored acknowledgements. These are now moved to and duplicated in each book 138 | - New: Added code listing captions, including source file name, for all books (#238) 139 | - New: Added captions to all figures (#238) 140 | - New: Local copy of `markdeep.min.js` for offline reading 141 | - Fix: Fixed various minor problems in the text 142 | 143 | ### _In One Weekend_ 144 | - Change: Reworked Lambertian reflection text (#155) 145 | - Change: Revised the figure for computing a random reflection vector (#142) 146 | - New: Clarified text around the ideal Lambertian distribution (#155) 147 | - New: Additional explanatory text to the dielectric chapter 148 | - New: Image for hemispherical rendering 149 | - New: Image for dealing with front and back faces (#326) 150 | - Fix: Update `ray_color()` code blocks to match current source (#391) 151 | 152 | ### _The Next Week_ 153 | - Change: Added proper handling of front vs back face intersection (#270) 154 | - New: "The Next Week" main program added swtich statement for different scenes 155 | - New: "The Next Week" main program now defines all image/camera parameters for each scene 156 | - Fix: Fixed bug in `noise_texture::value()` (#396) 157 | - Fix: Correct first Perlin noise() function in "The Next Week". 158 | - Fix: Fix OCR error in `texture::value()` function (#399) 159 | - Fix: Remove premature declaration of `moving_sphere::bounding_box()` (#405) 160 | 161 | ### _The Rest of Your Life_ 162 | - Change: Improved naming of auxilliary programs in _The Rest of Your Life_ source 163 | - Fix: Delete unused variable `p` in main() (#317) 164 | - Deleted: Several unused source files from `src/TheRestOfYourLife` 165 | 166 | 167 | ---------------------------------------------------------------------------------------------------- 168 | # v2.0.0 (2019-10-07) 169 | 170 | This major release marks an overhaul of the entire series, moving from a primarily PDF format to a 171 | web accessible format using Markdeep (https://casual-effects.com/markdeep/). This represents a huge 172 | overhaul to the contents, particularly around source code blocks in the text, mathematical 173 | typesetting and source-code cleanup. 174 | 175 | ### Common 176 | - Change: Moved existing _InOneWeekend_, _TheNextWeek_, _TheRestOfYourLife_ content to io repo 177 | - Change: Rewrote vec3.h `cross` function for clarity 178 | - New: General release to web 179 | - New: Created single monolithic raytracing.github.io repo 180 | - New: License change to CC0 in COPYING.txt 181 | - New: CHANGELOG.md 182 | - New: CONTRIBUTING.md 183 | - New: COPYING.txt 184 | - New: README.md 185 | - New: raytracing.github.io links to all the three books 186 | - New: CSS for all books 187 | - New: CSS for the print variant of the books 188 | - Fix: All instances of `hitable` have become `hittable` 189 | - Fix: Replaced `drand48()` with portable `random_double` number generation 190 | - Delete: Deprecated existing _InOneWeekend_, _TheNextWeek_, _TheRestOfYourLife_ repos 191 | 192 | ### _In One Weekend_ 193 | - Change: README files updated for top level, source, and books 194 | - Change: Text, Chapter 0 Overview has become Chapter 1, all subsequent chapters incremented 195 | - Change: Text, Syntax highlighting of source modifications 196 | - Change: Text, Chapter 3, Reorder include files in code blocks to match src conventions 197 | - Change: Text, Chapter 3, Consistent use of spaces in code blocks 198 | - Change: Text, Chapter 3, Reordered `vec3` class functions to + - * / 199 | - Change: Text, Chapter 4, Reorder include files in code blocks to match src conventions 200 | - Change: Text, Chapter 6, Reorder include files in code blocks to match src conventions 201 | - Change: Text, Chapter 6, Consistent use of spaces in code blocks 202 | - Change: Text, Chapter 7, Consistent use of spaces in code blocks 203 | - Change: Text, Chapter 9, Consistent use of spaces in code blocks 204 | - Change: Text, Chapter 9, Put function signatures and `{` on the same line 205 | - Change: Text, Chapter 10, Consistent use of spaces in code blocks 206 | - Change: Text, Chapter 10, Put function signatures and `{` on the same line 207 | - Change: Text, Chapter 11, Consistent use of spaces in code blocks 208 | - Change: Text, Chapter 13, Put function signatures and `{` on the same line 209 | - New: Markdeep page created for entire body of text 210 | - New: Markdeep MathJax for formulae and equations for body of text 211 | - New: raytracing.github.io/books/RayTracingInOneWeekend.html 212 | - Fix: Text, Chapter 7, Add `#include "random.h"` in code blocks 213 | - Fix: Text, Chapter 10, Added metal fuzziness parameter for initial dielectric 214 | - Fix: Text, Chapter 13, Added metal fuzziness parameter 215 | - Fix: Code, Removed extraneous `;` from `vec3::&operator[]` signature 216 | - Delete: Code, `vec3 p = r.point_at_parameter(2.0);` in main.cc 217 | 218 | ### _The Next Week_ 219 | - Change: Text, Chapter 0 Overview has become Chapter 1, all subsequent chapters incremented 220 | - Change: Text, Syntax highlighting of source modifications 221 | - Change: Text, Chapter 2, Consistent use of spaces in code blocks 222 | - Change: Text, Chapter 3, Consistent use of spaces in code blocks 223 | - Change: Text, Chapter 4, Consistent use of spaces in code blocks 224 | - Change: Text, Chapter 5, Consistent use of spaces in code blocks 225 | - Change: Text, Chapter 5, added "texture" to "We can use that texture on some spheres" 226 | - Change: Text, Chapter 7, Consistent use of spaces in code blocks 227 | - Change: Text, Chapter 7, "This is yz and xz" changed to "This is xz and yz" 228 | - Change: Text, Chapter 8, Changed "And the changes to Cornell is" to "... Cornell are" 229 | - Change: Text, Chapter 9, Changed short `if` statements to two lines for Consistency 230 | - Change: Text, Chapter 10, Consistent use of spaces in code blocks 231 | - Change: Code and Text, Chapter 9, cleaned up implementation of `constant_medium::hit` 232 | - Change: Code and Text, Chapter 9, Rewrote debug functionality in `constant_medium::hit` 233 | - New: raytracing.github.io/books/RayTracingTheNextWeek.html 234 | - New: README.md, source README.md 235 | - New: Markdeep page created for entire body of text 236 | - New: Markdeep MathJax created for formulae and equations for body of text 237 | - New: Earth map picture for use in rendering 238 | - Fix: Text, Chapter 2, The `lambertian` class definition now uses `vec3` instead of `texture` 239 | - Fix: Text, Chapter 7, Changed `cornell_box` hittable array size to 5 240 | - Fix: Code and Text, Chapter 3, Changed `List[0]` to `List[i]` in `hittable_list::bounding_box()` 241 | - Fix: Code and Text, Chapter 3, Replaced `fmax` and `fmin` with `ffmax` and `ffmin` 242 | - Fix: Code, Add missing headers to `constant_medium.h` to fix g++ compiler error 243 | 244 | ### _The Rest of Your Life_ 245 | - Change: Text, Chapter 0 Overview has become Chapter 1, all subsequent chapters incremented 246 | - Change: Text, Syntax highlighting of source modifications 247 | - Change: Text, Chapter 2, Reorder include files in code blocks to match src conventions 248 | - Change: Text, Chapter 3, Reorder include files in code blocks to match src conventions 249 | - Change: Text, Chapter 6, Consistent use of spaces in code blocks 250 | - Change: Text, Chapter 6, Consistent use of spaces in code blocks 251 | - Change: Text, Chapter 8, Changed calculation of `a` axis to pseudocode 252 | - Change: Text, Chapter 8, Consistent use of spaces in code blocks 253 | - New: raytracing.github.io/books/RayTracingTheRestOfYourLife.html 254 | - New: README.md, source README.md 255 | - New: Markdeep page created for entire body of text 256 | - New: Markdeep MathJax created for formulae and equations for body of text 257 | - Fix: Text, Chapter order starting from chapter 2 258 | - Fix: Text, Renamed figures and images to match new chapter numbering 259 | - Fix: Text, Chapter 4, Rewrote formula for "Color" to "Color = A * color(direction" 260 | - Fix: Code and Text, Chapter 6, `material::scattering_pdf` now returns type float 261 | - Fix: Code and Text, Chapter 6, removal of factor of 2 to `random_cosine_direction` calculation 262 | 263 | 264 | ---------------------------------------------------------------------------------------------------- 265 | # v1.123.0 (2018-08-26) 266 | 267 | - New: First GitHub release of _Ray Tracing: The Rest of Your Life_. 268 | 269 | 270 | ---------------------------------------------------------------------------------------------------- 271 | # v1.54.0 (2018-08-26) 272 | 273 | - New: First GitHub release of _Ray Tracing in One Weekend_. 274 | 275 | 276 | ---------------------------------------------------------------------------------------------------- 277 | # v1.42.0 (2018-08-26) 278 | 279 | - New: First GitHub release of _Ray Tracing: The Next Week_. 280 | 281 | --------------------------------------------------------------------------------