|
409 | 409 | </div>
|
410 | 410 |
|
411 | 411 | <div class='together'>
|
412 |
| -Note that the blue and red bounding volumes are contained in the purple one, but they might |
413 |
| -overlap, and they are not ordered -- they are just both inside. So the tree shown on the right has |
414 |
| -no concept of ordering in the left and right children; they are simply inside. The code would be: |
| 412 | +Note that the blue and red bounding volumes are contained in the purple one, but they might overlap, |
| 413 | +and they are not ordered -- they are just both inside. So the tree shown on the right has no concept |
| 414 | +of ordering in the left and right children; they are simply inside. The code would be: |
415 | 415 |
|
416 | 416 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
417 | 417 | if (hits purple)
|
|
439 | 439 |
|
440 | 440 | <div class='together'>
|
441 | 441 | Most people use the “slab” method. This is based on the observation that an n-dimensional AABB is
|
442 |
| -just the intersection of n axis-aligned intervals, often called “slabs” An interval is just |
443 |
| -the points between two endpoints, _e.g._, $x$ such that $3 < x < 5$, or more succinctly $x$ in |
444 |
| -$(3,5)$. In 2D, two intervals overlapping makes a 2D AABB (a rectangle): |
| 442 | +just the intersection of n axis-aligned intervals, often called “slabs” An interval is just the |
| 443 | +points between two endpoints, _e.g._, $x$ such that $3 < x < 5$, or more succinctly $x$ in $(3,5)$. |
| 444 | +In 2D, two intervals overlapping makes a 2D AABB (a rectangle): |
445 | 445 |
|
446 | 446 | ![Figure [2daabb]: 2D axis-aligned bounding box](../images/fig.2daabb.jpg)
|
447 | 447 |
|
|
459 | 459 | <div class='together'>
|
460 | 460 | In 3D, those boundaries are planes. The equations for the planes are $x = x_0$, and $x = x_1$. Where
|
461 | 461 | does the ray hit that plane? Recall that the ray can be thought of as just a function that given a
|
462 |
| -$t$ returns a location $p(t)$: |
| 462 | +$t$ returns a location $\mathbf{P}(t)$: |
463 | 463 |
|
464 |
| - $$ p(t) = \mathbf{a} + t \vec{\mathbf{b}} $$ |
| 464 | + $$ \mathbf{P}(t) = \mathbf{A} + t \mathbf{b} $$ |
465 | 465 | </div>
|
466 | 466 |
|
467 | 467 | <div class='together'>
|
468 |
| -That equation applies to all three of the x/y/z coordinates. For example, |
469 |
| -$x(t) = \mathbf{a}_x + t \vec{\mathbf{b}}_x$. This ray hits the plane $x = x_0$ at the $t$ that |
470 |
| -satisfies this equation: |
| 468 | +That equation applies to all three of the x/y/z coordinates. For example, $x(t) = A_x + t b_x$. This |
| 469 | +ray hits the plane $x = x_0$ at the $t$ that satisfies this equation: |
471 | 470 |
|
472 |
| - $$ x_0 = \mathbf{a}_x + t_0 \vec{\mathbf{b}}_x $$ |
| 471 | + $$ x_0 = A_x + t_0 b_x $$ |
473 | 472 | </div>
|
474 | 473 |
|
475 | 474 | <div class='together'>
|
476 | 475 | Thus $t$ at that hitpoint is:
|
477 | 476 |
|
478 |
| - $$ t_0 = \frac{x_0 - \mathbf{a}_x}{\vec{\mathbf{b}}_x} $$ |
| 477 | + $$ t_0 = \frac{x_0 - A_x}{b_x} $$ |
479 | 478 | </div>
|
480 | 479 |
|
481 | 480 | <div class='together'>
|
482 | 481 | We get the similar expression for $x_1$:
|
483 | 482 |
|
484 |
| - $$ t_1 = \frac{x_1 - \mathbf{a}_x}{\vec{\mathbf{b}}_x} $$ |
| 483 | + $$ t_1 = \frac{x_1 - A_x}{b_x} $$ |
485 | 484 | </div>
|
486 | 485 |
|
487 | 486 | <div class='together'>
|
|
526 | 525 | as long as we make it reasonably fast, so let’s go for simplest, which is often fastest anyway!
|
527 | 526 | First let’s look at computing the intervals:
|
528 | 527 |
|
529 |
| - $$ t_{x0} = \frac{x_0 - \mathbf{a}_x}{\vec{\mathbf{b}}_x} $$ |
530 |
| - $$ t_{x1} = \frac{x_1 - \mathbf{a}_x}{\vec{\mathbf{b}}_x} $$ |
| 528 | + $$ t_{x0} = \frac{x_0 - A_x}{b_x} $$ |
| 529 | + $$ t_{x1} = \frac{x_1 - A_x}{b_x} $$ |
531 | 530 | </div>
|
532 | 531 |
|
533 | 532 | <div class='together'>
|
534 |
| -One troublesome thing is that perfectly valid rays will have $\vec{\mathbf{b}}_x = 0$, causing |
535 |
| -division by zero. Some of those rays are inside the slab, and some are not. Also, the zero will have |
536 |
| -a ± sign under IEEE floating point. The good news for $\vec{\mathbf{b}}_x = 0$ is that $t_{x0}$ and |
537 |
| -$t_{x1}$ will both be +∞ or both be -∞ if not between $x_0$ and $x_1$. So, using min and max should |
538 |
| -get us the right answers: |
| 533 | +One troublesome thing is that perfectly valid rays will have $b_x = 0$, causing division by zero. |
| 534 | +Some of those rays are inside the slab, and some are not. Also, the zero will have a ± sign under |
| 535 | +IEEE floating point. The good news for $b_x = 0$ is that $t_{x0}$ and $t_{x1}$ will both be +∞ or |
| 536 | +both be -∞ if not between $x_0$ and $x_1$. So, using min and max should get us the right answers: |
539 | 537 |
|
540 | 538 | $$ t_{x0} = \min(
|
541 |
| - \frac{x_0 - \mathbf{a}_x}{\vec{\mathbf{b}}_x}, |
542 |
| - \frac{x_1 - \mathbf{a}_x}{\vec{\mathbf{b}}_x}) |
| 539 | + \frac{x_0 - A_x}{b_x}, |
| 540 | + \frac{x_1 - A_x}{b_x}) |
543 | 541 | $$
|
544 | 542 |
|
545 | 543 | $$ t_{x1} = \max(
|
546 |
| - \frac{x_0 - \mathbf{a}_x}{\vec{\mathbf{b}}_x}, |
547 |
| - \frac{x_1 - \mathbf{a}_x}{\vec{\mathbf{b}}_x}) |
| 544 | + \frac{x_0 - A_x}{b_x}, |
| 545 | + \frac{x_1 - A_x}{b_x}) |
548 | 546 | $$
|
549 | 547 | </div>
|
550 | 548 |
|
551 |
| -The remaining troublesome case if we do that is if $\vec{\mathbf{b}}_x = 0$ and either |
552 |
| -$x_0 - \mathbf{a}_x = 0$ or $x_1 - \mathbf{a}_x = 0$ so we get a `NaN`. In that case we can probably |
553 |
| -accept either hit or no hit answer, but we’ll revisit that later. |
| 549 | +The remaining troublesome case if we do that is if $b_x = 0$ and either $x_0 - A_x = 0$ or $x_1 - |
| 550 | +A_x = 0$ so we get a `NaN`. In that case we can probably accept either hit or no hit answer, but |
| 551 | +we’ll revisit that later. |
554 | 552 |
|
555 | 553 | <div class='together'>
|
556 | 554 | Now, let’s look at that overlap function. Suppose we can assume the intervals are not reversed (so
|
|
809 | 807 | but that is for speed not correctness. I’ll choose the middle ground, and at each node split the
|
810 | 808 | list along one axis. I’ll go for simplicity:
|
811 | 809 |
|
812 |
| -1. randomly choose an axis |
813 |
| -2. sort the primitives using library qsort |
814 |
| -3. put half in each subtree |
| 810 | + 1. randomly choose an axis |
| 811 | + 2. sort the primitives using library qsort |
| 812 | + 3. put half in each subtree |
815 | 813 |
|
816 | 814 | </div>
|
817 | 815 |
|
818 | 816 | <div class='together'>
|
819 | 817 | When the list coming in is two elements, I put one in each subtree and end the recursion. The
|
820 |
| -traverse algorithm should be smooth and not have to check for null pointers, so if I just have one |
| 818 | +traversal algorithm should be smooth and not have to check for null pointers, so if I just have one |
821 | 819 | element I duplicate it in each subtree. Checking explicitly for three elements and just following
|
822 | 820 | one recursion would probably help a little, but I figure the whole method will get optimized later.
|
823 | 821 | This yields:
|
|
1228 | 1226 | </div>
|
1229 | 1227 |
|
1230 | 1228 | <div class='together'>
|
1231 |
| -Now if we create an actual texture that takes these floats between 0 and 1 and creates grey |
1232 |
| -colors: |
| 1229 | +Now if we create an actual texture that takes these floats between 0 and 1 and creates grey colors: |
1233 | 1230 |
|
1234 | 1231 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1235 | 1232 | #include "perlin.h"
|
|
1710 | 1707 | </div>
|
1711 | 1708 |
|
1712 | 1709 | <div class='together'>
|
1713 |
| -The $atan2$ returns in the range $-\pi$ to $\pi$ so we need to take a little care there. |
| 1710 | +The $atan2$ returns values in the range $-\pi$ to $\pi$, so we need to take a little care there. |
1714 | 1711 | The $\theta$ is more straightforward:
|
1715 | 1712 |
|
1716 | 1713 | $$ \theta = \text{asin}(z) $$
|
|
1746 | 1743 | Storing Texture Image Data
|
1747 | 1744 | ---------------------------
|
1748 | 1745 | Now we also need to create a texture class that holds an image. I am going to use my favorite image
|
1749 |
| -utility [stb_image][]. It reads in an image into a big array of unsigned char. These are just |
1750 |
| -packed RGBs that each range 0..255 (black to full white). The `image_texture` class uses the |
1751 |
| -resulting image data. |
| 1746 | +utility [stb_image][]. It reads in an image into a big array of unsigned char. These are just packed |
| 1747 | +RGBs with each component in the range [0,255] (black to full white). The `image_texture` class uses |
| 1748 | +the resulting image data. |
1752 | 1749 |
|
1753 | 1750 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1754 | 1751 | #include "rtweekend.h"
|
|
1813 | 1810 | [Listing [img-texture]: <kbd>[texture.h]</kbd> Image texture class]
|
1814 | 1811 |
|
1815 | 1812 | <div class='together'>
|
1816 |
| -The representation of a packed array in that order is pretty standard. Thankfully, the |
1817 |
| -[stb_image][] package makes that super simple -- just include the header `rtw_stb_image.h` (found in |
1818 |
| -the project source code at `src/common/rtw_stb_image.h`) in `main.h`: |
| 1813 | +The representation of a packed array in that order is pretty standard. Thankfully, the [stb_image][] |
| 1814 | +package makes that super simple -- just include the header `rtw_stb_image.h` (found in the project |
| 1815 | +source code at `src/common/rtw_stb_image.h`) in `main.h`: |
1819 | 1816 |
|
1820 | 1817 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1821 | 1818 | #include "rtw_stb_image.h"
|
|
1986 | 1983 |
|
1987 | 1984 | <div class='together'>
|
1988 | 1985 | To determine whether a ray hits such a rectangle, we first determine where the ray hits the plane.
|
1989 |
| -Recall that a ray $p(t) = \mathbf{a} + t \cdot \vec{\mathbf{b}}$ has its z component defined by |
1990 |
| -$z(t) = \mathbf{a}_z + t \cdot \vec{\mathbf{b}}_z$. Rearranging those terms we can solve for what |
1991 |
| -the t is where $z=k$. |
| 1986 | +Recall that a ray $\mathbf{P}(t) = \mathbf{A} + t \mathbf{b}$ has its z component defined by $P_z(t) |
| 1987 | += A_z + t b_z$. Rearranging those terms we can solve for what the t is where $z=k$. |
1992 | 1988 |
|
1993 |
| - $$ t = \frac{k-\mathbf{a}_z}{\vec{\mathbf{b}}_z} $$ |
| 1989 | + $$ t = \frac{k-A_z}{b_z} $$ |
1994 | 1990 | </div>
|
1995 | 1991 |
|
1996 | 1992 | <div class='together'>
|
1997 | 1993 | Once we have $t$, we can plug that into the equations for $x$ and $y$:
|
1998 | 1994 |
|
1999 |
| - $$ x = \mathbf{a}_x + t \cdot \vec{\mathbf{b}}_x $$ |
2000 |
| - $$ y = \mathbf{a}_y + t \cdot \vec{\mathbf{b}}_y $$ |
| 1995 | + $$ x = A_x + t b_x $$ |
| 1996 | + $$ y = A_y + t b_y $$ |
2001 | 1997 | </div>
|
2002 | 1998 |
|
2003 | 1999 | It is a hit if $x_0 < x < x_1$ and $y_0 < y < y_1$.
|
|
2258 | 2254 | This is very noisy because the light is small. But we have a problem: some of the walls are facing
|
2259 | 2255 | the wrong way. We haven't specified that a diffuse material should behave differently on different
|
2260 | 2256 | faces of the object, but what if the Cornell box had a different pattern on the inside and outside
|
2261 |
| -walls? The rectangle objects are described such that their front faces are always in the |
2262 |
| -$(1, 0, 0)$, $(0, 1, 0)$, or $(0, 0, 1)$ directions. We need a way to switch the faces of an |
2263 |
| -object. Let’s make a hittable that does nothing but hold another hittable, and flips the face: |
| 2257 | +walls? The rectangle objects are described such that their front faces are always in the directions |
| 2258 | +$(1,0,0)$, $(0,1,0)$, or $(0,0,1)$. We need a way to switch the faces of an object. Let’s make a |
| 2259 | +hittable that does nothing but hold another hittable, and flips the face: |
2264 | 2260 |
|
2265 | 2261 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
2266 | 2262 | class flip_face : public hittable {
|
|
2933 | 2929 |
|
2934 | 2930 |
|
2935 | 2931 |
|
| 2932 | +[Markdeep]: https://casual-effects/markdeep/ |
| 2933 | +[stb_image]: https://github.com/nothings/stb |
| 2934 | + |
| 2935 | + |
| 2936 | + |
2936 | 2937 | <!-- Markdeep: https://casual-effects.com/markdeep/ -->
|
2937 | 2938 | <link rel='stylesheet' href='../style/book.css'>
|
2938 | 2939 | <style class="fallback">body{visibility:hidden;white-space:pre;font-family:monospace}</style>
|
|
0 commit comments