From 53a09f64205e4c027846d91313c4f8ee47dd3f87 Mon Sep 17 00:00:00 2001 From: Steve Hollasch Date: Fri, 25 Oct 2019 12:01:03 -0700 Subject: [PATCH 1/6] Add listing captions --- books/RayTracingInOneWeekend.html | 102 +++++++++++------ books/RayTracingTheNextWeek.html | 99 +++++++++++++++-- books/RayTracingTheRestOfYourLife.html | 146 +++++++++++++++++-------- 3 files changed, 258 insertions(+), 89 deletions(-) diff --git a/books/RayTracingInOneWeekend.html b/books/RayTracingInOneWeekend.html index fddde399..ff6f0b04 100644 --- a/books/RayTracingInOneWeekend.html +++ b/books/RayTracingInOneWeekend.html @@ -88,6 +88,7 @@ } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [main-initial]: [main.cc] Creating your first image] There are some things to note in that code: @@ -137,6 +138,7 @@ 14 253 51 15 253 51 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [first-img]: First image output] If it doesn’t, then you probably just have some newlines or something similar that is confusing the @@ -212,6 +214,7 @@ double e[3]; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [vec3-class]: [vec3.h] `vec3` class] We use `double` here, but some ray tracers use `float`. Either one is fine -- follow your own @@ -264,6 +267,7 @@ return v / v.length(); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [vec3-utility]: [vec3.h] vec3 utility functions]
Now we can change our main to use this: @@ -289,6 +293,7 @@ } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [main-gradient]: [main.cc] Creating a color gradient image]
@@ -315,13 +320,12 @@ #include "common/vec3.h" - class ray - { + class ray { public: ray() {} ray(const vec3& a, const vec3& b) { A = a; B = b; } - vec3 origin() const { return A; } - vec3 direction() const { return B; } + vec3 origin() const { return A; } + vec3 direction() const { return B; } vec3 point_at_parameter(double t) const { return A + t*B; } vec3 A; @@ -330,6 +334,7 @@ #endif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-initial]: [main.cc] The ray class] Now we are ready to turn the corner and make a ray tracer. At the core of a ray tracer is to send @@ -387,6 +392,7 @@ } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [main-blue-white-blend]: [main.cc] Rendering a blue-to-white gradient]
@@ -496,6 +502,7 @@ return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [main-red-sphere]: [main.cc] Rendering a red sphere]
@@ -569,6 +576,7 @@ return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [render-surface-normal]: [main.cc] Rendering surface normals on a sphere]
@@ -586,6 +594,7 @@ auto c = dot(oc, oc) - radius*radius; auto discriminant = b*b - 4*a*c; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-sphere-before]: [main.cc] Ray-sphere intersection code (before)] First, recall that a vector dotted with itself is equal to the squared length of that vector. @@ -616,6 +625,7 @@ return (-half_b - sqrt(discriminant) ) / a; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-sphere-after]: [main.cc] Ray-sphere intersection code (after)] Now, how about several spheres? While it is tempting to have an array of spheres, a very clean @@ -647,7 +657,7 @@ vec3 normal; }; - class hittable { + class hittable { public: virtual bool hit( const ray& r, double t_min, double t_max, hit_record& rec) const = 0; @@ -655,6 +665,7 @@ #endif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [hittable-initial]: [hittable.h] The hittable class]
@@ -667,10 +678,10 @@ #include "common/vec3.h" #include "hittable.h" - class sphere: public hittable { + class sphere: public hittable { public: sphere() {} - sphere(vec3 cen, double r) : center(cen), radius(r) {}; + sphere(vec3 cen, double r) : center(cen), radius(r) {}; virtual bool hit( const ray& r, double tmin, double tmax, hit_record& rec) const; vec3 center; @@ -707,6 +718,7 @@ #endif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [sphere-initial]: [sphere.h] The sphere class]
@@ -747,6 +759,7 @@ #endif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [hittable-list-initial]: [hittable_list.h] The hittable_list class]
@@ -785,7 +798,7 @@ #endif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + [Listing [rtweekend-initial]: [common/rtweekend.h] The rtweekend.h common header]
@@ -851,6 +864,7 @@ } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [main-with-rtweekend-h]: [main.cc] desc]
@@ -890,7 +904,7 @@ return rand() / (RAND_MAX + 1.0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - + [Listing [random-double]: [rtweekend.h] random_double() function]
@@ -910,6 +924,7 @@ return rand_generator(); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [random-double-alt]: [file] random_double(), alternate implemenation]
@@ -951,6 +966,7 @@ }; #endif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [camera-initial]: [camera.h] The camera class]
To handle the multi-sampled color computation, we update the `vec3::write_color()` function. Rather @@ -966,6 +982,7 @@ return x; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [clamp]: [rtweekend.h] The clamp() utility function] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ void write_color(std::ostream &out, int num_samples) { @@ -981,6 +998,7 @@ << static_cast(256.0 * clamp(b, 0.0, 0.999999)) << '\n'; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [write-color-clamped]: [vec3.h] The write_color() function]
Main is also changed: @@ -1018,6 +1036,7 @@ } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [main-multi-sample]: [main.cc] Rendering with multi-sampled pixels]
@@ -1079,6 +1098,7 @@ return vec3(r * cos(a), r * sin(a), z); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [random-unit-vec]: [material.h] The random_unit_vector() function]
@@ -1100,6 +1120,7 @@ } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-color-random-unit]: [main.cc] ray_color() using a random ray direction]
@@ -1136,6 +1157,7 @@ << static_cast(256.0 * clamp(b, 0.0, 0.999999)) << '\n'; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [write-color-gamma]: [vec3.h] write_color(), with gamma correction]
@@ -1154,6 +1176,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ if (world->hit(r, 0.001, infinity, rec)) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [reflect-tolerance]: [main.cc] Calculating reflected ray origins with tolerance] This gets rid of the shadow acne problem. Yes it is really called that. @@ -1176,13 +1199,14 @@ This suggests the abstract class: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - class material { + class material { public: virtual bool scatter( const ray& r_in, const hit_record& rec, vec3& attenuation, ray& scattered) const = 0; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [material-initial]: [material.h] The material class]
@@ -1198,13 +1222,17 @@ #include "common/rtweekend.h" #include "ray.h" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight class material; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ struct hit_record { double t; vec3 p; vec3 normal; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight material *mat_ptr; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ }; class hittable { @@ -1215,6 +1243,7 @@ #endif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [hit-with-material]: [hittable.h] Hit record with added material pointer]
What we have set up here is that material will tell us how rays interact with the surface. @@ -1229,11 +1258,11 @@ within `hit_record`. See the highlighted lines below: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - class sphere: public hittable { + class sphere: public hittable { public: sphere() {} sphere(vec3 cen, double r, material *m) - : center(cen), radius(r), mat_ptr(m) {}; + : center(cen), radius(r), mat_ptr(m) {}; virtual bool hit( const ray& r, double tmin, double tmax, hit_record& rec) const; vec3 center; @@ -1276,6 +1305,7 @@ return false; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [sphere-material]: [sphere.h] Ray-sphere intersection with added material information]
@@ -1299,6 +1329,7 @@ vec3 albedo; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [lambertian-initial]: [material.h] The lambertian material class]
Note we could just as well only scatter with some probability $p$ and have attenuation be @@ -1323,6 +1354,7 @@ return v - 2*dot(v,n)*n; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [vec3-reflect]: [material.h] vec3 reflection function]
@@ -1342,6 +1374,7 @@ vec3 albedo; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [metal-material]: [material.h] Metal material with reflectance function]
@@ -1369,6 +1402,7 @@ } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-color-scatter]: [main.cc] Ray color with scattered reflectance]
@@ -1407,6 +1441,7 @@ } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-with-metal]: [main.cc] Scene with metal spheres]
@@ -1464,6 +1499,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [metal-fuzz]: [main.cc] Metal spheres with fuzziness] In order to generate a random point inside a unit sphere (`random_in_unit_sphere()`), we used one of the easiest algorithms: a rejection method. First, pick a random point in the unit cube where x, y, @@ -1532,6 +1568,7 @@ return false; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [refract]: [material.h] Refraction function]
@@ -1572,6 +1609,7 @@ double ref_idx; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [dielectric]: [material.h] Dielectric material class]
Attenuation is always 1 -- the glass surface absorbs nothing. The `attenuation = vec3(1.0, 1.0, @@ -1588,6 +1626,7 @@ list[2] = new sphere(vec3(1,0,-1), 0.5, new metal(vec3(0.8, 0.6, 0.2), 0.0)); list[3] = new sphere(vec3(-1,0,-1), 0.5, new dielectric(1.5)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-dielectric]: [main.cc] Scene with dielectric sphere] We get: @@ -1613,6 +1652,7 @@ return r0 + (1-r0)*pow((1 - cosine),5); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [schlick]: [material.h] Schlick approximation]
@@ -1675,6 +1715,7 @@ double ref_idx; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [glass]: [material.h] Full glass material]
@@ -1689,6 +1730,7 @@ list[3] = new sphere(vec3(-1,0,-1), 0.5, new dielectric(1.5)); list[4] = new sphere(vec3(-1,0,-1), -0.45, new dielectric(1.5)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-hollow-glass]: [main.cc] Scene with hollow glass sphere]
@@ -1721,14 +1763,9 @@ This implies $h = \tan(\frac{\theta}{2})$. Our camera now becomes: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - #ifndef CAMERA_H - #define CAMERA_H - - #include "common/rtweekend.h" - #include "ray.h" - class camera { public: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight camera( double vfov, // vfov is top to bottom in degrees double aspect @@ -1741,6 +1778,7 @@ vertical = vec3(0.0, 2*half_height, 0.0); origin = vec3(0.0, 0.0, 0.0); } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ ray get_ray(double u, double v) { return ray(origin, @@ -1752,8 +1790,8 @@ vec3 horizontal; vec3 vertical; }; - #endif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [camera-fov]: [camera.h] Camera with adjustable field-of-view (fov)]
@@ -1765,6 +1803,7 @@ list[1] = new sphere(vec3( R,0,-1), R, new lambertian(vec3(1, 0, 0))); hittable *world = new hittable_list(list,2); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-wide-angle]: [main.cc] Scene with wide-angle camera] gives: @@ -1796,22 +1835,16 @@ camera horizontally level until you decide to experiment with crazy camera angles. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - #ifndef CAMERA_H - #define CAMERA_H - - #include "common/rtweekend.h" - #include "ray.h" - class camera { public: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight camera( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight vec3 lookfrom, vec3 lookat, vec3 vup, + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ double vfov, // vfov is top to bottom in degrees double aspect ) { vec3 u, v, w; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ auto theta = degrees_to_radians(vfov); auto half_height = tan(theta/2); auto half_width = aspect * half_height; @@ -1836,8 +1869,8 @@ vec3 horizontal; vec3 vertical; }; - #endif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [camera-orient]: [camera.h] Positionable and orientable camera]
This allows us to change the viewpoint: @@ -1845,6 +1878,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ camera cam(vec3(-2,2,1), vec3(0,0,-1), vec3(0,1,0), 90, double(nx)/ny); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-free-view]: [main.cc] Scene with alternate viewpoint] to get: @@ -1893,12 +1927,6 @@ point: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - #ifndef CAMERA_H - #define CAMERA_H - - #include "common/rtweekend.h" - #include "ray.h" - vec3 random_in_unit_disk() { vec3 p; do { @@ -1909,10 +1937,10 @@ class camera { public: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight camera( vec3 lookfrom, vec3 lookat, vec3 vup, double vfov, // vfov is top to bottom in degrees + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight double aspect, double aperture, double focus_dist ) { lens_radius = aperture / 2; @@ -1953,8 +1981,8 @@ double lens_radius; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ }; - #endif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [camera-dof]: [camera.h] Camera with adjustable depth-of-field (dof)]
@@ -1968,6 +1996,7 @@ camera cam(lookfrom, lookat, vec3(0,1,0), 20, double(nx)/ny, aperture, dist_to_focus); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-camera-dof]: [main.cc] Scene camera with depth-of-field] We get: @@ -2023,6 +2052,7 @@ return new hittable_list(list,i); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-final]: [main.cc] Final scene]
diff --git a/books/RayTracingTheNextWeek.html b/books/RayTracingTheNextWeek.html index 34115769..07655de0 100644 --- a/books/RayTracingTheNextWeek.html +++ b/books/RayTracingTheNextWeek.html @@ -62,8 +62,7 @@ For this we will first need to have a ray store the time it exists at: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - class ray - { + class ray { public: ray() {} ray(const vec3& a, const vec3& b, double ti = 0.0) { @@ -82,6 +81,7 @@ }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [time-ray]: [ray.h] Ray with time information]
Now we need to modify the camera to generate rays at a random time between `time1` and `time2`. @@ -143,6 +143,7 @@ }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [time-camera]: [camera.h] Camera with time information] We also need a moving object. I’ll create a sphere class that has its center move linearly from `center0` at `time0` to `center1` at `time1`. Outside that time interval it continues on, so those @@ -170,6 +171,7 @@ return center0 + ((time - time0) / (time1 - time0))*(center1 - center0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [moving-sphere]: [moving_sphere.h] A moving sphere]
An alternative to making a new moving sphere class is to just make them all move and have the @@ -215,6 +217,7 @@ return false; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [moving-sphere-hit]: [moving-sphere.h] Moving sphere hit function]
@@ -239,6 +242,7 @@ vec3 albedo; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [lambertian-animate]: [material.h] Lambertian matrial for moving objects]
@@ -295,10 +299,12 @@ return new hittable_list(list,i); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-spheres-moving]: + [main.cc] Last book's final scene, but with moving spheres]
-And with these viewing parameters gives: +And with these viewing parameters: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ vec3 lookfrom(13,2,3); @@ -311,6 +317,9 @@ dist_to_focus, 0.0, 1.0 ); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-spheres-moving-camera]: [main.cc] Viewing parameters] + +gives the following result: ![Image 2-1](../images/img-2-2-01.jpg) @@ -547,6 +556,7 @@ vec3 _max; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [aabb]: [aabb.h] Axis-aligned bounding box class]
@@ -571,6 +581,7 @@ return true; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [aabb-hit]: [aabb.h] Axis-aligned bounding box hit function]
@@ -588,6 +599,7 @@ virtual bool bounding_box(double t0, double t1, aabb& box) const = 0; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [hittable-bbox]: [hittable.h] Hittable class with bounding-box]
@@ -600,6 +612,7 @@ return true; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [sphere-bbox]: [sphere.h] Sphere with bounding box]
@@ -616,6 +629,7 @@ return true; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [moving-sphere-bbox]: [moving_sphere.h] Moving sphere with bounding box]
@@ -641,6 +655,7 @@ return true; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [hit-list-bbox]: [hittable_list.h] Hittable list with bounding box]
@@ -658,6 +673,7 @@ return aabb(small,big); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [surrounding-box]: [aabb.h] Surrounding bounding box]
@@ -687,6 +703,7 @@ return true; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [bvh]: [bvh.h] Bounding volume hierarchy]
Note that the children pointers are to generic hittables. They can be other `bvh_nodes`, or @@ -723,6 +740,7 @@ else return false; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [bvh-hit]: [bvh.h] Bounding volume hierarchy hit function]
@@ -785,6 +803,7 @@ box = surrounding_box(box_left, box_right); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [bvh-node]: [bvh.h] Bounding volume hierarchy node]
The check for whether there is a bounding box at all is in case you sent in something like an @@ -810,6 +829,7 @@ return 1; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [bvh-x-comp]: [bvh.h] BVH comparison function, X-axis] @@ -838,6 +858,7 @@ vec3 color; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [texture]: [texture.h] A texture class]
Now we can make textured materials by replacing the vec3 color with a texture pointer: @@ -845,20 +866,27 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ class lambertian : public material { public: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight lambertian(texture *a) : albedo(a) {} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ virtual bool scatter( const ray& r_in, const hit_record& rec, vec3& attenuation, ray& scattered ) const { vec3 target = rec.p + rec.normal + random_unit_vector(); scattered = ray(rec.p, target - rec.p); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight attenuation = albedo->value(0, 0, rec.p); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ return true; } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight texture *albedo; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [lambertian-textured]: [material.h] Lambertian material with texture]
@@ -867,12 +895,14 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ new lambertian(vec3(0.5, 0.5, 0.5))) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [lam-solid]: [main.cc] Lambertian material with solid color] now you should replace the `vec3(...)` with `new constant_texture(vec3(...))` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ new lambertian(new constant_texture(vec3(0.5, 0.5, 0.5)))) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [lam-textured]: [main.cc] Lambertian material with texture]
@@ -896,6 +926,7 @@ texture *even; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [checker-texture]: [texture.h] Checkered texture]
Those checker odd/even pointers can be to a constant texture or to some other procedural texture. @@ -911,6 +942,7 @@ ); list[0] = new sphere(vec3(0,-1000,0), 1000, new lambertian(checker)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [checker-example]: [main.cc] Checkered texture in use] We get: @@ -934,6 +966,7 @@ return new hittable_list(list,2); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-two-checker]: [main.cc] Scene with two checkered spheres] With camera: @@ -946,6 +979,7 @@ camera cam(lookfrom, lookat, vec3(0,1,0), 20, double(nx)/ny, aperture, dist_to_focus, 0.0, 1.0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-two-checker-view]: [main.cc] Viewing parameters] We get: @@ -1035,6 +1069,7 @@ int *perlin::perm_y = perlin_generate_perm(); int *perlin::perm_z = perlin_generate_perm(); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [perlin]: [perlin.h] A Perlin texture class and functions]
@@ -1051,6 +1086,7 @@ perlin noise; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [noise-texture]: [texture.h] Noise texture]
@@ -1065,6 +1101,7 @@ return new hittable_list(list, 2); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-perlin]: [main.cc] Scene with two Perlin-textured spheres]
@@ -1078,6 +1115,7 @@ camera cam(lookfrom, lookat, vec3(0,1,0), 20, double(nx)/ny, aperture, dist_to_focus, 0.0, 1.0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-perlin-view]: [main.cc] Viewing parameters]
@@ -1128,6 +1166,7 @@ static int *perm_z; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [perlin-trilinear]: [perlin.h] Perlin with trilienear interpolation]
@@ -1161,6 +1200,7 @@ int k = floor(p.z()); ... ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [perlin-smoothed]: [perlin.h] Perlin smoothed]
@@ -1189,6 +1229,7 @@ double scale; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [perlin-smoothed-2]: [perlin.h] Perlin smoothed, higher frequency] which gives: @@ -1208,6 +1249,7 @@ int *perlin::perm_y = perlin_generate_perm(); int *perlin::perm_z = perlin_generate_perm(); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [perlin-randunit]: [perlin.h] Perlin with random unit translations]
@@ -1226,6 +1268,7 @@ return p; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [perlin-gen-2]: [perlin.h] New perlin_generate()]
@@ -1258,6 +1301,7 @@ static int *perm_z; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [perlin-2]: [perlin.h] The perlin class so far]
@@ -1280,6 +1324,7 @@ return accum; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [perlin-interp]: [perlin.h] Perlin interpolation function so far]
@@ -1306,6 +1351,7 @@ return fabs(accum); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [perlin-turb]: [perlin.h] Turbulence function]
Here `fabs()` is the `math.h` absolute value function. @@ -1340,6 +1386,7 @@ double scale; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [noise-tex-2]: [texture.h] Noise texture with turbulence] Which yields: @@ -1411,6 +1458,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ get_sphere_uv((rec.p-center)/radius, rec.u, rec.v); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [get-sphere-uv-call]: [sphere.h] Sphere UV coordinates from hit]
@@ -1424,6 +1472,7 @@ v = (theta + pi/2) / pi; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [get-sphere-uv]: [sphere.h] get_sphere_uv function]
Now we also need to create a texture class that holds an image. I am going to use my favorite image @@ -1454,6 +1503,7 @@ return vec3(r, g, b); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [img-texture]: [surface_texture.h] Image texture class]
The representation of a packed array in that order is pretty standard. Thankfully, the `stb_image` @@ -1462,6 +1512,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ #include "common/rtw_stb_image.h" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [incl-stb-img]: Including the STB image package]
@@ -1477,6 +1528,7 @@ unsigned char *tex_data = stbi_load("earthmap.jpg", &nx, &ny, &nn, 0); material *mat = new lambertian(new image_texture(tex_data, nx, ny)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [stbi-load-use]: [main.cc] Using stbi_load() to load an image]
We start to see some of the power of all colors being textures -- we can assign any kind of texture @@ -1497,8 +1549,8 @@
First, let’s make a light emitting material. We need to add an emitted function (we could also add -it to hit_record instead -- that’s a matter of design taste). Like the background, it just tells the -ray what color it is and performs no reflection. It’s very simple: +it to `hit_record instead` -- that’s a matter of design taste). Like the background, it just tells +the ray what color it is and performs no reflection. It’s very simple: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ class diffuse_light : public material { @@ -1512,6 +1564,7 @@ texture *emit; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [diffuse-light]: [material.h] A diffuse light class]
@@ -1523,11 +1576,14 @@ public: virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& attenuation, ray& scattered) const = 0; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight virtual vec3 emitted(double u, double v, const vec3& p) const { return vec3(0,0,0); } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [matl-emit]: [material.h] New emitted function in class material]
@@ -1539,6 +1595,7 @@ if (world->hit(r, 0.001, infinity, rec)) { ray scattered; vec3 attenuation; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight vec3 emitted = rec.mat_ptr->emitted(rec.u, rec.v, rec.p); if (depth < 50 && rec.mat_ptr->scatter(r, rec, attenuation, scattered)) return emitted + attenuation * ray_color(scattered, world, depth+1); @@ -1547,8 +1604,10 @@ } else return vec3(0,0,0); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-color-emitted]: [main.cc] ray_color function for emitting materials]
Now, let’s make some rectangles. Rectangles are often convenient for modelling man-made @@ -1601,6 +1660,7 @@ double x0, x1, y0, y1, k; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [xy-rect]: [aarect.h] XY-plane rectangle objects]
@@ -1624,6 +1684,7 @@ return true; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [xy-rect-hit]: [aarect.h] Hit function for XY rectangle objects]
@@ -1642,6 +1703,7 @@ return new hittable_list(list,4); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [rect-light]: [main.cc] A simple rectangle light]
@@ -1698,6 +1760,7 @@ double y0, y1, z0, z1, k; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [xz-yz-rects]: [aarect.h] XZ and YZ rectangle objects]
@@ -1738,6 +1801,7 @@ return true; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [xz-yz]: [aarect.h] XZ and YZ rectangle object hit functions]
@@ -1761,6 +1825,7 @@ return new hittable_list(list,i); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [cornell-box-empty]: [main.cc] Cornell box scene, empty]
@@ -1776,6 +1841,7 @@ camera cam(lookfrom, lookat, vec3(0,1,0), vfov, double(nx)/ny, aperture, dist_to_focus, 0.0, 1.0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [cornell-box-view]: [main.cc] Viewing parameters]
@@ -1813,6 +1879,7 @@ hittable *ptr; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [flip-normals]: [hittable.h] Flip-normals function]
@@ -1827,16 +1894,23 @@ material *green = new lambertian(new constant_texture(vec3(0.12, 0.45, 0.15))); material *light = new diffuse_light(new constant_texture(vec3(15, 15, 15))); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight list[i++] = new flip_normals(new yz_rect(0, 555, 0, 555, 555, green)); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ list[i++] = new yz_rect(0, 555, 0, 555, 0, red); list[i++] = new xz_rect(213, 343, 227, 332, 554, light); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight list[i++] = new flip_normals(new xz_rect(0, 555, 0, 555, 555, white)); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ list[i++] = new xz_rect(0, 555, 0, 555, 0, white); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight list[i++] = new flip_normals(new xy_rect(0, 555, 0, 555, 555, white)); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ return new hittable_list(list,i); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [cornell-box-flipped]: [main.cc] Empty Cornell box with flipped rectangles]
@@ -1888,6 +1962,7 @@ return list_ptr->hit(r, t0, t1, rec); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [box-class]: [box.h] A box object]
Now we can add two blocks (but not rotated) @@ -1896,6 +1971,7 @@ list[i++] = new box(vec3(130, 0, 65), vec3(295, 165, 230), white); list[i++] = new box(vec3(265, 0, 295), vec3(430, 330, 460), white); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [add-boxes]: [main.cc] Adding box objects]
@@ -1954,6 +2030,7 @@ return false; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [translate-class]: [hittable.h] Hittable translation class]
@@ -2016,6 +2093,7 @@ aabb bbox; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [rot-y]: [hittable.h] Hittable rotate-Y class]
@@ -2038,8 +2116,7 @@ auto newx = cos_theta*x + sin_theta*z; auto newz = -sin_theta*x + cos_theta*z; vec3 tester(newx, y, newz); - for (int c = 0; c < 3; c++) - { + for (int c = 0; c < 3; c++) { if (tester[c] > max[c]) max[c] = tester[c]; if (tester[c] < min[c]) @@ -2051,6 +2128,7 @@ bbox = aabb(min, max); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [rot-y-rot]: [hittable.h] Rotate-Y rotate method]
@@ -2080,6 +2158,7 @@ return false; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [rot-y-hit]: [hittable.h] Hittable Y-rotate hit function]
@@ -2095,6 +2174,7 @@ vec3(265,0,295) ); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-rot-y]: [main.cc] Cornell scene with Y-rotated boxes]
@@ -2153,6 +2233,7 @@ material *phase_function; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [const-med-class]: [constant_medium.h] Constant medium class]
@@ -2175,6 +2256,7 @@ texture *albedo; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [isotropic-class]: [material.h] The isotropic class]
@@ -2230,6 +2312,7 @@ return false; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [const-med-hit]: [constant_medium.h] Constant medium hit method]
The reason we have to be so careful about the logic around the boundary is we need to make sure this @@ -2271,6 +2354,7 @@ return new hittable_list(list,i); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [cornell-smoke]: [main.cc] Cornell box, with smoke]
@@ -2345,6 +2429,7 @@ return new hittable_list(list,l); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-final]: [main.cc] Final scene]
Running it with 10,000 rays per pixel yields: diff --git a/books/RayTracingTheRestOfYourLife.html b/books/RayTracingTheRestOfYourLife.html index 2694149e..fe56dd74 100644 --- a/books/RayTracingTheRestOfYourLife.html +++ b/books/RayTracingTheRestOfYourLife.html @@ -90,6 +90,7 @@ std::cout << "Estimate of Pi = " << 4*double(inside_circle) / N << "\n"; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [estpi-1]: [pi.cc] Estimating π]
This gives me the answer `Estimate of Pi = 3.196` @@ -122,6 +123,7 @@ } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [estpi-2]: [pi.cc] Estimating π, v2]
@@ -165,6 +167,7 @@ 4*double(inside_circle_stratified) / (sqrt_N*sqrt_N) << "\n"; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [estpi-3]: [pi.cc] Estimating π, v3] I get: @@ -207,6 +210,12 @@ This suggests a MC approach: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + #include "common/rtweekend.h" + + #include + #include + #include + int main() { int inside_circle = 0; int inside_circle_stratified = 0; @@ -219,6 +228,7 @@ std::cout << "I =" << 2*sum/N << "\n"; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [integ-xsq-1]: [integrate_x_sq.cc] Integrating $x^2$]
This, as expected, produces approximately the exact answer we get with algebra, $I = 8/3$. But we @@ -381,16 +391,11 @@ down-weight. The _pdf_ is a perfect measure of how much or little sampling is being done. So the weighting function should be proportional to $1/pdf$ . In fact it is exactly $1/pdf$ : - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - #include "common/rtweekend.h" - - #include - #include - #include - + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight inline double pdf(double x) { return 0.5*x; } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ int main() { int inside_circle = 0; @@ -398,12 +403,15 @@ int N = 1000000; double sum; for (int i = 0; i < N; i++) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight auto x = sqrt(4*random_double()); sum += x*x / pdf(x); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ } std::cout << "I =" << sum/N << "\n"; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [integ-xsq-2]: [integrate_x_sq.cc] Integrating $x^2$ with _pdf_] Since we are sampling more where the integrand is big, we might expect less noise and thus faster @@ -414,17 +422,11 @@ If we take that same code with uniform samples so the pdf = $1/2$ over the range [0,2] we can use the machinery to get `x = 2*random_double()` and the code is: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - #include "common/rtweekend.h" - #include "random.h" - - #include - #include - #include - + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight inline double pdf(double x) { return 0.5; } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ int main() { int inside_circle = 0; @@ -432,12 +434,15 @@ int N = 1000000; double sum; for (int i = 0; i < N; i++) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight auto x = 2*random_double(); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ sum += x*x / pdf(x); } std::cout << "I =" << sum/N << "\n"; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [integ-xsq-3]: [integrate_x_sq.cc] Integrating $x^2$, v3]
@@ -461,29 +466,29 @@ integrating $p$ analytically), but it’s a good exercise to make sure our code works. For just 1 sample we get: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - #include "common/rtweekend.h" - - #include - #include - #include - + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight inline double pdf(double x) { return 3*x*x/8; } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ int main() { int inside_circle = 0; int inside_circle_stratified = 0; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight int N = 1; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ double sum; for (int i = 0; i < N; i++) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight auto x = pow(8*random_double(), 1./3.); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ sum += x*x / pdf(x); } std::cout << "I =" << sum/N << "\n"; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [integ-xsq-4]: [integrate_x_sq.cc] Integrating $x^2$, final version]
Which always returns the exact answer. @@ -504,7 +509,7 @@ ==================================================================================================== In our ray tracer we pick random directions, and directions can be represented as points on the -unit-sphere. The same methodology as before applies. But now we need to have a pdf defined over 2D. +unit sphere. The same methodology as before applies, but now we need to have a pdf defined over 2D. Suppose we have this integral over all directions: $$ \int cos^2(\theta) $$ @@ -525,6 +530,7 @@ return p; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [rand-unit-sphere]: [pdf.h] Random point in unit sphere]
@@ -539,6 +545,8 @@ return unit_vector(p); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [rand-on-sphere]: [sphere_importance.cc] + Random point on the surface of the unit sphere, importance sampled]
@@ -562,6 +570,8 @@ std::cout << "I =" << sum/N << "\n"; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [main-sphereimp]: [sphere_importance.cc] + Generating importance-sampled points on the unit sphere]
The analytic answer (if you remember enough advanced calc, check me!) is $\frac{4}{3} \pi$, and the @@ -702,12 +712,13 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ void cornell_box(hittable **scene, camera **cam, double aspect) { - int i = 0; - hittable **list = new hittable*[8]; material *red = new lambertian( new constant_texture(vec3(0.65, 0.05, 0.05)) ); material *white = new lambertian( new constant_texture(vec3(0.73, 0.73, 0.73)) ); material *green = new lambertian( new constant_texture(vec3(0.12, 0.45, 0.15)) ); material *light = new diffuse_light( new constant_texture(vec3(15, 15, 15)) ); + + hittable **list = new hittable*[8]; + int i = 0; list[i++] = new flip_normals(new yz_rect(0, 555, 0, 555, 555, green)); list[i++] = new yz_rect(0, 555, 0, 555, 0, red); list[i++] = new xz_rect(213, 343, 227, 332, 554, light); @@ -719,6 +730,7 @@ list[i++] = new translate(new rotate_y( new box(vec3(0, 0, 0), vec3(165, 330, 165), white), 15), vec3(265,0,295)); *scene = new hittable_list(list,i); + vec3 lookfrom(278, 278, -800); vec3 lookat(278, 278, 0); auto dist_to_focus = 10.0; @@ -728,10 +740,11 @@ vfov, aspect, aperture, dist_to_focus, 0.0, 1.0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [cornell-box]: [main.cc] Cornell box, refactored]
-At 500x500 my code produces this image in 10min on 1 core of my Macbook: +At 500×500 my code produces this image in 10min on 1 core of my Macbook: ![Figure 6-1](../images/img-3-06-1.jpg) @@ -744,10 +757,10 @@ let’s sample like we do now: $p(direction) = \cos(\theta) / \pi$.
-We modify the base-class _material_ to enable this importance sampling: +We modify the base-class `material` to enable this importance sampling: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - class material { + class material { public: virtual bool scatter( @@ -768,6 +781,8 @@ } }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [class-material]: [material.h] + The material class, adding importance sampling]
@@ -798,6 +813,8 @@ texture *albedo; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [class-lambertian-impsample]: [material.h] + Lambertian material, modified for importance sampling]
@@ -824,6 +841,8 @@ return vec3(0,0,0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-color-impsample]: [main.cc] + The ray_color function, modified for importance sampling]
You should get exactly the same picture. @@ -845,6 +864,7 @@ return true; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scatter-mod]: [material.h] Modified scatter function]
@@ -950,6 +970,7 @@ } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [rand-unit-sphere-plot]: [sphere_plot.cc] Random points on the unit sphere]
@@ -997,6 +1018,7 @@ std::cout << "Estimate = " << sum/N << "\n"; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [cos-cubed]: [cos_cubed.cc] Integration using $cos^3(x)$]
@@ -1040,6 +1062,7 @@ std::cout << "Estimate = " << sum/N << "\n"; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [cos-density]: [cos_density.cc] Integration with cosine density function]
We can generate other densities later as we need them. In the next chapter we’ll get them aligned to @@ -1126,14 +1149,13 @@ utility functions: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - class onb - { + class onb { public: onb() {} inline vec3 operator[](int i) const { return axis[i]; } - vec3 u() const { return axis[0]; } - vec3 v() const { return axis[1]; } - vec3 w() const { return axis[2]; } + vec3 u() const { return axis[0]; } + vec3 v() const { return axis[1]; } + vec3 w() const { return axis[2]; } vec3 local(double a, double b, double c) const { return a*u() + b*v() + c*w(); } vec3 local(const vec3& a) const { return a.x()*u() + a.y()*v() + a.z()*w(); } void build_from_w(const vec3&); @@ -1152,6 +1174,7 @@ axis[0] = cross(w(), v()); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [class-onb]: [onb.h] Ortho-normal basis class]
@@ -1170,6 +1193,7 @@ return true; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scatter-onb]: [material.h] Scatter function, with ortho-normal basis]
@@ -1262,6 +1286,7 @@ return vec3(0,0,0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-color-lights]: [main.cc] Ray color with light sampling]
@@ -1287,6 +1312,7 @@ return vec3(0,0,0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [emitted-directional]: [material.h] Material emission, directional]
@@ -1343,12 +1369,13 @@ minimal interface works, and for the _pdf_ this implies: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - class pdf { + class pdf { public: virtual double value(const vec3& direction) const = 0; virtual vec3 generate() const = 0; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [class-pdf]: [pdf.h] The PDF class]
We’ll see if that works by fleshing out the subclasses. For sampling the light, we will need @@ -1370,12 +1397,13 @@ else return 0; } - virtual vec3 generate() const { + virtual vec3 generate() const { return uvw.local(random_cosine_direction()); } onb uvw; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [class-cos-pdf]: [pdf.h] The cosine_pdf class]
@@ -1409,6 +1437,7 @@ return vec3(0,0,0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-color-cos-pdf]: [main.cc] The ray_color function, using cosine pdf]
This yields an apparently matching result so all we’ve done so far is refactor where `pdf` is @@ -1436,6 +1465,7 @@ hittable *ptr; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [class-hittable-pdf]: [pdf.h] The hittable_pdf class]
@@ -1444,22 +1474,25 @@ class: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - class hittable { + class hittable { public: - virtual bool hit(const ray& r, double t_min, double t_max, - hit_record& rec) const = 0; + virtual bool hit( + const ray& r, double t_min, double t_max, hit_record& rec) const = 0; virtual bool bounding_box(double t0, double t1, aabb& box) const = 0; - virtual double pdf_value(const vec3& o, const vec3& v) const {return 0.0;} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight + virtual double pdf_value(const vec3& o, const vec3& v) const {return 0.0;} virtual vec3 random(const vec3& o) const {return vec3(1, 0, 0);} + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [hittable-plus2]: [hittable.h] The hittable class, with two new methods]
And we change `xz_rect` to implement those functions: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - class xz_rect: public hittable { + class xz_rect: public hittable { public: xz_rect() {} xz_rect( @@ -1493,6 +1526,7 @@ double x0, x1, z0, z1, k; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [xz-rect-pdf]: [aarect.h] XZ rect with pdf]
@@ -1526,6 +1560,7 @@ return vec3(0,0,0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-color-hittable-pdf]: [main.cc] ray_color function with hittable pdf]
@@ -1555,6 +1590,7 @@ pdf *p[2]; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [class-mixturepdf]: [pdf.h] The mixture_pdf class]
@@ -1590,6 +1626,7 @@ return vec3(0,0,0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-color-mixture]: [main.cc] The ray_color function, using mixture pdf]
@@ -1673,19 +1710,21 @@ We can redesign `material` and stuff all the new arguments into a `struct` like we did for `hittable`: - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - struct scatter_record - { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight + struct scatter_record { ray specular_ray; bool is_specular; vec3 attenuation; pdf *pdf_ptr; }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - class material { + class material { public: virtual bool scatter( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight const ray& r_in, const hit_record& hrec, scatter_record& srec + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ ) const { return false; } @@ -1697,12 +1736,15 @@ } virtual vec3 emitted( + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight const ray& r_in, const hit_record& rec, double u, double v, const vec3& p + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ ) const { return vec3(0,0,0); } }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [material-refactor]: [material.h] Refactoring the material class]
@@ -1725,8 +1767,8 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight - bool scatter(const ray& r_in, const hit_record& hrec, - scatter_record& srec) const { + bool scatter(const ray& r_in, const hit_record& hrec, scatter_record& srec + ) const { srec.is_specular = false; srec.attenuation = albedo->value(hrec.u, hrec.v, hrec.p); srec.pdf_ptr = new cosine_pdf(hrec.normal); @@ -1737,6 +1779,7 @@ texture *albedo; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [lambertian-scatter]: [material.h] New lambertian scatter() method]
@@ -1767,6 +1810,7 @@ return vec3(0,0,0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-color-scatter]: [main.cc] Ray color with scatter]
@@ -1793,6 +1837,7 @@ double fuzz; }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [metal-scatter]: [material.h] The metal class scatter method]
Note that if fuzziness is high, this surface isn’t ideally specular, but the implicit sampling works @@ -1833,6 +1878,8 @@ return vec3(0,0,0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-color-implicit]: [main.cc] + Ray color function with implicitly-sampled rays]
@@ -1871,6 +1918,7 @@ vfov, aspect, aperture, dist_to_focus, 0.0, 1.0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-cornell-al]: [main.cc] Cornell box scene with aluminum material]
@@ -1968,6 +2016,7 @@ return uvw.local(random_to_sphere(radius, distance_squared)); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [sphere-pdf]: [sphere.h] Sphere with pdf]
@@ -1984,6 +2033,7 @@ return vec3(x, y, z); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [rand-to-sphere]: [pdf.h] The random_to_sphere utility function]
@@ -2004,6 +2054,7 @@ col += ray_color(r, world, glass_sphere, 0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [sampling-sphere]: [main.cc] Sampling just the sphere]
@@ -2035,6 +2086,7 @@ return list[ index ]->random(o); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [density-mixture]: [hittable_list.h] Creating a mixture of densities]
@@ -2048,6 +2100,7 @@ a[1] = glass_sphere; hittable_list hlist(a,2); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scene-density-mixture]: [main.cc] Updating the scene]
@@ -2100,6 +2153,7 @@ << static_cast(255.999 * clamp(b, 0.0, 1.0)) << '\n'; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [write-color-nan]: [common/vec3.h] NaN-tolerant write_color function]
From 354ae8be6a84cedd9b9e65a881428c3c50ff1c1c Mon Sep 17 00:00:00 2001 From: Steve Hollasch Date: Sat, 26 Oct 2019 12:22:46 -0700 Subject: [PATCH 2/6] Update style CSS for listing captions --- style/book.css | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/style/book.css b/style/book.css index e5028d31..3a60951d 100644 --- a/style/book.css +++ b/style/book.css @@ -131,6 +131,14 @@ body { color: #a0a0a0; } +.md div.listingcaption { + margin-left: 3ex; +} + +.md div.listingcaption kbd { + font-style: normal; +} + /* ------------------------------------------------------------------------------------------------- ** Images & Figures ** -----------------------------------------------------------------------------------------------*/ @@ -195,4 +203,9 @@ body { .md pre.listing.tilde code { font-size: 65%; } + + .md div.listingcaption.tilde { + margin-left: 5ex; + } + } From 31d9ed471fc40948c3e0d3420cd9734ea118c2e8 Mon Sep 17 00:00:00 2001 From: Steve Hollasch Date: Sat, 26 Oct 2019 13:01:00 -0700 Subject: [PATCH 3/6] Revert "Delete bogus files from src/theRestOfYourLife" This reverts commit f09161e7742f2575664b14dbb34f6546b3e1586b. These files are referenced as standalone programs, just not by name. --- CMakeLists.txt | 2 + src/TheRestOfYourLife/bucamera.h | 49 ++++++++ src/TheRestOfYourLife/coscubed.cc | 33 +++++ src/TheRestOfYourLife/cosine_density.cc | 40 ++++++ src/TheRestOfYourLife/foomaterial.h | 161 ++++++++++++++++++++++++ src/TheRestOfYourLife/pi.cc | 40 ++++++ src/TheRestOfYourLife/sphereimp.cc | 44 +++++++ src/TheRestOfYourLife/sphereplot.cc | 29 +++++ src/TheRestOfYourLife/x2.cc | 30 +++++ src/TheRestOfYourLife/x2imp.cc | 34 +++++ 10 files changed, 462 insertions(+) create mode 100644 src/TheRestOfYourLife/bucamera.h create mode 100644 src/TheRestOfYourLife/coscubed.cc create mode 100644 src/TheRestOfYourLife/cosine_density.cc create mode 100644 src/TheRestOfYourLife/foomaterial.h create mode 100644 src/TheRestOfYourLife/pi.cc create mode 100644 src/TheRestOfYourLife/sphereimp.cc create mode 100644 src/TheRestOfYourLife/sphereplot.cc create mode 100644 src/TheRestOfYourLife/x2.cc create mode 100644 src/TheRestOfYourLife/x2imp.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 97377a8d..fcfe5cb5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,9 +58,11 @@ set ( SOURCE_REST_OF_YOUR_LIFE src/TheRestOfYourLife/aabb.h src/TheRestOfYourLife/aarect.h src/TheRestOfYourLife/box.h + src/TheRestOfYourLife/bucamera.h src/TheRestOfYourLife/bvh.h src/TheRestOfYourLife/camera.h src/TheRestOfYourLife/constant_medium.h + src/TheRestOfYourLife/foomaterial.h src/TheRestOfYourLife/hittable.h src/TheRestOfYourLife/hittable_list.h src/TheRestOfYourLife/material.h diff --git a/src/TheRestOfYourLife/bucamera.h b/src/TheRestOfYourLife/bucamera.h new file mode 100644 index 00000000..0763377c --- /dev/null +++ b/src/TheRestOfYourLife/bucamera.h @@ -0,0 +1,49 @@ +#ifndef CAMERAH +#define CAMERAH +//================================================================================================== +// Written in 2016 by Peter Shirley +// +// To the extent possible under law, the author(s) have dedicated all copyright and related and +// neighboring rights to this software to the public domain worldwide. This software is distributed +// without any warranty. +// +// You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication along +// with this software. If not, see . +//================================================================================================== + +#include "ray.h" + + +class camera { + public: + camera() { + lower_left_corner = vec3(-2.0, -1.0, -1.0); + horizontal = vec3(4.0, 0.0, 0.0); + vertical = vec3(0.0, 2.0, 0.0); + /* + lower_left_corner = vec3(-.1, -0.05, -1.0); + horizontal = vec3(0.2, 0.0, 0.0); + vertical = vec3(0.0, 0.1, 0.0); + */ + origin = vec3(0.0, 0.0, 0.0); + } + + camera(vec3 lookfrom, vec3 lookat, vec3 view_up, float aspect, float vfov, float aperture, float distance_to_focus) { + origin = lookfrom; + w = unit_vector(lookfrom - lookat; + u = unit_vector(cross(vup, w)); + v = cross(w, u); + ZZ + } + ray get_ray(float s, float t) { return ray(origin, lower_left_corner + s*horizontal + t*vertical - origin); } + + vec3 origin; + vec3 lower_left_corner; + vec3 horizontal; + vec3 vertical; + vec3 u, v, w; + float radius; +}; + +#endif + diff --git a/src/TheRestOfYourLife/coscubed.cc b/src/TheRestOfYourLife/coscubed.cc new file mode 100644 index 00000000..5706f90b --- /dev/null +++ b/src/TheRestOfYourLife/coscubed.cc @@ -0,0 +1,33 @@ +//================================================================================================== +// Written in 2016 by Peter Shirley +// +// To the extent possible under law, the author(s) have dedicated all copyright and related and +// neighboring rights to this software to the public domain worldwide. This software is distributed +// without any warranty. +// +// You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication along +// with this software. If not, see . +//================================================================================================== + +#include "common/rtweekend.h" +#include "random.h" + +#include +#include + + +int main() { + int N = 1000000; + float sum = 0.0; + for (int i = 0; i < N; i++) { + float r1 = random_double(); + float r2 = random_double(); + float x = cos(2*pi*r1)*2*sqrt(r2*(1-r2)); + float y = sin(2*pi*r1)*2*sqrt(r2*(1-r2)); + float z = 1 - r2; + sum += z*z*z / (1.0/(2.0*pi)); + } + std::cout << "PI/2 = " << pi/2 << "\n"; + std::cout << "Estimate = " << sum/N << "\n"; +} + diff --git a/src/TheRestOfYourLife/cosine_density.cc b/src/TheRestOfYourLife/cosine_density.cc new file mode 100644 index 00000000..91db417a --- /dev/null +++ b/src/TheRestOfYourLife/cosine_density.cc @@ -0,0 +1,40 @@ +//================================================================================================== +// Written in 2016 by Peter Shirley +// +// To the extent possible under law, the author(s) have dedicated all copyright and related and +// neighboring rights to this software to the public domain worldwide. This software is distributed +// without any warranty. +// +// You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication along +// with this software. If not, see . +//================================================================================================== + +#include "common/rtweekend.h" +#include "common/vec3.h" +#include "random.h" + +#include +#include + + +inline vec3 random_cosine_direction() { + float r1 = random_double(); + float r2 = random_double(); + float z = sqrt(1-r2); + float phi = 2*pi*r1; + float x = cos(phi)*sqrt(r2); + float y = sin(phi)*sqrt(r2); + return vec3(x, y, z); +} + + +int main() { + int N = 1000000; + float sum = 0.0; + for (int i = 0; i < N; i++) { + vec3 v = random_cosine_direction(); + sum += v.z()*v.z()*v.z() / (v.z()/(pi)); + } + std::cout << "PI/2 = " << pi/2 << "\n"; + std::cout << "Estimate = " << sum/N << "\n"; +} diff --git a/src/TheRestOfYourLife/foomaterial.h b/src/TheRestOfYourLife/foomaterial.h new file mode 100644 index 00000000..bd61d256 --- /dev/null +++ b/src/TheRestOfYourLife/foomaterial.h @@ -0,0 +1,161 @@ +#ifndef MATERIALH +#define MATERIALH +//================================================================================================== +// Written in 2016 by Peter Shirley +// +// To the extent possible under law, the author(s) have dedicated all copyright and related and +// neighboring rights to this software to the public domain worldwide. This software is distributed +// without any warranty. +// +// You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication along +// with this software. If not, see . +//================================================================================================== + +#include "common/rtweekend.h" +#include "hittable.h" +#include "random.h" +#include "ray.h" +#include "texture.h" + + +float schlick(float cosine, float ref_idx) { + float r0 = (1-ref_idx) / (1+ref_idx); + r0 = r0*r0; + return r0 + (1-r0)*pow((1 - cosine),5); +} + +bool refract(const vec3& v, const vec3& n, float ni_over_nt, vec3& refracted) { + vec3 uv = unit_vector(v); + float dt = dot(uv, n); + float discriminant = 1.0 - ni_over_nt*ni_over_nt*(1-dt*dt); + if (discriminant > 0) { + refracted = ni_over_nt*(uv - n*dt) - n*sqrt(discriminant); + return true; + } + else + return false; +} + + +vec3 reflect(const vec3& v, const vec3& n) { + return v - 2*dot(v,n)*n; +} + + +vec3 random_in_unit_sphere() { + vec3 p; + do { + p = 2.0*vec3(random_double(),random_double(),random_double()) - vec3(1,1,1); + } while (dot(p,p) >= 1.0); + return p; +} + + +class material { + public: + virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& albedo, ray& scattered, float& pdf) const { + return false;} + virtual float scattering_pdf(const ray& r_in, const hit_record& rec, const ray& scattered) const { + return false;} + virtual vec3 emitted(float u, float v, const vec3& p) const { return vec3(0,0,0); } +}; + +class diffuse_light : public material { + public: + diffuse_light(texture *a) : emit(a) {} + virtual vec3 emitted(float u, float v, const vec3& p) const { return emit->value(u, v, p); } + texture *emit; +}; + + +class lambertian : public material { + public: + lambertian(texture *a) : albedo(a) {} + float scattering_pdf(const ray& r_in, const hit_record& rec, const ray& scattered) const { + float cosine = dot(rec.normal, unit_vector(scattered.direction())); + if (cosine < 0) cosine = 0; + return cosine / pi; + } + bool scatter(const ray& r_in, const hit_record& rec, vec3& alb, ray& scattered, float& pdf) const { + vec3 target = rec.p + rec.normal + random_in_unit_sphere(); + scattered = ray(rec.p, unit_vector(target-rec.p), r_in.time()); + alb = albedo->value(rec.u, rec.v, rec.p); + pdf = dot(rec.normal, scattered.direction()) / pi; + return true; + } + texture *albedo; +}; + +/* +class isotropic : public material { + public: + isotropic(texture *a) : albedo(a) {} + virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& attenuation, ray& scattered) const { + scattered = ray(rec.p, random_in_unit_sphere()); + attenuation = albedo->value(rec.u, rec.v, rec.p); + return true; + } + + texture *albedo; +}; +*/ + + +/* +class metal : public material { + public: + metal(const vec3& a, float f) : albedo(a) { if (f < 1) fuzz = f; else fuzz = 1; } + virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& attenuation, ray& scattered) const { + vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal); + scattered = ray(rec.p, reflected + fuzz*random_in_unit_sphere()); + attenuation = albedo; + return (dot(scattered.direction(), rec.normal) > 0); + } + vec3 albedo; + float fuzz; +}; + +class dielectric : public material { + public: + dielectric(float ri) : ref_idx(ri) {} + virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& attenuation, ray& scattered) const { + vec3 outward_normal; + vec3 reflected = reflect(r_in.direction(), rec.normal); + float ni_over_nt; + attenuation = vec3(1.0, 1.0, 1.0); + vec3 refracted; + float reflect_prob; + float cosine; + if (dot(r_in.direction(), rec.normal) > 0) { + outward_normal = -rec.normal; + ni_over_nt = ref_idx; + cosine = ref_idx * dot(r_in.direction(), rec.normal) / r_in.direction().length(); + } + else { + outward_normal = rec.normal; + ni_over_nt = 1.0 / ref_idx; + cosine = -dot(r_in.direction(), rec.normal) / r_in.direction().length(); + } + if (refract(r_in.direction(), outward_normal, ni_over_nt, refracted)) { + reflect_prob = schlick(cosine, ref_idx); + } + else { + scattered = ray(rec.p, reflected); + reflect_prob = 1.0; + } + if (random_double() < reflect_prob) { + scattered = ray(rec.p, reflected); + } + else { + scattered = ray(rec.p, refracted); + } + return true; + } + + float ref_idx; +}; + +*/ + +#endif + diff --git a/src/TheRestOfYourLife/pi.cc b/src/TheRestOfYourLife/pi.cc new file mode 100644 index 00000000..370d6a2d --- /dev/null +++ b/src/TheRestOfYourLife/pi.cc @@ -0,0 +1,40 @@ +//================================================================================================== +// Written in 2016 by Peter Shirley +// +// To the extent possible under law, the author(s) have dedicated all copyright and related and +// neighboring rights to this software to the public domain worldwide. This software is distributed +// without any warranty. +// +// You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication along +// with this software. If not, see . +//================================================================================================== + +#include "random.h" + +#include +#include +#include + + +int main() { + int inside_circle = 0; + int inside_circle_stratified = 0; + int sqrt_N = 30000; + for (int i = 0; i < sqrt_N; i++) { + for (int j = 0; j < sqrt_N; j++) { + float x = 2*random_double() - 1; + float y = 2*random_double() - 1; + if (x*x + y*y < 1) + inside_circle++; + x = 2*((i + random_double()) / sqrt_N) - 1; + y = 2*((j + random_double()) / sqrt_N) - 1; + if (x*x + y*y < 1) + inside_circle_stratified++; + } + } + std::cout << "Regular Estimate of Pi = " << + 4*float(inside_circle) / (sqrt_N*sqrt_N) << "\n"; + std::cout << "Stratified Estimate of Pi = " << + 4*float(inside_circle_stratified) / (sqrt_N*sqrt_N) << "\n"; +} + diff --git a/src/TheRestOfYourLife/sphereimp.cc b/src/TheRestOfYourLife/sphereimp.cc new file mode 100644 index 00000000..ac4656ec --- /dev/null +++ b/src/TheRestOfYourLife/sphereimp.cc @@ -0,0 +1,44 @@ +//================================================================================================== +// Written in 2016 by Peter Shirley +// +// To the extent possible under law, the author(s) have dedicated all copyright and related and +// neighboring rights to this software to the public domain worldwide. This software is distributed +// without any warranty. +// +// You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication along +// with this software. If not, see . +//================================================================================================== + +#include "common/rtweekend.h" +#include "common/vec3.h" +#include "random.h" + +#include +#include +#include + + +vec3 random_on_unit_sphere() { + vec3 p; + do { + p = 2.0*vec3(random_double(),random_double(),random_double()) - vec3(1,1,1); + } while (dot(p,p) >= 1.0); + return unit_vector(p); +} + + + +inline float pdf(const vec3& p) { + return 1 / (4*pi); +} + +int main() { + int N = 1000000; + float sum; + for (int i = 0; i < N; i++) { + vec3 d = random_on_unit_sphere(); + float cosine_squared = d.z()*d.z(); + sum += cosine_squared / pdf(d); + } + std::cout << "I =" << sum/N << "\n"; +} diff --git a/src/TheRestOfYourLife/sphereplot.cc b/src/TheRestOfYourLife/sphereplot.cc new file mode 100644 index 00000000..fdece4b2 --- /dev/null +++ b/src/TheRestOfYourLife/sphereplot.cc @@ -0,0 +1,29 @@ +//================================================================================================== +// Written in 2016 by Peter Shirley +// +// To the extent possible under law, the author(s) have dedicated all copyright and related and +// neighboring rights to this software to the public domain worldwide. This software is distributed +// without any warranty. +// +// You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication along +// with this software. If not, see . +//================================================================================================== + +#include "common/rtweekend.h" +#include "random.h" + +#include +#include + + +int main() { + for (int i = 0; i < 2000; i++) { + float r1 = random_double(); + float r2 = random_double(); + float x = cos(2*pi*r1)*2*sqrt(r2*(1-r2)); + float y = sin(2*pi*r1)*2*sqrt(r2*(1-r2)); + float z = 1 - 2*r2; + std::cout << x << " " << y << " " << z << "\n"; + } +} + diff --git a/src/TheRestOfYourLife/x2.cc b/src/TheRestOfYourLife/x2.cc new file mode 100644 index 00000000..93a1634e --- /dev/null +++ b/src/TheRestOfYourLife/x2.cc @@ -0,0 +1,30 @@ +//================================================================================================== +// Written in 2016 by Peter Shirley +// +// To the extent possible under law, the author(s) have dedicated all copyright and related and +// neighboring rights to this software to the public domain worldwide. This software is distributed +// without any warranty. +// +// You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication along +// with this software. If not, see . +//================================================================================================== + +#include "random.h" + +#include +#include +#include + + +int main() { + int inside_circle = 0; + int inside_circle_stratified = 0; + int N = 1000000; + float sum; + for (int i = 0; i < N; i++) { + float x = 2*random_double(); + sum += x*x; + } + std::cout << "I =" << 2*sum/N << "\n"; +} + diff --git a/src/TheRestOfYourLife/x2imp.cc b/src/TheRestOfYourLife/x2imp.cc new file mode 100644 index 00000000..9b78df8c --- /dev/null +++ b/src/TheRestOfYourLife/x2imp.cc @@ -0,0 +1,34 @@ +//================================================================================================== +// Written in 2016 by Peter Shirley +// +// To the extent possible under law, the author(s) have dedicated all copyright and related and +// neighboring rights to this software to the public domain worldwide. This software is distributed +// without any warranty. +// +// You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication along +// with this software. If not, see . +//================================================================================================== + +#include "random.h" + +#include +#include +#include + + +inline float pdf(float x) { + return 3*x*x/8; +} + +int main() { + int inside_circle = 0; + int inside_circle_stratified = 0; + int N = 1; + float sum; + for (int i = 0; i < N; i++) { + float x = pow(8*random_double(), 1./3.); + sum += x*x / pdf(x); + } + std::cout << "I =" << sum/N << "\n"; +} + From d2dbd5c44e363ec2fad0d9963a59104443bffdc6 Mon Sep 17 00:00:00 2001 From: Steve Hollasch Date: Sat, 26 Oct 2019 14:33:27 -0700 Subject: [PATCH 4/6] Alt program renames, updates - Rename alternate programs for clarity - Light formatting tweaks --- .../{coscubed.cc => cos_cubed.cc} | 0 .../{cosine_density.cc => cos_density.cc} | 0 src/TheRestOfYourLife/foomaterial.h | 161 ------------------ src/TheRestOfYourLife/hittable.h | 9 +- .../{x2imp.cc => integrate_x_sq.cc} | 0 src/TheRestOfYourLife/main.cc | 6 +- .../{sphereimp.cc => sphere_importance.cc} | 0 .../{sphereplot.cc => sphere_plot.cc} | 4 +- src/TheRestOfYourLife/x2.cc | 30 ---- 9 files changed, 9 insertions(+), 201 deletions(-) rename src/TheRestOfYourLife/{coscubed.cc => cos_cubed.cc} (100%) rename src/TheRestOfYourLife/{cosine_density.cc => cos_density.cc} (100%) delete mode 100644 src/TheRestOfYourLife/foomaterial.h rename src/TheRestOfYourLife/{x2imp.cc => integrate_x_sq.cc} (100%) rename src/TheRestOfYourLife/{sphereimp.cc => sphere_importance.cc} (100%) rename src/TheRestOfYourLife/{sphereplot.cc => sphere_plot.cc} (92%) delete mode 100644 src/TheRestOfYourLife/x2.cc diff --git a/src/TheRestOfYourLife/coscubed.cc b/src/TheRestOfYourLife/cos_cubed.cc similarity index 100% rename from src/TheRestOfYourLife/coscubed.cc rename to src/TheRestOfYourLife/cos_cubed.cc diff --git a/src/TheRestOfYourLife/cosine_density.cc b/src/TheRestOfYourLife/cos_density.cc similarity index 100% rename from src/TheRestOfYourLife/cosine_density.cc rename to src/TheRestOfYourLife/cos_density.cc diff --git a/src/TheRestOfYourLife/foomaterial.h b/src/TheRestOfYourLife/foomaterial.h deleted file mode 100644 index bd61d256..00000000 --- a/src/TheRestOfYourLife/foomaterial.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef MATERIALH -#define MATERIALH -//================================================================================================== -// Written in 2016 by Peter Shirley -// -// To the extent possible under law, the author(s) have dedicated all copyright and related and -// neighboring rights to this software to the public domain worldwide. This software is distributed -// without any warranty. -// -// You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication along -// with this software. If not, see . -//================================================================================================== - -#include "common/rtweekend.h" -#include "hittable.h" -#include "random.h" -#include "ray.h" -#include "texture.h" - - -float schlick(float cosine, float ref_idx) { - float r0 = (1-ref_idx) / (1+ref_idx); - r0 = r0*r0; - return r0 + (1-r0)*pow((1 - cosine),5); -} - -bool refract(const vec3& v, const vec3& n, float ni_over_nt, vec3& refracted) { - vec3 uv = unit_vector(v); - float dt = dot(uv, n); - float discriminant = 1.0 - ni_over_nt*ni_over_nt*(1-dt*dt); - if (discriminant > 0) { - refracted = ni_over_nt*(uv - n*dt) - n*sqrt(discriminant); - return true; - } - else - return false; -} - - -vec3 reflect(const vec3& v, const vec3& n) { - return v - 2*dot(v,n)*n; -} - - -vec3 random_in_unit_sphere() { - vec3 p; - do { - p = 2.0*vec3(random_double(),random_double(),random_double()) - vec3(1,1,1); - } while (dot(p,p) >= 1.0); - return p; -} - - -class material { - public: - virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& albedo, ray& scattered, float& pdf) const { - return false;} - virtual float scattering_pdf(const ray& r_in, const hit_record& rec, const ray& scattered) const { - return false;} - virtual vec3 emitted(float u, float v, const vec3& p) const { return vec3(0,0,0); } -}; - -class diffuse_light : public material { - public: - diffuse_light(texture *a) : emit(a) {} - virtual vec3 emitted(float u, float v, const vec3& p) const { return emit->value(u, v, p); } - texture *emit; -}; - - -class lambertian : public material { - public: - lambertian(texture *a) : albedo(a) {} - float scattering_pdf(const ray& r_in, const hit_record& rec, const ray& scattered) const { - float cosine = dot(rec.normal, unit_vector(scattered.direction())); - if (cosine < 0) cosine = 0; - return cosine / pi; - } - bool scatter(const ray& r_in, const hit_record& rec, vec3& alb, ray& scattered, float& pdf) const { - vec3 target = rec.p + rec.normal + random_in_unit_sphere(); - scattered = ray(rec.p, unit_vector(target-rec.p), r_in.time()); - alb = albedo->value(rec.u, rec.v, rec.p); - pdf = dot(rec.normal, scattered.direction()) / pi; - return true; - } - texture *albedo; -}; - -/* -class isotropic : public material { - public: - isotropic(texture *a) : albedo(a) {} - virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& attenuation, ray& scattered) const { - scattered = ray(rec.p, random_in_unit_sphere()); - attenuation = albedo->value(rec.u, rec.v, rec.p); - return true; - } - - texture *albedo; -}; -*/ - - -/* -class metal : public material { - public: - metal(const vec3& a, float f) : albedo(a) { if (f < 1) fuzz = f; else fuzz = 1; } - virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& attenuation, ray& scattered) const { - vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal); - scattered = ray(rec.p, reflected + fuzz*random_in_unit_sphere()); - attenuation = albedo; - return (dot(scattered.direction(), rec.normal) > 0); - } - vec3 albedo; - float fuzz; -}; - -class dielectric : public material { - public: - dielectric(float ri) : ref_idx(ri) {} - virtual bool scatter(const ray& r_in, const hit_record& rec, vec3& attenuation, ray& scattered) const { - vec3 outward_normal; - vec3 reflected = reflect(r_in.direction(), rec.normal); - float ni_over_nt; - attenuation = vec3(1.0, 1.0, 1.0); - vec3 refracted; - float reflect_prob; - float cosine; - if (dot(r_in.direction(), rec.normal) > 0) { - outward_normal = -rec.normal; - ni_over_nt = ref_idx; - cosine = ref_idx * dot(r_in.direction(), rec.normal) / r_in.direction().length(); - } - else { - outward_normal = rec.normal; - ni_over_nt = 1.0 / ref_idx; - cosine = -dot(r_in.direction(), rec.normal) / r_in.direction().length(); - } - if (refract(r_in.direction(), outward_normal, ni_over_nt, refracted)) { - reflect_prob = schlick(cosine, ref_idx); - } - else { - scattered = ray(rec.p, reflected); - reflect_prob = 1.0; - } - if (random_double() < reflect_prob) { - scattered = ray(rec.p, reflected); - } - else { - scattered = ray(rec.p, refracted); - } - return true; - } - - float ref_idx; -}; - -*/ - -#endif - diff --git a/src/TheRestOfYourLife/hittable.h b/src/TheRestOfYourLife/hittable.h index ea8786f7..e3e2ffe1 100644 --- a/src/TheRestOfYourLife/hittable.h +++ b/src/TheRestOfYourLife/hittable.h @@ -38,12 +38,12 @@ struct hit_record material *mat_ptr; }; -class hittable { +class hittable { public: virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const = 0; virtual bool bounding_box(double t0, double t1, aabb& box) const = 0; - virtual double pdf_value(const vec3& o, const vec3& v) const {return 0.0;} - virtual vec3 random(const vec3& o) const {return vec3(1, 0, 0);} + virtual double pdf_value(const vec3& o, const vec3& v) const { return 0.0; } + virtual vec3 random(const vec3& o) const { return vec3(1,0,0); } }; class flip_normals : public hittable { @@ -120,8 +120,7 @@ rotate_y::rotate_y(hittable *p, double angle) : ptr(p) { auto newx = cos_theta*x + sin_theta*z; auto newz = -sin_theta*x + cos_theta*z; vec3 tester(newx, y, newz); - for ( int c = 0; c < 3; c++ ) - { + for ( int c = 0; c < 3; c++ ) { if ( tester[c] > max[c] ) max[c] = tester[c]; if ( tester[c] < min[c] ) diff --git a/src/TheRestOfYourLife/x2imp.cc b/src/TheRestOfYourLife/integrate_x_sq.cc similarity index 100% rename from src/TheRestOfYourLife/x2imp.cc rename to src/TheRestOfYourLife/integrate_x_sq.cc diff --git a/src/TheRestOfYourLife/main.cc b/src/TheRestOfYourLife/main.cc index 6f5e6010..9b0859b5 100644 --- a/src/TheRestOfYourLife/main.cc +++ b/src/TheRestOfYourLife/main.cc @@ -57,12 +57,13 @@ vec3 ray_color(const ray& r, hittable *world, hittable *light_shape, int depth) } void cornell_box(hittable **scene, camera **cam, double aspect) { - int i = 0; - hittable **list = new hittable*[8]; material *red = new lambertian( new constant_texture(vec3(0.65, 0.05, 0.05)) ); material *white = new lambertian( new constant_texture(vec3(0.73, 0.73, 0.73)) ); material *green = new lambertian( new constant_texture(vec3(0.12, 0.45, 0.15)) ); material *light = new diffuse_light( new constant_texture(vec3(15, 15, 15)) ); + + hittable **list = new hittable*[8]; + int i = 0; list[i++] = new flip_normals(new yz_rect(0, 555, 0, 555, 555, green)); list[i++] = new yz_rect(0, 555, 0, 555, 0, red); list[i++] = new flip_normals(new xz_rect(213, 343, 227, 332, 554, light)); @@ -74,6 +75,7 @@ void cornell_box(hittable **scene, camera **cam, double aspect) { list[i++] = new translate(new rotate_y( new box(vec3(0, 0, 0), vec3(165, 330, 165), white), 15), vec3(265,0,295)); *scene = new hittable_list(list,i); + vec3 lookfrom(278, 278, -800); vec3 lookat(278, 278, 0); auto dist_to_focus = 10.0; diff --git a/src/TheRestOfYourLife/sphereimp.cc b/src/TheRestOfYourLife/sphere_importance.cc similarity index 100% rename from src/TheRestOfYourLife/sphereimp.cc rename to src/TheRestOfYourLife/sphere_importance.cc diff --git a/src/TheRestOfYourLife/sphereplot.cc b/src/TheRestOfYourLife/sphere_plot.cc similarity index 92% rename from src/TheRestOfYourLife/sphereplot.cc rename to src/TheRestOfYourLife/sphere_plot.cc index fdece4b2..fcc7cd9e 100644 --- a/src/TheRestOfYourLife/sphereplot.cc +++ b/src/TheRestOfYourLife/sphere_plot.cc @@ -1,5 +1,5 @@ //================================================================================================== -// Written in 2016 by Peter Shirley +// Originally written in 2016 by Peter Shirley // // To the extent possible under law, the author(s) have dedicated all copyright and related and // neighboring rights to this software to the public domain worldwide. This software is distributed @@ -10,7 +10,6 @@ //================================================================================================== #include "common/rtweekend.h" -#include "random.h" #include #include @@ -26,4 +25,3 @@ int main() { std::cout << x << " " << y << " " << z << "\n"; } } - diff --git a/src/TheRestOfYourLife/x2.cc b/src/TheRestOfYourLife/x2.cc deleted file mode 100644 index 93a1634e..00000000 --- a/src/TheRestOfYourLife/x2.cc +++ /dev/null @@ -1,30 +0,0 @@ -//================================================================================================== -// Written in 2016 by Peter Shirley -// -// To the extent possible under law, the author(s) have dedicated all copyright and related and -// neighboring rights to this software to the public domain worldwide. This software is distributed -// without any warranty. -// -// You should have received a copy (see file COPYING.txt) of the CC0 Public Domain Dedication along -// with this software. If not, see . -//================================================================================================== - -#include "random.h" - -#include -#include -#include - - -int main() { - int inside_circle = 0; - int inside_circle_stratified = 0; - int N = 1000000; - float sum; - for (int i = 0; i < N; i++) { - float x = 2*random_double(); - sum += x*x; - } - std::cout << "I =" << 2*sum/N << "\n"; -} - From a23d4757c5fe900a434a26a6ae7cd3185c485e74 Mon Sep 17 00:00:00 2001 From: Steve Hollasch Date: Sat, 26 Oct 2019 15:21:12 -0700 Subject: [PATCH 5/6] Update alt programs and setup build - random.h and vec3.h are now included with rtweekend.h - switch from float to double precision - miscellaneous small updates - add all alt programs to the build --- CMakeLists.txt | 34 +++++++++++++++------- src/TheRestOfYourLife/cos_cubed.cc | 16 +++++----- src/TheRestOfYourLife/cos_density.cc | 16 +++++----- src/TheRestOfYourLife/integrate_x_sq.cc | 13 ++++----- src/TheRestOfYourLife/pi.cc | 23 ++++++++------- src/TheRestOfYourLife/sphere_importance.cc | 20 +++++-------- src/TheRestOfYourLife/sphere_plot.cc | 12 ++++---- 7 files changed, 70 insertions(+), 64 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fcfe5cb5..e4264c2c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,9 +15,13 @@ project ( RTWeekend set ( CMAKE_CXX_STANDARD 11 ) # Source -set ( SOURCE_ONE_WEEKEND +set ( COMMON_ALL src/common/rtweekend.h src/common/vec3.h +) + +set ( SOURCE_ONE_WEEKEND + ${COMMON_ALL} src/InOneWeekend/camera.h src/InOneWeekend/hittable.h src/InOneWeekend/hittable_list.h @@ -28,9 +32,8 @@ set ( SOURCE_ONE_WEEKEND ) set ( SOURCE_NEXT_WEEK - src/common/rtweekend.h + ${COMMON_ALL} src/common/rtw_stb_image.h - src/common/vec3.h src/common/external/stb_image.h src/TheNextWeek/aabb.h src/TheNextWeek/aarect.h @@ -51,9 +54,8 @@ set ( SOURCE_NEXT_WEEK ) set ( SOURCE_REST_OF_YOUR_LIFE - src/common/rtweekend.h + ${COMMON_ALL} src/common/rtw_stb_image.h - src/common/vec3.h src/common/external/stb_image.h src/TheRestOfYourLife/aabb.h src/TheRestOfYourLife/aarect.h @@ -62,7 +64,6 @@ set ( SOURCE_REST_OF_YOUR_LIFE src/TheRestOfYourLife/bvh.h src/TheRestOfYourLife/camera.h src/TheRestOfYourLife/constant_medium.h - src/TheRestOfYourLife/foomaterial.h src/TheRestOfYourLife/hittable.h src/TheRestOfYourLife/hittable_list.h src/TheRestOfYourLife/material.h @@ -77,12 +78,23 @@ set ( SOURCE_REST_OF_YOUR_LIFE src/TheRestOfYourLife/main.cc ) -set ( COMMON_DIR src ) - +# Executables add_executable(inOneWeekend ${SOURCE_ONE_WEEKEND}) add_executable(theNextWeek ${SOURCE_NEXT_WEEK}) add_executable(theRestOfYourLife ${SOURCE_REST_OF_YOUR_LIFE}) +add_executable(cos_cubed src/TheRestOfYourLife/cos_cubed.cc ${COMMON_ALL}) +add_executable(cos_density src/TheRestOfYourLife/cos_density.cc ${COMMON_ALL}) +add_executable(integrate_x_sq src/TheRestOfYourLife/integrate_x_sq.cc ${COMMON_ALL}) +add_executable(pi src/TheRestOfYourLife/pi.cc ${COMMON_ALL}) +add_executable(sphere_importance src/TheRestOfYourLife/sphere_importance.cc ${COMMON_ALL}) +add_executable(sphere_plot src/TheRestOfYourLife/sphere_plot.cc ${COMMON_ALL}) -target_include_directories(inOneWeekend PRIVATE ${COMMON_DIR}) -target_include_directories(theNextWeek PRIVATE ${COMMON_DIR}) -target_include_directories(theRestOfYourLife PRIVATE ${COMMON_DIR}) +target_include_directories(inOneWeekend PRIVATE src) +target_include_directories(theNextWeek PRIVATE src) +target_include_directories(theRestOfYourLife PRIVATE src) +target_include_directories(cos_cubed PRIVATE src) +target_include_directories(cos_density PRIVATE src) +target_include_directories(integrate_x_sq PRIVATE src) +target_include_directories(pi PRIVATE src) +target_include_directories(sphere_importance PRIVATE src) +target_include_directories(sphere_plot PRIVATE src) diff --git a/src/TheRestOfYourLife/cos_cubed.cc b/src/TheRestOfYourLife/cos_cubed.cc index 5706f90b..3618c940 100644 --- a/src/TheRestOfYourLife/cos_cubed.cc +++ b/src/TheRestOfYourLife/cos_cubed.cc @@ -1,5 +1,5 @@ //================================================================================================== -// Written in 2016 by Peter Shirley +// Originally written in 2016 by Peter Shirley // // To the extent possible under law, the author(s) have dedicated all copyright and related and // neighboring rights to this software to the public domain worldwide. This software is distributed @@ -10,7 +10,6 @@ //================================================================================================== #include "common/rtweekend.h" -#include "random.h" #include #include @@ -18,16 +17,15 @@ int main() { int N = 1000000; - float sum = 0.0; + auto sum = 0.0; for (int i = 0; i < N; i++) { - float r1 = random_double(); - float r2 = random_double(); - float x = cos(2*pi*r1)*2*sqrt(r2*(1-r2)); - float y = sin(2*pi*r1)*2*sqrt(r2*(1-r2)); - float z = 1 - r2; + auto r1 = random_double(); + auto r2 = random_double(); + auto x = cos(2*pi*r1)*2*sqrt(r2*(1-r2)); + auto y = sin(2*pi*r1)*2*sqrt(r2*(1-r2)); + auto z = 1 - r2; sum += z*z*z / (1.0/(2.0*pi)); } std::cout << "PI/2 = " << pi/2 << "\n"; std::cout << "Estimate = " << sum/N << "\n"; } - diff --git a/src/TheRestOfYourLife/cos_density.cc b/src/TheRestOfYourLife/cos_density.cc index 91db417a..d3972ffb 100644 --- a/src/TheRestOfYourLife/cos_density.cc +++ b/src/TheRestOfYourLife/cos_density.cc @@ -10,27 +10,25 @@ //================================================================================================== #include "common/rtweekend.h" -#include "common/vec3.h" -#include "random.h" #include #include inline vec3 random_cosine_direction() { - float r1 = random_double(); - float r2 = random_double(); - float z = sqrt(1-r2); - float phi = 2*pi*r1; - float x = cos(phi)*sqrt(r2); - float y = sin(phi)*sqrt(r2); + auto r1 = random_double(); + auto r2 = random_double(); + auto z = sqrt(1-r2); + auto phi = 2*pi*r1; + auto x = cos(phi)*sqrt(r2); + auto y = sin(phi)*sqrt(r2); return vec3(x, y, z); } int main() { int N = 1000000; - float sum = 0.0; + auto sum = 0.0; for (int i = 0; i < N; i++) { vec3 v = random_cosine_direction(); sum += v.z()*v.z()*v.z() / (v.z()/(pi)); diff --git a/src/TheRestOfYourLife/integrate_x_sq.cc b/src/TheRestOfYourLife/integrate_x_sq.cc index 9b78df8c..ab08b48c 100644 --- a/src/TheRestOfYourLife/integrate_x_sq.cc +++ b/src/TheRestOfYourLife/integrate_x_sq.cc @@ -1,5 +1,5 @@ //================================================================================================== -// Written in 2016 by Peter Shirley +// Originally written in 2016 by Peter Shirley // // To the extent possible under law, the author(s) have dedicated all copyright and related and // neighboring rights to this software to the public domain worldwide. This software is distributed @@ -9,14 +9,14 @@ // with this software. If not, see . //================================================================================================== -#include "random.h" +#include "common/rtweekend.h" #include #include #include -inline float pdf(float x) { +inline double pdf(double x) { return 3*x*x/8; } @@ -24,11 +24,10 @@ int main() { int inside_circle = 0; int inside_circle_stratified = 0; int N = 1; - float sum; + auto sum = 0.0; for (int i = 0; i < N; i++) { - float x = pow(8*random_double(), 1./3.); + auto x = pow(8*random_double(), 1./3.); sum += x*x / pdf(x); } - std::cout << "I =" << sum/N << "\n"; + std::cout << "I = " << sum/N << "\n"; } - diff --git a/src/TheRestOfYourLife/pi.cc b/src/TheRestOfYourLife/pi.cc index 370d6a2d..afba16c9 100644 --- a/src/TheRestOfYourLife/pi.cc +++ b/src/TheRestOfYourLife/pi.cc @@ -1,5 +1,5 @@ //================================================================================================== -// Written in 2016 by Peter Shirley +// Originally written in 2016 by Peter Shirley // // To the extent possible under law, the author(s) have dedicated all copyright and related and // neighboring rights to this software to the public domain worldwide. This software is distributed @@ -9,7 +9,7 @@ // with this software. If not, see . //================================================================================================== -#include "random.h" +#include "common/rtweekend.h" #include #include @@ -19,11 +19,11 @@ int main() { int inside_circle = 0; int inside_circle_stratified = 0; - int sqrt_N = 30000; + int sqrt_N = 10000; for (int i = 0; i < sqrt_N; i++) { for (int j = 0; j < sqrt_N; j++) { - float x = 2*random_double() - 1; - float y = 2*random_double() - 1; + auto x = 2*random_double() - 1; + auto y = 2*random_double() - 1; if (x*x + y*y < 1) inside_circle++; x = 2*((i + random_double()) / sqrt_N) - 1; @@ -32,9 +32,12 @@ int main() { inside_circle_stratified++; } } - std::cout << "Regular Estimate of Pi = " << - 4*float(inside_circle) / (sqrt_N*sqrt_N) << "\n"; - std::cout << "Stratified Estimate of Pi = " << - 4*float(inside_circle_stratified) / (sqrt_N*sqrt_N) << "\n"; -} + auto N = static_cast(sqrt_N) * sqrt_N; + + std::cout + << "Regular Estimate of Pi = " + << 4*double(inside_circle) / N << '\n' + << "Stratified Estimate of Pi = " + << 4*double(inside_circle_stratified) / N << '\n'; +} diff --git a/src/TheRestOfYourLife/sphere_importance.cc b/src/TheRestOfYourLife/sphere_importance.cc index ac4656ec..6f878366 100644 --- a/src/TheRestOfYourLife/sphere_importance.cc +++ b/src/TheRestOfYourLife/sphere_importance.cc @@ -1,5 +1,5 @@ //================================================================================================== -// Written in 2016 by Peter Shirley +// Originally written in 2016 by Peter Shirley // // To the extent possible under law, the author(s) have dedicated all copyright and related and // neighboring rights to this software to the public domain worldwide. This software is distributed @@ -10,8 +10,6 @@ //================================================================================================== #include "common/rtweekend.h" -#include "common/vec3.h" -#include "random.h" #include #include @@ -26,19 +24,17 @@ vec3 random_on_unit_sphere() { return unit_vector(p); } - - -inline float pdf(const vec3& p) { - return 1 / (4*pi); +inline double pdf(const vec3& p) { + return 1.0 / (4.0*pi); } int main() { int N = 1000000; - float sum; + auto sum = 0.0; for (int i = 0; i < N; i++) { - vec3 d = random_on_unit_sphere(); - float cosine_squared = d.z()*d.z(); - sum += cosine_squared / pdf(d); + vec3 d = random_on_unit_sphere(); + auto cosine_squared = d.z()*d.z(); + sum += cosine_squared / pdf(d); } - std::cout << "I =" << sum/N << "\n"; + std::cout << "I = " << sum/N << '\n'; } diff --git a/src/TheRestOfYourLife/sphere_plot.cc b/src/TheRestOfYourLife/sphere_plot.cc index fcc7cd9e..d01f47f7 100644 --- a/src/TheRestOfYourLife/sphere_plot.cc +++ b/src/TheRestOfYourLife/sphere_plot.cc @@ -17,11 +17,11 @@ int main() { for (int i = 0; i < 2000; i++) { - float r1 = random_double(); - float r2 = random_double(); - float x = cos(2*pi*r1)*2*sqrt(r2*(1-r2)); - float y = sin(2*pi*r1)*2*sqrt(r2*(1-r2)); - float z = 1 - 2*r2; - std::cout << x << " " << y << " " << z << "\n"; + auto r1 = random_double(); + auto r2 = random_double(); + auto x = cos(2*pi*r1)*2*sqrt(r2*(1-r2)); + auto y = sin(2*pi*r1)*2*sqrt(r2*(1-r2)); + auto z = 1 - 2*r2; + std::cout << x << " " << y << " " << z << '\n'; } } From 03f038443f75cceef9e3bf2594bd77762dc4f982 Mon Sep 17 00:00:00 2001 From: Steve Hollasch Date: Sat, 26 Oct 2019 15:39:07 -0700 Subject: [PATCH 6/6] Update alt programs + book to match Resolves #237 --- books/RayTracingTheRestOfYourLife.html | 63 ++++++++++++---------- src/TheRestOfYourLife/cos_cubed.cc | 4 +- src/TheRestOfYourLife/cos_density.cc | 4 +- src/TheRestOfYourLife/pdf.h | 8 +-- src/TheRestOfYourLife/pi.cc | 1 - src/TheRestOfYourLife/sphere_importance.cc | 8 +-- 6 files changed, 47 insertions(+), 41 deletions(-) diff --git a/books/RayTracingTheRestOfYourLife.html b/books/RayTracingTheRestOfYourLife.html index fe56dd74..fd9c65fe 100644 --- a/books/RayTracingTheRestOfYourLife.html +++ b/books/RayTracingTheRestOfYourLife.html @@ -87,7 +87,7 @@ if(x*x + y*y < 1) inside_circle++; } - std::cout << "Estimate of Pi = " << 4*double(inside_circle) / N << "\n"; + std::cout << "Estimate of Pi = " << 4*double(inside_circle) / N << '\n'; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Listing [estpi-1]: [pi.cc] Estimating π] @@ -161,10 +161,13 @@ inside_circle_stratified++; } } - std::cout << "Regular Estimate of Pi = " << - 4*double(inside_circle) / (sqrt_N*sqrt_N) << "\n"; - std::cout << "Stratified Estimate of Pi = " << - 4*double(inside_circle_stratified) / (sqrt_N*sqrt_N) << "\n"; + + auto N = static_cast(sqrt_N) * sqrt_N; + std::cout + << "Regular Estimate of Pi = " + << 4*double(inside_circle) / (sqrt_N*sqrt_N) << '\n' + << "Stratified Estimate of Pi = " + << 4*double(inside_circle_stratified) / (sqrt_N*sqrt_N) << '\n'; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Listing [estpi-3]: [pi.cc] Estimating π, v3] @@ -401,14 +404,14 @@ int inside_circle = 0; int inside_circle_stratified = 0; int N = 1000000; - double sum; + auto sum = 0.0; for (int i = 0; i < N; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight auto x = sqrt(4*random_double()); sum += x*x / pdf(x); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ } - std::cout << "I =" << sum/N << "\n"; + std::cout << "I = " << sum/N << '\n'; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Listing [integ-xsq-2]: [integrate_x_sq.cc] Integrating $x^2$ with _pdf_] @@ -432,14 +435,14 @@ int inside_circle = 0; int inside_circle_stratified = 0; int N = 1000000; - double sum; + auto sum = 0.0; for (int i = 0; i < N; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight auto x = 2*random_double(); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ sum += x*x / pdf(x); } - std::cout << "I =" << sum/N << "\n"; + std::cout << "I = " << sum/N << '\n'; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Listing [integ-xsq-3]: [integrate_x_sq.cc] Integrating $x^2$, v3] @@ -478,14 +481,14 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight int N = 1; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - double sum; + auto sum = 0.0; for (int i = 0; i < N; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight auto x = pow(8*random_double(), 1./3.); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ sum += x*x / pdf(x); } - std::cout << "I =" << sum/N << "\n"; + std::cout << "I = " << sum/N << '\n'; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Listing [integ-xsq-4]: [integrate_x_sq.cc] Integrating $x^2$, final version] @@ -525,8 +528,8 @@ vec3 random_in_unit_sphere() { vec3 p; do { - p = 2.0*vec3(random_double(),random_double(),random_double()) - vec3(1,1,1); - } while (dot(p,p) >= 1.0); + p = 2*vec3(random_double(),random_double(),random_double()) - vec3(1,1,1); + } while (p.squared_length() >= 1); return p; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -539,10 +542,12 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ vec3 random_on_unit_sphere() { vec3 p; + double len_squared; do { - p = 2.0*vec3(random_double(),random_double(),random_double()) - vec3(1,1,1); - } while (dot(p,p) >= 1.0); - return unit_vector(p); + p = 2*vec3(random_double(),random_double(),random_double()) - vec3(1,1,1); + len_squared = p.squared_length(); + } while (len_squared >= 1); + return p / sqrt(len_squared); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Listing [rand-on-sphere]: [sphere_importance.cc] @@ -561,13 +566,13 @@ int main() { int N = 1000000; - double sum; + auto sum = 0.0; for (int i = 0; i < N; i++) { - vec3 d = random_on_unit_sphere(); - auto cosine_squared = d.z()*d.z(); - sum += cosine_squared / pdf(d); + vec3 d = random_on_unit_sphere(); + auto cosine_squared = d.z()*d.z(); + sum += cosine_squared / pdf(d); } - std::cout << "I =" << sum/N << "\n"; + std::cout << "I = " << sum/N << '\n'; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Listing [main-sphereimp]: [sphere_importance.cc] @@ -965,8 +970,7 @@ auto x = cos(2*pi*r1)*2*sqrt(r2*(1-r2)); auto y = sin(2*pi*r1)*2*sqrt(r2*(1-r2)); auto z = 1 - 2*r2; - - std::cout << x << " " << y << " " << z << "\n"; + std::cout << x << " " << y << " " << z << '\n'; } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1014,8 +1018,8 @@ auto z = 1 - r2; sum += z*z*z / (1.0/(2.0*pi)); } - std::cout << "PI/2 = " << pi/2 << "\n"; - std::cout << "Estimate = " << sum/N << "\n"; + std::cout << "PI/2 = " << pi/2 << '\n'; + std::cout << "Estimate = " << sum/N << '\n'; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Listing [cos-cubed]: [cos_cubed.cc] Integration using $cos^3(x)$] @@ -1041,6 +1045,11 @@ Let’s also start generating them as random vectors: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + #include "common/rtweekend.h" + + #include + #include + inline vec3 random_cosine_direction() { auto r1 = random_double(); auto r2 = random_double(); @@ -1058,8 +1067,8 @@ vec3 v = random_cosine_direction(); sum += v.z()*v.z()*v.z() / (v.z()/(pi)); } - std::cout << "PI/2 = " << pi/2 << "\n"; - std::cout << "Estimate = " << sum/N << "\n"; + std::cout << "PI/2 = " << pi/2 << '\n'; + std::cout << "Estimate = " << sum/N << '\n'; } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Listing [cos-density]: [cos_density.cc] Integration with cosine density function] diff --git a/src/TheRestOfYourLife/cos_cubed.cc b/src/TheRestOfYourLife/cos_cubed.cc index 3618c940..fb34605d 100644 --- a/src/TheRestOfYourLife/cos_cubed.cc +++ b/src/TheRestOfYourLife/cos_cubed.cc @@ -26,6 +26,6 @@ int main() { auto z = 1 - r2; sum += z*z*z / (1.0/(2.0*pi)); } - std::cout << "PI/2 = " << pi/2 << "\n"; - std::cout << "Estimate = " << sum/N << "\n"; + std::cout << "PI/2 = " << pi/2 << '\n'; + std::cout << "Estimate = " << sum/N << '\n'; } diff --git a/src/TheRestOfYourLife/cos_density.cc b/src/TheRestOfYourLife/cos_density.cc index d3972ffb..eb8f92d7 100644 --- a/src/TheRestOfYourLife/cos_density.cc +++ b/src/TheRestOfYourLife/cos_density.cc @@ -33,6 +33,6 @@ int main() { vec3 v = random_cosine_direction(); sum += v.z()*v.z()*v.z() / (v.z()/(pi)); } - std::cout << "PI/2 = " << pi/2 << "\n"; - std::cout << "Estimate = " << sum/N << "\n"; + std::cout << "PI/2 = " << pi/2 << '\n'; + std::cout << "Estimate = " << sum/N << '\n'; } diff --git a/src/TheRestOfYourLife/pdf.h b/src/TheRestOfYourLife/pdf.h index ad442933..5a2d7527 100644 --- a/src/TheRestOfYourLife/pdf.h +++ b/src/TheRestOfYourLife/pdf.h @@ -35,17 +35,14 @@ inline vec3 random_to_sphere(double radius, double distance_squared) { return vec3(x, y, z); } - vec3 random_in_unit_sphere() { vec3 p; do { - p = 2.0*vec3(random_double(),random_double(),random_double()) - vec3(1,1,1); - } while (dot(p,p) >= 1.0); + p = 2*vec3(random_double(),random_double(),random_double()) - vec3(1,1,1); + } while (p.squared_length() >= 1); return p; } - - class pdf { public: virtual double value(const vec3& direction) const = 0; @@ -53,7 +50,6 @@ class pdf { virtual ~pdf() {} }; - class cosine_pdf : public pdf { public: cosine_pdf(const vec3& w) { uvw.build_from_w(w); } diff --git a/src/TheRestOfYourLife/pi.cc b/src/TheRestOfYourLife/pi.cc index afba16c9..3c368d08 100644 --- a/src/TheRestOfYourLife/pi.cc +++ b/src/TheRestOfYourLife/pi.cc @@ -34,7 +34,6 @@ int main() { } auto N = static_cast(sqrt_N) * sqrt_N; - std::cout << "Regular Estimate of Pi = " << 4*double(inside_circle) / N << '\n' diff --git a/src/TheRestOfYourLife/sphere_importance.cc b/src/TheRestOfYourLife/sphere_importance.cc index 6f878366..f6d552f8 100644 --- a/src/TheRestOfYourLife/sphere_importance.cc +++ b/src/TheRestOfYourLife/sphere_importance.cc @@ -18,10 +18,12 @@ vec3 random_on_unit_sphere() { vec3 p; + double len_squared; do { - p = 2.0*vec3(random_double(),random_double(),random_double()) - vec3(1,1,1); - } while (dot(p,p) >= 1.0); - return unit_vector(p); + p = 2*vec3(random_double(), random_double(), random_double()) - vec3(1,1,1); + len_squared = p.squared_length(); + } while (len_squared >= 1); + return p / sqrt(len_squared); } inline double pdf(const vec3& p) {