|
529 | 529 | weighting function should be proportional to $1/pdf$. In fact it is exactly $1/pdf$:
|
530 | 530 |
|
531 | 531 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
532 |
| - inline double pdf(double x) { |
| 532 | + double pdf(double x) { |
533 | 533 | return 0.5*x;
|
534 | 534 | }
|
535 | 535 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
|
563 | 563 | the machinery to get `x = random_double(0,2)`, and the code is:
|
564 | 564 |
|
565 | 565 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
566 |
| - inline double pdf(double x) { |
| 566 | + double pdf(double x) { |
567 | 567 | return 0.5;
|
568 | 568 | }
|
569 | 569 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
|
606 | 606 | sample we get:
|
607 | 607 |
|
608 | 608 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
609 |
| - inline double pdf(double x) { |
| 609 | + double pdf(double x) { |
610 | 610 | return 3*x*x/8;
|
611 | 611 | }
|
612 | 612 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
|
667 | 667 | the z axis:
|
668 | 668 |
|
669 | 669 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
670 |
| - inline double pdf(const vec3& p) { |
| 670 | + double pdf(const vec3& p) { |
671 | 671 | return 1 / (4*pi);
|
672 | 672 | }
|
673 | 673 |
|
|
1264 | 1264 | Let’s also start generating them as random vectors:
|
1265 | 1265 |
|
1266 | 1266 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1267 |
| - #include "rtweekend.h" |
1268 |
| - |
1269 |
| - #include <iostream> |
1270 |
| - #include <math.h> |
1271 |
| - |
1272 | 1267 | inline vec3 random_cosine_direction() {
|
1273 | 1268 | auto r1 = random_double();
|
1274 | 1269 | auto r2 = random_double();
|
|
1280 | 1275 |
|
1281 | 1276 | return vec3(x, y, z);
|
1282 | 1277 | }
|
| 1278 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1279 | + [Listing [random-cosine-direction]: <kbd>vec3.h</kbd> Random cosine direction utility function |
| 1280 | + |
| 1281 | + |
| 1282 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1283 | + #include "rtweekend.h" |
| 1284 | + |
| 1285 | + #include <iostream> |
| 1286 | + #include <iomanip> |
| 1287 | + #include <math.h> |
| 1288 | + |
1283 | 1289 |
|
1284 | 1290 | int main() {
|
1285 | 1291 | int N = 1000000;
|
|
1394 | 1400 | public:
|
1395 | 1401 | onb() {}
|
1396 | 1402 |
|
1397 |
| - inline vec3 operator[](int i) const { return axis[i]; } |
| 1403 | + vec3 operator[](int i) const { return axis[i]; } |
1398 | 1404 |
|
1399 | 1405 | vec3 u() const { return axis[0]; }
|
1400 | 1406 | vec3 v() const { return axis[1]; }
|
|
1725 | 1731 | First, let’s try a cosine density:
|
1726 | 1732 |
|
1727 | 1733 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1728 |
| - inline vec3 random_cosine_direction() { |
1729 |
| - auto r1 = random_double(); |
1730 |
| - auto r2 = random_double(); |
1731 |
| - auto z = sqrt(1-r2); |
1732 |
| - |
1733 |
| - auto phi = 2*pi*r1; |
1734 |
| - auto x = cos(phi)*sqrt(r2); |
1735 |
| - auto y = sin(phi)*sqrt(r2); |
1736 |
| - |
1737 |
| - return vec3(x, y, z); |
1738 |
| - } |
1739 |
| - |
1740 | 1734 | class cosine_pdf : public pdf {
|
1741 | 1735 | public:
|
1742 | 1736 | cosine_pdf(const vec3& w) { uvw.build_from_w(w); }
|
|
2438 | 2432 | The sphere class needs the two PDF-related functions:
|
2439 | 2433 |
|
2440 | 2434 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
| 2435 | + class sphere : public hittable { |
| 2436 | + ... |
| 2437 | + private: |
| 2438 | + ... |
| 2439 | + static vec3 random_to_sphere(double radius, double distance_squared) { |
| 2440 | + auto r1 = random_double(); |
| 2441 | + auto r2 = random_double(); |
| 2442 | + auto z = 1 + r2*(sqrt(1-radius*radius/distance_squared) - 1); |
| 2443 | + |
| 2444 | + auto phi = 2*pi*r1; |
| 2445 | + auto x = cos(phi)*sqrt(1-z*z); |
| 2446 | + auto y = sin(phi)*sqrt(1-z*z); |
| 2447 | + |
| 2448 | + return vec3(x, y, z); |
| 2449 | + } |
| 2450 | + }; |
| 2451 | + |
2441 | 2452 | double sphere::pdf_value(const point3& o, const vec3& v) const {
|
2442 | 2453 | hit_record rec;
|
2443 | 2454 | if (!this->hit(ray(o, v), interval(0.001, infinity), rec))
|
|
2460 | 2471 | [Listing [sphere-pdf]: <kbd>[sphere.h]</kbd> Sphere with PDF]
|
2461 | 2472 | </div>
|
2462 | 2473 |
|
2463 |
| -<div class='together'> |
2464 |
| -With the utility function: |
2465 |
| - |
2466 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2467 |
| - inline vec3 random_to_sphere(double radius, double distance_squared) { |
2468 |
| - auto r1 = random_double(); |
2469 |
| - auto r2 = random_double(); |
2470 |
| - auto z = 1 + r2*(sqrt(1-radius*radius/distance_squared) - 1); |
2471 |
| - |
2472 |
| - auto phi = 2*pi*r1; |
2473 |
| - auto x = cos(phi)*sqrt(1-z*z); |
2474 |
| - auto y = sin(phi)*sqrt(1-z*z); |
2475 |
| - |
2476 |
| - return vec3(x, y, z); |
2477 |
| - } |
2478 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2479 |
| - [Listing [rand-to-sphere]: <kbd>[pdf.h]</kbd> The random_to_sphere utility function] |
2480 |
| -</div> |
2481 |
| - |
2482 | 2474 | <div class='together'>
|
2483 | 2475 | We can first try just sampling the sphere rather than the light:
|
2484 | 2476 |
|
|
0 commit comments