|
69 | 69 | write it to a file. The catch is, there are so many formats. Many of those are complex. I always
|
70 | 70 | start with a plain text ppm file. Here’s a nice description from Wikipedia:
|
71 | 71 |
|
72 |
| -  |
| 72 | + ![Figure [ppm]: PPM Example](../images/fig-1.01-ppm.jpg) |
73 | 73 |
|
74 | 74 | <div class='together'>
|
75 | 75 | Let’s make some C++ code to output such a thing:
|
|
418 | 418 | can go anywhere on the 3D line. For positive $t$, you get only the parts in front of $\mathbf{A}$,
|
419 | 419 | and this is what is often called a half-line or ray.
|
420 | 420 |
|
421 |
| - ![Figure [lerp]: Linear interpolation](../images/fig.lerp.jpg) |
| 421 | + ![Figure [lerp]: Linear interpolation](../images/fig-1.02-lerp.jpg) |
422 | 422 |
|
423 | 423 | </div>
|
424 | 424 |
|
|
473 | 473 | sides to move the ray endpoint across the screen. Note that I do not make the ray direction a unit
|
474 | 474 | length vector because I think not doing that makes for simpler and slightly faster code.
|
475 | 475 |
|
476 |
| - ![Figure [cam-geom]: Camera geometry](../images/fig.cam-geom.jpg) |
| 476 | + ![Figure [cam-geom]: Camera geometry](../images/fig-1.03-cam-geom.jpg) |
477 | 477 |
|
478 | 478 | <div class='together'>
|
479 | 479 | Below in code, the ray `r` goes to approximately the pixel centers (I won’t worry about exactness
|
|
611 | 611 | (meaning no real solutions), or zero (meaning one real solution). In graphics, the algebra almost
|
612 | 612 | always relates very directly to the geometry. What we have is:
|
613 | 613 |
|
614 |
| - ![Figure [ray-sphere]: Ray-sphere intersection results](../images/fig.ray-sphere.jpg) |
| 614 | + ![Figure [ray-sphere]: Ray-sphere intersection results](../images/fig-1.04-ray-sphere.jpg) |
615 | 615 |
|
616 | 616 | </div>
|
617 | 617 |
|
|
676 | 676 | personal preference as are most design decisions like that. For a sphere, the outward normal is in
|
677 | 677 | the direction of the hit point minus the center:
|
678 | 678 |
|
679 |
| - ![Figure [surf-normal]: Sphere surface-normal geometry](../images/fig.sphere-normal.jpg) |
| 679 | + ![Figure [sphere-normal]: Sphere surface-normal geometry](../images/fig-1.05-sphere-normal.jpg) |
680 | 680 |
|
681 | 681 | <div class='together'>
|
682 | 682 | On the earth, this implies that the vector from the earth’s center to you points straight up. Let’s
|
|
886 | 886 | the sphere, the normal will point outward, but if the ray is inside the sphere, the normal will
|
887 | 887 | point inward.
|
888 | 888 |
|
889 |
| - ![Figure [normal-directions]: Possible directions for sphere surface-normal geometry |
890 |
| - ](../images/fig.normal-possibilities.jpg) |
| 889 | + ![Figure [normal-sides]: Possible directions for sphere surface-normal geometry |
| 890 | + ](../images/fig-1.06-normal-sides.jpg) |
891 | 891 |
|
892 | 892 | </div>
|
893 | 893 |
|
|
1308 | 1308 | For a given pixel we have several samples within that pixel and send rays through each of the
|
1309 | 1309 | samples. The colors of these rays are then averaged:
|
1310 | 1310 |
|
1311 |
| - ![Figure [pixel-samples]: Pixel samples](../images/fig.pixel-samples.jpg) |
| 1311 | + ![Figure [pixel-samples]: Pixel samples](../images/fig-1.07-pixel-samples.jpg) |
1312 | 1312 |
|
1313 | 1313 | </div>
|
1314 | 1314 |
|
|
1452 | 1452 | direction randomized. So, if we send three rays into a crack between two diffuse surfaces they will
|
1453 | 1453 | each have different random behavior:
|
1454 | 1454 |
|
1455 |
| - ![Figure [light-bounce]: Light ray bounces](../images/fig.light-bounce.jpg) |
| 1455 | + ![Figure [light-bounce]: Light ray bounces](../images/fig-1.08-light-bounce.jpg) |
1456 | 1456 |
|
1457 | 1457 | </div>
|
1458 | 1458 |
|
|
1476 | 1476 | from the hit point $\mathbf{P}$ to the random point $\mathbf{S}$ (this is the vector
|
1477 | 1477 | $(\mathbf{S}-\mathbf{P})$):
|
1478 | 1478 |
|
1479 |
| - ![Figure [rand-vector]: Generating a random diffuse bounce ray](../images/fig.rand-vector.jpg) |
| 1479 | + ![Figure [rand-vec]: Generating a random diffuse bounce ray](../images/fig-1.09.rand-vec.jpg) |
1480 | 1480 |
|
1481 | 1481 | </div>
|
1482 | 1482 |
|
|
1693 | 1693 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1694 | 1694 | [Listing [random-unit-vector]: <kbd>[vec3.h]</kbd> The random_unit_vector() function]
|
1695 | 1695 |
|
1696 |
| - ![Figure [rand-unit-vector]: Generating a random unit vector](../images/fig.rand-unitvector.png) |
| 1696 | + ![Figure [rand-unitvec]: Generating a random unit vector](../images/fig-1.10-rand-unitvec.png) |
1697 | 1697 |
|
1698 | 1698 | </div>
|
1699 | 1699 |
|
|
2006 | 2006 | For smooth metals the ray won’t be randomly scattered. The key math is: how does a ray get
|
2007 | 2007 | reflected from a metal mirror? Vector math is our friend here:
|
2008 | 2008 |
|
2009 |
| - ![Figure [reflection]: Ray reflection](../images/fig.ray-reflect.jpg) |
| 2009 | + ![Figure [reflection]: Ray reflection](../images/fig-1.11-reflection.jpg) |
2010 | 2010 |
|
2011 | 2011 | </div>
|
2012 | 2012 |
|
|
2141 | 2141 | We can also randomize the reflected direction by using a small sphere and choosing a new endpoint
|
2142 | 2142 | for the ray:
|
2143 | 2143 |
|
2144 |
| - ![Figure [reflect-fuzzy]: Generating fuzzed reflection rays](../images/fig.reflect-fuzzy.jpg) |
| 2144 | + ![Figure [reflect-fuzzy]: Generating fuzzed reflection rays](../images/fig-1.12-reflect-fuzzy.jpg) |
2145 | 2145 |
|
2146 | 2146 | </div>
|
2147 | 2147 |
|
|
2224 | 2224 | "eta" and "eta prime") are the refractive indices (typically air = 1.0, glass = 1.3–1.7, diamond =
|
2225 | 2225 | 2.4). The geometry is:
|
2226 | 2226 |
|
2227 |
| - ![Figure [ray-refract]: Refracted ray geometry](../images/fig.ray-refract.jpg) |
| 2227 | + ![Figure [refraction]: Ray refraction](../images/fig-1.13-refraction.jpg) |
2228 | 2228 |
|
2229 | 2229 | </div>
|
2230 | 2230 |
|
|
2536 | 2536 | I first keep the rays coming from the origin and heading to the $z = -1$ plane. We could make it the
|
2537 | 2537 | $z = -2$ plane, or whatever, as long as we made $h$ a ratio to that distance. Here is our setup:
|
2538 | 2538 |
|
2539 |
| - ![Figure [cam-view-geom]: Camera viewing geometry](../images/fig.cam-view-geom.jpg) |
| 2539 | + ![Figure [cam-view-geom]: Camera viewing geometry](../images/fig-1.14-cam-view-geom.jpg) |
2540 | 2540 |
|
2541 | 2541 | </div>
|
2542 | 2542 |
|
|
2607 | 2607 | constant, you can still rotate your head around your nose. What we need is a way to specify an “up”
|
2608 | 2608 | vector for the camera. This up vector should lie in the plane orthogonal to the view direction.
|
2609 | 2609 |
|
2610 |
| - ![Figure [cam-look]: Camera view direction](../images/fig.cam-look.jpg) |
| 2610 | + ![Figure [cam-view-dir]: Camera view direction](../images/fig-1.15-cam-view-dir.jpg) |
2611 | 2611 |
|
2612 | 2612 | We can actually use any up vector we want, and simply project it onto this plane to get an up vector
|
2613 | 2613 | for the camera. I use the common convention of naming a “view up” (_vup_) vector. A couple of cross
|
2614 | 2614 | products, and we now have a complete orthonormal basis $(u,v,w)$ to describe our camera’s
|
2615 | 2615 | orientation.
|
2616 | 2616 |
|
2617 |
| - ![Figure [cam-up]: Camera view up direction](../images/fig.cam-up.jpg) |
| 2617 | + ![Figure [cam-view-up]: Camera view up direction](../images/fig-1.16-cam-view-up.jpg) |
2618 | 2618 |
|
2619 | 2619 | Remember that `vup`, `v`, and `w` are all in the same plane. Note that, like before when our fixed
|
2620 | 2620 | camera faced -Z, our arbitrary view camera faces -w. And keep in mind that we can -- but we don’t
|
|
2721 | 2721 | it's computed (the image is projected upside down on the film). Graphics people, however, usually
|
2722 | 2722 | use a thin lens approximation:
|
2723 | 2723 |
|
2724 |
| - ![Figure [cam-lens]: Camera lens model](../images/fig.cam-lens.jpg) |
| 2724 | + ![Figure [cam-lens]: Camera lens model](../images/fig-1.17-cam-lens.jpg) |
2725 | 2725 |
|
2726 | 2726 | </div>
|
2727 | 2727 |
|
|
2731 | 2731 | surface of the lens, and send them toward a virtual film plane, by finding the projection of the
|
2732 | 2732 | film on the plane that is in focus (at the distance `focus_dist`).
|
2733 | 2733 |
|
2734 |
| - ![Figure [cam-film-plane]: Camera focus plane](../images/fig.cam-film-plane.jpg) |
| 2734 | + ![Figure [cam-film-plane]: Camera focus plane](../images/fig-1.18-cam-film-plane.jpg) |
2735 | 2735 |
|
2736 | 2736 | </div>
|
2737 | 2737 |
|
|
0 commit comments