diff --git a/books/RayTracingTheRestOfYourLife.html b/books/RayTracingTheRestOfYourLife.html index 44a6ce77..ac7d8768 100644 --- a/books/RayTracingTheRestOfYourLife.html +++ b/books/RayTracingTheRestOfYourLife.html @@ -317,10 +317,12 @@ cam.render(world); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - [Listing [estpi-3]: [main.cc] Stratifying the samples inside pixels] + [Listing [estpi-3]: [main.cc] Cornell box, revisited] Run this program to generate an un-stratified render and save for comparison. +Now make the following changes to implement a stratified sampling procedure: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ class camera { public: @@ -476,20 +478,13 @@
Our work above is equally valid as a means to solve for $\pi$ as it is a means to solve for the area -of a circle. So we could make the following substitution in the first version of our program: - - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - ... - int main() { - ... - +of a circle. So we could make the following substitution in one of the first versions of our pi +program: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ delete std::cout << "Estimate of Pi = " << (4.0 * inside_circle) / N << '\n'; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight std::cout << "Estimated area of unit circle = " << (4.0 * inside_circle) / N << '\n'; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Listing [estunitcircle]: [pi.cc] Estimating area of unit circle] @@ -1186,6 +1181,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ int N = 1000000; auto sum = 0.0; + for (int i = 0; i < N; i++) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight auto x = f(random_double()); @@ -1748,10 +1744,10 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight double scattering_pdf = rec.mat->scattering_pdf(r, rec, scattered); - double pdf = scattering_pdf; + double pdf_value = scattering_pdf; color color_from_scatter = - (attenuation * scattering_pdf * ray_color(scattered, depth-1, world)) / pdf; + (attenuation * scattering_pdf * ray_color(scattered, depth-1, world)) / pdf_value; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ return color_from_emission + color_from_scatter; @@ -1765,7 +1761,7 @@
You should get exactly the same picture. Which _should make sense_, as the scattered part of -`ray_color` is getting multiplied by `scattering_pdf / pdf`, and as `pdf` is equal to +`ray_color` is getting multiplied by `scattering_pdf / pdf_value`, and as `pdf_value` is equal to `scattering_pdf` is just the same as multiplying by one. @@ -1804,11 +1800,11 @@ double scattering_pdf = rec.mat->scattering_pdf(r, rec, scattered); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight - double pdf = 1 / (2*pi); + double pdf_value = 1 / (2*pi); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ color color_from_scatter = - (attenuation * scattering_pdf * ray_color(scattered, depth-1, world)) / pdf; + (attenuation * scattering_pdf * ray_color(scattered, depth-1, world)) / pdf_value; return color_from_emission + color_from_scatter; } @@ -1830,7 +1826,7 @@ double scattering_pdf = rec.mat->scattering_pdf(r, rec, scattered); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight - double pdf = scattering_pdf; + double pdf_value = scattering_pdf; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ ... @@ -2312,8 +2308,10 @@ class hit_record; class material { + public: ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight virtual bool scatter( const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered, double& pdf @@ -2351,59 +2349,88 @@ }; class metal : public material { - public: - ... + public: + ... + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight bool scatter( const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered, double& pdf ) const override { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - ... + ... } - }; + }; class dielectric : public material { - public: - ... + public: + ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight bool scatter( const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered, double& pdf ) const override { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - ... + ... } - }; + }; class diffuse_light : public material { - public: - ... + ... + }; + + class isotropic : public material { + public: + ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight bool scatter( const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered, double& pdf ) const override { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - ... + ... } - }; + }; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [scatter-onb]: [material.h] Scatter function, with orthonormal basis] - class isotropic : public material { - public: + + +And here we add the accompanying changes to the camera class: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + class camera { + ... + private: + ... + + color ray_color(const ray& r, int depth, const hittable& world) const { ... - + + ray scattered; + color attenuation; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight - bool scatter( - const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered, double& pdf - ) const override { + double pdf_value; // TODO: What are we supposed to do with the returned PDF? + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + color color_from_emission = rec.mat->emitted(rec.u, rec.v, rec.p); + + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight + if (!rec.mat->scatter(r, rec, attenuation, scattered, pdf_value)) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - ... + return color_from_emission; + + ... } + + ... }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - [Listing [scatter-onb]: [material.h] Scatter function, with orthonormal basis] - - + [Listing [scatter-onb-ray-color]: [camera.h] + Updated ray_color function with returned PDF value + ]
Which produces: @@ -2427,8 +2454,8 @@ bool scatter( const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered, double& pdf ) const override { - attenuation = tex->value(rec.u, rec.v, rec.p); scattered = ray(rec.p, random_unit_vector(), r_in.time()); + attenuation = tex->value(rec.u, rec.v, rec.p); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight pdf = 1 / (4 * pi); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ @@ -2511,6 +2538,8 @@ class camera { ... private: + ... + color ray_color(const ray& r, int depth, const hittable& world) const { // If we've exceeded the ray bounce limit, no more light is gathered. if (depth <= 0) @@ -2524,15 +2553,10 @@ ray scattered; color attenuation; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight - double pdf; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + double pdf_value; // TODO: What are we supposed to do with the returned PDF? color color_from_emission = rec.mat->emitted(rec.u, rec.v, rec.p); - - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight - if (!rec.mat->scatter(r, rec, attenuation, scattered, pdf)) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + if (!rec.mat->scatter(r, rec, attenuation, scattered, pdf_value)) return color_from_emission; @@ -2550,14 +2574,14 @@ if (light_cosine < 0.000001) return color_from_emission; - pdf = distance_squared / (light_cosine * light_area); + pdf_value = distance_squared / (light_cosine * light_area); scattered = ray(rec.p, to_light, r.time()); double scattering_pdf = rec.mat->scattering_pdf(r, rec, scattered); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ color color_from_scatter = - (attenuation * scattering_pdf * ray_color(scattered, depth-1, world)) / pdf; + (attenuation * scattering_pdf * ray_color(scattered, depth-1, world)) / pdf_value; return color_from_emission + color_from_scatter; } @@ -2565,7 +2589,23 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [Listing [ray-color-lights]: [camera.h] Ray color with light sampling] -
+We'll test this scene with just ten samples per pixel: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + int main() { + ... + cam.aspect_ratio = 1.0; + cam.image_width = 600; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight + cam.samples_per_pixel = 10; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + cam.max_depth = 50; + cam.background = color(0,0,0); + ... + } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [ray-color-lights-10spp]: [main.cc] Ray color with light sampling at 10spp] + With 10 samples per pixel this yields: ![Image 7: Cornell box, sampling only the light, 10 samples per pixel @@ -2574,8 +2614,6 @@ This is about what we would expect from something that samples only the light sources, so this appears to work. -
- Switching to Unidirectional Light ---------------------------------- @@ -2609,7 +2647,7 @@ const override { if (!rec.front_face) return color(0,0,0); - return emit->value(u, v, p); + return tex->value(u, v, p); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ @@ -2699,7 +2737,7 @@ #endif ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - [Listing [class-pdf]: [pdf.h] The abstract pdf class] + [Listing [class-pdf]: [pdf.h] The abstract PDF class]
@@ -2721,7 +2759,7 @@ } }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - [Listing [class-uni-pdf]: [pdf.h] The uniform_pdf class] + [Listing [class-uni-pdf]: [pdf.h] The sphere_pdf class] @@ -2754,10 +2792,13 @@ We can try this cosine PDF in the `ray_color()` function: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + #include "rtweekend.h" + #include "hittable.h" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight #include "pdf.h" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + #include "material.h" class camera { ... @@ -2776,36 +2817,49 @@ ray scattered; color attenuation; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight - double pdf_val; + double pdf_value; // TODO: What are we supposed to do with the returned PDF? color color_from_emission = rec.mat->emitted(r, rec, rec.u, rec.v, rec.p); - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight - if (!rec.mat->scatter(r, rec, attenuation, scattered, pdf_val)) - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + if (!rec.mat->scatter(r, rec, attenuation, scattered, pdf_value)) return color_from_emission; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight cosine_pdf surface_pdf(rec.normal); scattered = ray(rec.p, surface_pdf.generate(), r.time()); - pdf_val = surface_pdf.value(scattered.direction()); + pdf_value = surface_pdf.value(scattered.direction()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ double scattering_pdf = rec.mat->scattering_pdf(r, rec, scattered); color color_from_scatter = - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight - (attenuation * scattering_pdf * ray_color(scattered, depth-1, world)) / pdf_val; - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + (attenuation * scattering_pdf * ray_color(scattered, depth-1, world)) / pdf_value; return color_from_emission + color_from_scatter; } }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - [Listing [ray-color-cos-pdf]: [camera.h] The ray_color function, using cosine pdf] + [Listing [ray-color-cos-pdf]: [camera.h] The ray_color function, using cosine PDF] + + + +
+And set the render back to 1000 samples per pixel: + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + int main() { + ... + cam.aspect_ratio = 1.0; + cam.image_width = 600; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight + cam.samples_per_pixel = 1000; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + cam.max_depth = 50; + cam.background = color(0,0,0); + ... + } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + [Listing [cosine-density-1000spp]: [main.cc] Reset sampling back to 1000spp]
@@ -2824,9 +2878,16 @@ Now we can try sampling directions toward a `hittable`, like the light. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - ... + #include "rtweekend.h" + + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight #include "hittable_list.h" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + #include "onb.h" + ... + class hittable_pdf : public pdf { public: hittable_pdf(const hittable& objects, const point3& origin) @@ -2859,7 +2920,11 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ class hittable { public: - ... + virtual ~hittable() = default; + + virtual bool hit(const ray& r, interval ray_t, hit_record& rec) const = 0; + + virtual aabb bounding_box() const = 0; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight @@ -2868,7 +2933,7 @@ } virtual vec3 random(const point3& origin) const { - return vec3(1, 0, 0); + return vec3(1,0,0); } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ }; @@ -2896,6 +2961,7 @@ set_bounding_box(); } + ... @@ -2930,7 +2996,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ }; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - [Listing [quad-pdf]: [quad.h] quad with pdf] + [Listing [quad-pdf]: [quad.h] quad with PDF] @@ -2946,6 +3012,8 @@ class camera { public: ... + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight void render(const hittable& world, const hittable& lights) { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ @@ -2975,23 +3043,27 @@ ... private: ... + + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight color ray_color(const ray& r, int depth, const hittable& world, const hittable& lights) const { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ ... ray scattered; color attenuation; - double pdf_val; + double pdf_value; // TODO: What are we supposed to do with the returned PDF? color color_from_emission = rec.mat->emitted(r, rec, rec.u, rec.v, rec.p); - if (!rec.mat->scatter(r, rec, attenuation, scattered, pdf_val)) + if (!rec.mat->scatter(r, rec, attenuation, scattered, pdf_value)) return color_from_emission; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight hittable_pdf light_pdf(light_ptr, rec.p); scattered = ray(rec.p, light_pdf.generate(), r.time()); - pdf_val = light_pdf.value(scattered.direction()); + pdf_value = light_pdf.value(scattered.direction()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ double scattering_pdf = rec.mat->scattering_pdf(r, rec, scattered); @@ -2999,7 +3071,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight color sample_color = ray_color(scattered, depth-1, world, lights); - color color_from_scatter = (attenuation * scattering_pdf * sample_color) / pdf_val; + color color_from_scatter = (attenuation * scattering_pdf * sample_color) / pdf_value; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ return color_from_emission + color_from_scatter; @@ -3101,7 +3173,7 @@ honestly sounds like a nightmare, but fortunately we don't need to do that. There are some directions that both PDFs could have generated. For example, a direction toward the light could have been generated by either $\operatorname{pLight}$ _or_ $\operatorname{pSurface}$. It is sufficient -for us to solve for the pdf value of $\operatorname{pSurface}$ and of $\operatorname{pLight}$ for a +for us to solve for the PDF value of $\operatorname{pSurface}$ and of $\operatorname{pLight}$ for a random direction and then take the PDF mixture weights to solve for the total PDF value for that direction. The mixture density class is actually pretty straightforward: @@ -3141,11 +3213,12 @@ ... private: ... + color ray_color(const ray& r, int depth, const hittable& world, const hittable& lights) const { ... - if (!rec.mat->scatter(r, rec, attenuation, scattered, pdf_val)) + if (!rec.mat->scatter(r, rec, attenuation, scattered, pdf_value)) return color_from_emission; @@ -3155,13 +3228,13 @@ mixture_pdf mixed_pdf(p0, p1); scattered = ray(rec.p, mixed_pdf.generate(), r.time()); - pdf_val = mixed_pdf.value(scattered.direction()); + pdf_value = mixed_pdf.value(scattered.direction()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ double scattering_pdf = rec.mat->scattering_pdf(r, rec, scattered); color sample_color = ray_color(scattered, depth-1, world, lights); - color color_from_scatter = (attenuation * scattering_pdf * sample_color) / pdf_val; + color color_from_scatter = (attenuation * scattering_pdf * sample_color) / pdf_value; return color_from_emission + color_from_scatter; } @@ -3272,6 +3345,7 @@ public: ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight virtual bool scatter(const ray& r_in, const hit_record& rec, scatter_record& srec) const { return false; @@ -3289,6 +3363,20 @@ The `lambertian` material becomes simpler: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + #include "rtweekend.h" + + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ delete + #include "onb.h" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight + #include "pdf.h" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + #include "texture.h" + + class hit_record; + + ... + class lambertian : public material { public: lambertian(const color& albedo) : tex(make_shared(albedo)) {} @@ -3304,9 +3392,12 @@ } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ - double scattering_pdf(const ray& r_in, const hit_record& rec, const ray& scattered) const { - auto cosine = dot(rec.normal, unit_vector(scattered.direction())); - return cosine < 0 ? 0 : cosine/pi; + double scattering_pdf(const ray& r_in, const hit_record& rec, const ray& scattered) + const override { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight + auto cos_theta = dot(rec.normal, unit_vector(scattered.direction())); + return cos_theta < 0 ? 0 : cos_theta/pi; + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ } private: @@ -3357,6 +3448,7 @@ ... private: ... + color ray_color(const ray& r, int depth, const hittable& world, const hittable& lights) const { // If we've exceeded the ray bounce limit, no more light is gathered. @@ -3387,14 +3479,15 @@ mixture_pdf p(light_ptr, srec.pdf_ptr); ray scattered = ray(rec.p, p.generate(), r.time()); - auto pdf_val = p.value(scattered.direction()); + auto pdf_value = p.value(scattered.direction()); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ double scattering_pdf = rec.mat->scattering_pdf(r, rec, scattered); color sample_color = ray_color(scattered, depth-1, world, lights); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight - color color_from_scatter = (srec.attenuation * scattering_pdf * sample_color) / pdf_val; + color color_from_scatter = + (srec.attenuation * scattering_pdf * sample_color) / pdf_value; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ return color_from_emission + color_from_scatter; @@ -3638,6 +3731,11 @@ The sphere class needs the two PDF-related functions: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + #include "hittable.h" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight + #include "onb.h" + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + class sphere : public hittable { public: ... @@ -3669,6 +3767,7 @@ private: ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight static vec3 random_to_sphere(double radius, double distance_squared) { auto r1 = random_double(); diff --git a/images/img-3.06-cornell-ortho.jpg b/images/img-3.06-cornell-ortho.jpg index 133306d0..9edd823a 100644 Binary files a/images/img-3.06-cornell-ortho.jpg and b/images/img-3.06-cornell-ortho.jpg differ diff --git a/images/img-3.07-cornell-sample-light.jpg b/images/img-3.07-cornell-sample-light.jpg index 21df642b..599d3599 100644 Binary files a/images/img-3.07-cornell-sample-light.jpg and b/images/img-3.07-cornell-sample-light.jpg differ diff --git a/images/img-3.08-cornell-lightdown.jpg b/images/img-3.08-cornell-lightdown.jpg index 02a913b3..7500b679 100644 Binary files a/images/img-3.08-cornell-lightdown.jpg and b/images/img-3.08-cornell-lightdown.jpg differ diff --git a/images/img-3.09-cornell-cos-pdf.jpg b/images/img-3.09-cornell-cos-pdf.jpg index f07efe0c..5ab54371 100644 Binary files a/images/img-3.09-cornell-cos-pdf.jpg and b/images/img-3.09-cornell-cos-pdf.jpg differ diff --git a/images/img-3.10-hittable-light.jpg b/images/img-3.10-hittable-light.jpg index 0e4e9f5c..0b86258e 100644 Binary files a/images/img-3.10-hittable-light.jpg and b/images/img-3.10-hittable-light.jpg differ diff --git a/images/img-3.11-cosine-and-light.jpg b/images/img-3.11-cosine-and-light.jpg index 8449cda2..aca37418 100644 Binary files a/images/img-3.11-cosine-and-light.jpg and b/images/img-3.11-cosine-and-light.jpg differ diff --git a/images/img-3.12-arbitrary-pdf.jpg b/images/img-3.12-arbitrary-pdf.jpg index 3313167c..2e043cc4 100644 Binary files a/images/img-3.12-arbitrary-pdf.jpg and b/images/img-3.12-arbitrary-pdf.jpg differ diff --git a/images/img-3.13-cornell-glass-sphere.jpg b/images/img-3.13-cornell-glass-sphere.jpg index 4b49b6a4..2e043cc4 100644 Binary files a/images/img-3.13-cornell-glass-sphere.jpg and b/images/img-3.13-cornell-glass-sphere.jpg differ diff --git a/images/img-3.14-glass-and-light.jpg b/images/img-3.14-glass-and-light.jpg index 071062c5..ebeca3fa 100644 Binary files a/images/img-3.14-glass-and-light.jpg and b/images/img-3.14-glass-and-light.jpg differ diff --git a/images/img-3.15-book3-final.jpg b/images/img-3.15-book3-final.jpg index 5ae7e601..ebeca3fa 100644 Binary files a/images/img-3.15-book3-final.jpg and b/images/img-3.15-book3-final.jpg differ diff --git a/src/InOneWeekend/color.h b/src/InOneWeekend/color.h index 9494a018..115602a8 100644 --- a/src/InOneWeekend/color.h +++ b/src/InOneWeekend/color.h @@ -16,6 +16,7 @@ using color = vec3; + inline double linear_to_gamma(double linear_component) { if (linear_component > 0) @@ -24,6 +25,7 @@ inline double linear_to_gamma(double linear_component) return 0; } + void write_color(std::ostream& out, const color& pixel_color) { auto r = pixel_color.x(); auto g = pixel_color.y(); diff --git a/src/InOneWeekend/rtweekend.h b/src/InOneWeekend/rtweekend.h index 0464d1b1..98218071 100644 --- a/src/InOneWeekend/rtweekend.h +++ b/src/InOneWeekend/rtweekend.h @@ -21,11 +21,13 @@ using std::make_shared; using std::shared_ptr; + // Constants const double infinity = std::numeric_limits::infinity(); const double pi = 3.1415926535897932385; + // Utility Functions inline double degrees_to_radians(double degrees) { @@ -42,6 +44,7 @@ inline double random_double(double min, double max) { return min + (max-min)*random_double(); } + // Common Headers #include "color.h" diff --git a/src/TheNextWeek/color.h b/src/TheNextWeek/color.h index 9494a018..115602a8 100644 --- a/src/TheNextWeek/color.h +++ b/src/TheNextWeek/color.h @@ -16,6 +16,7 @@ using color = vec3; + inline double linear_to_gamma(double linear_component) { if (linear_component > 0) @@ -24,6 +25,7 @@ inline double linear_to_gamma(double linear_component) return 0; } + void write_color(std::ostream& out, const color& pixel_color) { auto r = pixel_color.x(); auto g = pixel_color.y(); diff --git a/src/TheNextWeek/quad.h b/src/TheNextWeek/quad.h index 652f91d4..57ef5cbb 100644 --- a/src/TheNextWeek/quad.h +++ b/src/TheNextWeek/quad.h @@ -14,6 +14,7 @@ #include "hittable.h" #include "hittable_list.h" + class quad : public hittable { public: quad(const point3& Q, const vec3& u, const vec3& v, shared_ptr mat) diff --git a/src/TheNextWeek/rtweekend.h b/src/TheNextWeek/rtweekend.h index 52250318..41028b9d 100644 --- a/src/TheNextWeek/rtweekend.h +++ b/src/TheNextWeek/rtweekend.h @@ -21,11 +21,13 @@ using std::make_shared; using std::shared_ptr; + // Constants const double infinity = std::numeric_limits::infinity(); const double pi = 3.1415926535897932385; + // Utility Functions inline double degrees_to_radians(double degrees) { @@ -47,6 +49,7 @@ inline int random_int(int min, int max) { return int(random_double(min, max+1)); } + // Common Headers #include "color.h" diff --git a/src/TheRestOfYourLife/camera.h b/src/TheRestOfYourLife/camera.h index 777b7844..64ba4a6e 100644 --- a/src/TheRestOfYourLife/camera.h +++ b/src/TheRestOfYourLife/camera.h @@ -14,6 +14,7 @@ #include "rtweekend.h" #include "hittable.h" +#include "pdf.h" #include "material.h" @@ -175,12 +176,13 @@ class camera { mixture_pdf p(light_ptr, srec.pdf_ptr); ray scattered = ray(rec.p, p.generate(), r.time()); - auto pdf_val = p.value(scattered.direction()); + auto pdf_value = p.value(scattered.direction()); double scattering_pdf = rec.mat->scattering_pdf(r, rec, scattered); color sample_color = ray_color(scattered, depth-1, world, lights); - color color_from_scatter = (srec.attenuation * scattering_pdf * sample_color) / pdf_val; + color color_from_scatter = + (srec.attenuation * scattering_pdf * sample_color) / pdf_value; return color_from_emission + color_from_scatter; } diff --git a/src/TheRestOfYourLife/color.h b/src/TheRestOfYourLife/color.h index 1c4a9ac9..22588287 100644 --- a/src/TheRestOfYourLife/color.h +++ b/src/TheRestOfYourLife/color.h @@ -16,6 +16,7 @@ using color = vec3; + inline double linear_to_gamma(double linear_component) { if (linear_component > 0) @@ -24,6 +25,7 @@ inline double linear_to_gamma(double linear_component) return 0; } + void write_color(std::ostream& out, const color& pixel_color) { auto r = pixel_color.x(); auto g = pixel_color.y(); diff --git a/src/TheRestOfYourLife/cos_cubed.cc b/src/TheRestOfYourLife/cos_cubed.cc index fca24927..dcf721de 100644 --- a/src/TheRestOfYourLife/cos_cubed.cc +++ b/src/TheRestOfYourLife/cos_cubed.cc @@ -13,7 +13,7 @@ #include #include -#include + double f(double r2) { // auto x = std::cos(2*pi*r1) * 2 * std::sqrt(r2*(1-r2)); @@ -23,10 +23,12 @@ double f(double r2) { return cos_theta*cos_theta*cos_theta; } + double pdf() { return 1.0 / (2.0*pi); } + int main() { int N = 1000000; diff --git a/src/TheRestOfYourLife/cos_density.cc b/src/TheRestOfYourLife/cos_density.cc index 428fa65d..c1564f26 100644 --- a/src/TheRestOfYourLife/cos_density.cc +++ b/src/TheRestOfYourLife/cos_density.cc @@ -13,17 +13,19 @@ #include #include -#include + double f(const vec3& d) { auto cos_theta = d.z(); return cos_theta*cos_theta*cos_theta; } + double pdf(const vec3& d) { return d.z() / pi; } + int main() { int N = 1000000; diff --git a/src/TheRestOfYourLife/estimate_halfway.cc b/src/TheRestOfYourLife/estimate_halfway.cc index 43513609..98d5cc6a 100644 --- a/src/TheRestOfYourLife/estimate_halfway.cc +++ b/src/TheRestOfYourLife/estimate_halfway.cc @@ -13,40 +13,42 @@ #include #include #include -#include -#include -#include + struct sample { double x; double p_x; }; + bool compare_by_x(const sample& a, const sample& b) { return a.x < b.x; } + int main() { unsigned int N = 10000; double sum = 0.0; - // iterate through all of our samples + // Iterate through all of our samples. + std::vector samples; for (unsigned int i = 0; i < N; i++) { - // Get the area under the curve + // Get the area under the curve. auto x = random_double(0, 2*pi); auto sin_x = std::sin(x); auto p_x = exp(-x / (2*pi)) * sin_x * sin_x; sum += p_x; - // store this sample + + // Store this sample. sample this_sample = {x, p_x}; samples.push_back(this_sample); } - // Sort the samples by x + // Sort the samples by x. std::sort(samples.begin(), samples.end(), compare_by_x); - // Find out the sample at which we have half of our area + // Find out the sample at which we have half of our area. double half_sum = sum / 2.0; double halfway_point = 0.0; double accum = 0.0; diff --git a/src/TheRestOfYourLife/integrate_x_sq.cc b/src/TheRestOfYourLife/integrate_x_sq.cc index 654b5728..dfa2aa24 100644 --- a/src/TheRestOfYourLife/integrate_x_sq.cc +++ b/src/TheRestOfYourLife/integrate_x_sq.cc @@ -13,26 +13,31 @@ #include #include -#include -#include + double f(double d) { return 8.0 * std::pow(d, 1.0/3.0); } + double pdf(double x) { - return (3.0/8.0) * x*x; + return (3.0/8.0) * x*x; } + int main() { int N = 1; - auto sum = 0.0; + for (int i = 0; i < N; i++) { - auto x = f(random_double()); + auto z = random_double(); + if (z == 0.0) // Ignore zero to avoid NaNs + continue; + + auto x = f(z); sum += x*x / pdf(x); } std::cout << std::fixed << std::setprecision(12); - std::cout << "I = " << sum / N << '\n'; + std::cout << "I = " << (sum / N) << '\n'; } diff --git a/src/TheRestOfYourLife/main.cc b/src/TheRestOfYourLife/main.cc index d99c7b88..1386689d 100644 --- a/src/TheRestOfYourLife/main.cc +++ b/src/TheRestOfYourLife/main.cc @@ -12,8 +12,6 @@ #include "rtweekend.h" #include "camera.h" -#include "constant_medium.h" -#include "hittable.h" #include "hittable_list.h" #include "material.h" #include "quad.h" diff --git a/src/TheRestOfYourLife/onb.h b/src/TheRestOfYourLife/onb.h index 43085eae..53f961eb 100644 --- a/src/TheRestOfYourLife/onb.h +++ b/src/TheRestOfYourLife/onb.h @@ -13,6 +13,7 @@ #include "rtweekend.h" + class onb { public: onb() {} diff --git a/src/TheRestOfYourLife/pdf.h b/src/TheRestOfYourLife/pdf.h index 1993b41b..cf635f8a 100644 --- a/src/TheRestOfYourLife/pdf.h +++ b/src/TheRestOfYourLife/pdf.h @@ -1,15 +1,5 @@ #ifndef PDF_H #define PDF_H -//============================================================================================== -// 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 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 "rtweekend.h" @@ -26,35 +16,35 @@ class pdf { }; -class cosine_pdf : public pdf { +class sphere_pdf : public pdf { public: - cosine_pdf(const vec3& w) { uvw.build_from_w(w); } + sphere_pdf() {} double value(const vec3& direction) const override { - auto cosine_theta = dot(unit_vector(direction), uvw.w()); - return std::fmax(0, cosine_theta/pi); + return 1/ (4 * pi); } vec3 generate() const override { - return uvw.local(random_cosine_direction()); + return random_unit_vector(); } - - private: - onb uvw; }; -class sphere_pdf : public pdf { +class cosine_pdf : public pdf { public: - sphere_pdf() {} + cosine_pdf(const vec3& w) { uvw.build_from_w(w); } double value(const vec3& direction) const override { - return 1/ (4 * pi); + auto cosine_theta = dot(unit_vector(direction), uvw.w()); + return std::fmax(0, cosine_theta/pi); } vec3 generate() const override { - return random_unit_vector(); + return uvw.local(random_cosine_direction()); } + + private: + onb uvw; }; diff --git a/src/TheRestOfYourLife/pi.cc b/src/TheRestOfYourLife/pi.cc index 714db06d..2e44ce74 100644 --- a/src/TheRestOfYourLife/pi.cc +++ b/src/TheRestOfYourLife/pi.cc @@ -13,10 +13,11 @@ #include #include -#include int main() { + std::cout << std::fixed << std::setprecision(12); + int inside_circle = 0; int inside_circle_stratified = 0; int sqrt_N = 1000; @@ -25,21 +26,19 @@ int main() { for (int j = 0; j < sqrt_N; j++) { auto x = random_double(-1,1); auto y = random_double(-1,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 << std::fixed << std::setprecision(12); - std::cout << "Regular Estimate of Pi = " - << (4.0 * inside_circle) / (sqrt_N*sqrt_N) << '\n'; - std::cout << "Stratified Estimate of Pi = " + std::cout + << "Regular Estimate of Pi = " + << (4.0 * inside_circle) / (sqrt_N*sqrt_N) << '\n' + << "Stratified Estimate of Pi = " << (4.0 * inside_circle_stratified) / (sqrt_N*sqrt_N) << '\n'; } diff --git a/src/TheRestOfYourLife/quad.h b/src/TheRestOfYourLife/quad.h index f9565d6d..48ec931c 100644 --- a/src/TheRestOfYourLife/quad.h +++ b/src/TheRestOfYourLife/quad.h @@ -14,6 +14,7 @@ #include "hittable.h" #include "hittable_list.h" + class quad : public hittable { public: quad(const point3& Q, const vec3& u, const vec3& v, shared_ptr mat) diff --git a/src/TheRestOfYourLife/rtweekend.h b/src/TheRestOfYourLife/rtweekend.h index 52250318..41028b9d 100644 --- a/src/TheRestOfYourLife/rtweekend.h +++ b/src/TheRestOfYourLife/rtweekend.h @@ -21,11 +21,13 @@ using std::make_shared; using std::shared_ptr; + // Constants const double infinity = std::numeric_limits::infinity(); const double pi = 3.1415926535897932385; + // Utility Functions inline double degrees_to_radians(double degrees) { @@ -47,6 +49,7 @@ inline int random_int(int min, int max) { return int(random_double(min, max+1)); } + // Common Headers #include "color.h" diff --git a/src/TheRestOfYourLife/sphere_importance.cc b/src/TheRestOfYourLife/sphere_importance.cc index b127fa8f..0930931f 100644 --- a/src/TheRestOfYourLife/sphere_importance.cc +++ b/src/TheRestOfYourLife/sphere_importance.cc @@ -13,8 +13,6 @@ #include #include -#include -#include double f(const vec3& d) { @@ -22,10 +20,12 @@ double f(const vec3& d) { return cosine_squared; } + double pdf(const vec3& d) { return 1 / (4*pi); } + int main() { int N = 1000000; auto sum = 0.0; diff --git a/src/TheRestOfYourLife/sphere_plot.cc b/src/TheRestOfYourLife/sphere_plot.cc index b9db5be4..3b754bc8 100644 --- a/src/TheRestOfYourLife/sphere_plot.cc +++ b/src/TheRestOfYourLife/sphere_plot.cc @@ -22,7 +22,6 @@ int main() { auto x = std::cos(2*pi*r1) * 2 * std::sqrt(r2*(1-r2)); auto y = std::sin(2*pi*r1) * 2 * std::sqrt(r2*(1-r2)); auto z = 1 - 2*r2; - std::cout << x << " " << y << " " << z << '\n'; } }