|
2266 | 2266 | -----------------------
|
2267 | 2267 | Spheres are generally the first ray tracing primitive because their implicit formula makes it so
|
2268 | 2268 | easy to solve for ray intersection. Like spheres, planes also have an implicit formula, and
|
2269 |
| -ray-plane intersection is even _easier_ to solve. |
| 2269 | +we can use their implicit formula to produce an algorithm that solves for ray-plane intersection. |
| 2270 | +Indeed, ray-plane intersection is even _easier_ to solve than ray-sphere intersection. |
2270 | 2271 |
|
2271 | 2272 | You may already know this implicit formula for a plane:
|
2272 | 2273 |
|
|
2279 | 2280 |
|
2280 | 2281 | (We didn't flip the sign of D because it's just some constant that we'll figure out later.)
|
2281 | 2282 |
|
2282 |
| -Here's another way to think of this formula: given the plane perpendicular to the normal vector |
| 2283 | +Here's a good way to think of this formula: given the plane perpendicular to the normal vector |
2283 | 2284 | $\mathbf{n} = (A,B,C)$, and the position vector $\mathbf{v} = (x,y,z)$ (that is, the vector from the
|
2284 |
| -origin to any point on the plane), then |
| 2285 | +origin to any point on the plane), then we can use the dot product to solve for $D$: |
2285 | 2286 |
|
2286 | 2287 | $$ \mathbf{n} \cdot \mathbf{v} = D $$
|
2287 | 2288 |
|
| 2289 | +for any position on the plane. This is an equivalent formulation of the $Ax + By + Cz = D$ formula |
| 2290 | +given above, only now in terms of our 3D values. |
| 2291 | + |
2288 | 2292 | Now to find the intersection with some ray $\mathbf{R}(t) = \mathbf{P} + t\mathbf{d}$. Plugging in
|
2289 | 2293 | the ray equation, we get
|
2290 | 2294 |
|
|
2298 | 2302 |
|
2299 | 2303 | $$ t = \frac{D - \mathbf{n} \cdot \mathbf{P}}{\mathbf{n} \cdot \mathbf{d}} $$
|
2300 | 2304 |
|
2301 |
| -This gives us $t$, which we can plug into the ray equation to find the point of intersection. |
| 2305 | +This gives us $t$, which we can plug into the ray equation to find the point of intersection. Note |
| 2306 | +that the denominator $\mathbf{n} \cdot \mathbf{d}$ will be zero if the ray is parallel to the plane. |
| 2307 | +In this case, we can immediately record a miss between the ray and the plane. As for other |
| 2308 | +primitives, if the ray $t$ parameter is less than the minimum acceptable value, we also record a |
| 2309 | +miss. |
2302 | 2310 |
|
2303 |
| -Ok, we can find the point of intersection between a ray and a plane. This will help us determine |
2304 |
| -whether a ray hits a given quadrilateral, using the plane that contains the (planar) quadrilateral. |
2305 |
| -In fact, we can use this approach to define any planar primitive, like triangles and disks (more |
2306 |
| -later). |
| 2311 | +All right, we can find the point of intersection between a ray and a plane. This will help us |
| 2312 | +determine whether a ray hits a given quadrilateral, using the plane that contains the (planar) |
| 2313 | +quadrilateral. In fact, we can use this approach to define any planar primitive, like triangles and |
| 2314 | +disks (more later). |
2307 | 2315 |
|
2308 | 2316 | We now have three questions we must answer:
|
2309 | 2317 |
|
|
2333 | 2341 |
|
2334 | 2342 | Finding the Plane That Contains a Given Quadrilateral
|
2335 | 2343 | ------------------------------------------------------
|
2336 |
| -We have $O$, $u$, and $v$, and want the corresponding equation of the plane containing all three of |
2337 |
| -these values (and thus the quad itself). |
| 2344 | +We have $\mathbf{O}$, $u$, and $v$, and want the corresponding equation of the plane containing all |
| 2345 | +three of these values (and thus the quad itself). |
2338 | 2346 |
|
2339 | 2347 | Fortunately, this is very simple. Recall that in $Ax + By + Cz = D$, $(A,B,C)$ represents the
|
2340 | 2348 | normal vector. To get this, we just use the cross product of the two side vectors $u$ and $v$:
|
|
2365 | 2373 | Since a plane is a 2D construct, we just need a plane origin point $\mathbf{O}$ and _two_ basis
|
2366 | 2374 | vectors: $\mathbf{u}$ and $\mathbf{v}$. Now normally, you see axes that are perpendicular to each
|
2367 | 2375 | other, so they all meet at 90° angles. However, this doesn't need to be the case in order to span
|
2368 |
| -the entire space -- you just can't have two axes that are parallel to each other. |
| 2376 | +the entire space -- you just need two axes that are not parallel to each other. |
2369 | 2377 |
|
2370 | 2378 | ![Figure [ray-plane]: Ray-plane intersection](../images/fig-2.06-ray-plane.jpg)
|
2371 | 2379 |
|
|
2381 | 2389 |
|
2382 | 2390 | If $\mathbf{u}$ and $\mathbf{v}$ were guaranteed to be orthogonal to each other (forming a 90°
|
2383 | 2391 | angle between them), then this would be a simple matter of projecting $\mathbf{P}$ onto the two
|
2384 |
| -basis vectors $\mathbf{u}$ and $\mathbf{v}$. However, since they can form any angle (other than |
2385 |
| -zero), the math's a little bit tricker. |
| 2392 | +basis vectors $\mathbf{u}$ and $\mathbf{v}$. However, since we are not restricting $u$ and $v$ to be |
| 2393 | +perpendicular, and allowing them to form any angle (other than zero), the math's a little bit |
| 2394 | +trickier. |
2386 | 2395 |
|
2387 | 2396 | $$ \mathbf{P} = \mathbf{O} + \alpha \mathbf{u} + \beta \mathbf{v}$$
|
2388 | 2397 |
|
|
2563 | 2572 |
|
2564 | 2573 | We'll leave these additional 2D primitives as an exercise to the reader, depending on your desire to
|
2565 | 2574 | explore. Consider triangles, disks, and rings. You could even create cut-out stencils based on the
|
2566 |
| -texture map! We've included the solution for triangle, ellipse, and annulus in the commit history |
2567 |
| -(search the history for "annulus"), so you can take a peek if you'd like to see our solution. |
| 2575 | +texture map! |
2568 | 2576 |
|
2569 | 2577 |
|
2570 | 2578 |
|
|
2847 | 2855 | Instances
|
2848 | 2856 | ====================================================================================================
|
2849 | 2857 | The Cornell Box usually has two blocks in it. These are rotated relative to the walls. First, let’s
|
2850 |
| -make an axis-aligned block primitive that holds 6 rectangles: |
| 2858 | +create a function that returns a box, by creating a `hittable_list` of six rectangles: |
2851 | 2859 |
|
2852 | 2860 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
2853 | 2861 | ...
|
|
0 commit comments