|
47 | 47 |
|
48 | 48 | I assume a little bit of familiarity with vectors (like dot product and vector addition). If you
|
49 | 49 | don’t know that, do a little review. If you need that review, or to learn it for the first time,
|
50 |
| -check out Marschner’s and my graphics text, Foley, Van Dam, et al., or McGuire’s graphics codex. |
| 50 | +check out Marschner’s and my graphics text, Foley, Van Dam, _et al._, or McGuire’s graphics codex. |
51 | 51 |
|
52 | 52 | If you run into trouble, or do something cool you’d like to show somebody, send me some email at
|
53 | 53 |
|
|
417 | 417 | between, I want a blend. This forms a “linear blend”, or “linear interpolation”, or “lerp” for
|
418 | 418 | short, between two things. A lerp is always of the form
|
419 | 419 |
|
420 |
| - $$ blendedValue = (1-t)*startValue + t*endValue, $$ |
| 420 | + $$ blendedValue = (1-t)*startValue + t*endValue, $$ |
421 | 421 |
|
422 | 422 | with $t$ going from zero to one. In our case this produces:
|
423 | 423 |
|
|
431 | 431 | Let’s add a single object to our ray tracer. People often use spheres in ray tracers because
|
432 | 432 | calculating whether a ray hits a sphere is pretty straightforward. Recall that the equation for a
|
433 | 433 | sphere centered at the origin of radius $R$ is $x^2 + y^2 + z^2 = R^2$. The way you can read that
|
434 |
| -equation is “for any $(x, y, z)$, if $x^2 + y^2 + z^2 = R^2$ then $(x,y,z)$ is on the sphere, and |
| 434 | +equation is “for any $(x, y, z)$, if $x^2 + y^2 + z^2 = R^2$ then $(x,y,z)$ is on the sphere, and |
435 | 435 | otherwise it is not”. It gets uglier if the sphere center is at $(C_x, C_y, C_z)$:
|
436 | 436 |
|
437 |
| - $$ (x-C_x)^2 + (y-C_y)^2 + (z-C_z)^2 = R^2 $$ |
| 437 | + $$ (x-C_x)^2 + (y-C_y)^2 + (z-C_z)^2 = R^2 $$ |
438 | 438 |
|
439 | 439 | In graphics, you almost always want your formulas to be in terms of vectors so all the x/y/z stuff
|
440 | 440 | is under the hood in the `vec3` class. You might note that the vector from center
|
441 |
| -$ C = (C_x,C_y,C_z) $ to point $ P = (x,y,z) $ is $ (p - C) $, and therefore |
| 441 | +$C = (C_x,C_y,C_z)$ to point $P = (x,y,z)$ is $(p - C)$, and therefore |
442 | 442 |
|
443 |
| - $$ dot((p - C),(p - C)) = (x-C_x)^2 + (y-C_y)^2 + (z-C_z)^2 $$ |
| 443 | + $$ dot((p - C),(p - C)) = (x-C_x)^2 + (y-C_y)^2 + (z-C_z)^2 $$ |
444 | 444 |
|
445 | 445 | So the equation of the sphere in vector form is:
|
446 | 446 |
|
447 |
| - $$ dot((p - C),(p - C)) = R^2 $$ |
| 447 | + $$ dot((p - C),(p - C)) = R^2 $$ |
448 | 448 |
|
449 |
| -We can read this as “any point p that satisfies this equation is on the sphere”. We want to know if |
450 |
| -our ray $ p(t) = A + t*B $ ever hits the sphere anywhere. If it does hit the sphere, there is some |
451 |
| -$t$ for which $p(t)$ satisfies the sphere equation. So we are looking for any t where this is true: |
| 449 | +We can read this as “any point p that satisfies this equation is on the sphere”. We want to know |
| 450 | +if our ray $p(t) = A + t*B$ ever hits the sphere anywhere. If it does hit the sphere, there is |
| 451 | +some $t$ for which $p(t)$ satisfies the sphere equation. So we are looking for any $t$ where this |
| 452 | +is true: |
452 | 453 |
|
453 |
| - $$ dot((p(t) - C),(p(t) - C)) = R^2 $$ |
| 454 | + $$ dot((p(t) - C),(p(t) - C)) = R^2 $$ |
454 | 455 |
|
455 | 456 | or expanding the full form of the ray $p(t)$:
|
456 | 457 |
|
457 |
| - $$ dot((A + t*B - C), (A + t*B - C)) = R^2 $$ |
| 458 | + $$ dot((A + t*B - C), (A + t*B - C)) = R^2 $$ |
458 | 459 |
|
459 | 460 | The rules of vector algebra are all that we would want here, and if we expand that equation and
|
460 | 461 | move all the terms to the left hand side we get:
|
461 | 462 |
|
462 |
| - $$ t^2 \cdot dot(B,B) + 2t \cdot dot(B,A-C) + dot(A-C,A-C) - R^2 = 0 $$ |
| 463 | + $$ t^2 \cdot dot(B,B) + 2t \cdot dot(B,A-C) + dot(A-C,A-C) - R^2 = 0 $$ |
463 | 464 |
|
464 | 465 | The vectors and $R$ in that equation are all constant and known. The unknown is $t$, and the
|
465 | 466 | equation is a quadratic, like you probably saw in your high school math class. You can solve for $t$
|
|
743 | 744 | a bit so we can make a cooler camera later.
|
744 | 745 |
|
745 | 746 | One thing we need is a random number generator that returns real random numbers. We need a function
|
746 |
| -that returns a canonical random number which by convention returns random real in the range |
747 |
| -$0 ≤ ran < 1$. The “less than” before the 1 is important as we will sometimes take advantage of that. |
| 747 | +that returns a canonical random number which by convention returns random real in the range |
| 748 | +$0 ≤ ran < 1$. The “less than” before the 1 is important as we will sometimes take advantage of |
| 749 | +that. |
748 | 750 |
|
749 | 751 | A simple approach to this is to use the `rand()` function that can be found in `<cstdlib>`. This
|
750 | 752 | function returns a random integer in the range 0 and RANDMAX. Hence we can get a real random number
|
|
1231 | 1233 |
|
1232 | 1234 | The refraction is described by Snell’s law:
|
1233 | 1235 |
|
1234 |
| - $$ n \cdot sin(theta) = n' \cdot sin(theta') $$ |
| 1236 | + $$ n \cdot sin(theta) = n' \cdot sin(theta') $$ |
1235 | 1237 |
|
1236 | 1238 | Where $n$ and $n'$ are the refractive indices (typically air = 1, glass = 1.3–1.7, diamond = 2.4)
|
1237 | 1239 | and the geometry is:
|
|
0 commit comments