|
473 | 473 |
|
474 | 474 | Sending Rays Into the Scene
|
475 | 475 | ----------------------------
|
476 |
| -Now we are ready to turn the corner and make a ray tracer. At the core, the ray tracer sends rays |
477 |
| -through pixels and computes the color seen in the direction of those rays. The involved steps are |
478 |
| -(1) calculate the ray from the eye to the pixel, (2) determine which objects the ray intersects, and |
479 |
| -(3) compute a color for that intersection point. When first developing a ray tracer, I always do a |
480 |
| -simple camera for getting the code up and running. I also make a simple `ray_color(ray)` function |
481 |
| -that returns the color of the background (a simple gradient). |
| 476 | +Now we are ready to turn the corner and make a ray tracer. |
| 477 | +At the core, the ray tracer sends rays through pixels and computes the color seen in the direction |
| 478 | +of those rays. |
| 479 | +The involved steps are |
| 480 | +(1) calculate the ray from the eye to the pixel, |
| 481 | +(2) determine which objects the ray intersects, and |
| 482 | +(3) compute a color for that intersection point. |
| 483 | +When first developing a ray tracer, I always do a simple camera for getting the code up and running. |
| 484 | +I also make a simple `ray_color(ray)` function that returns the color of the background (a simple |
| 485 | +gradient). |
482 | 486 |
|
483 | 487 | I’ve often gotten into trouble using square images for debugging because I transpose $x$ and $y$ too
|
484 |
| -often, so I’ll use a non-square image. For now we'll use a 16:9 aspect ratio, since that's so |
485 |
| -common. |
486 |
| - |
| 488 | +often, so I’ll use a non-square image. |
| 489 | +For now we'll use a 16:9 aspect ratio, since that's so common. |
487 | 490 |
|
488 | 491 | In addition to setting up the pixel dimensions for the rendered image, we also need to set up a
|
489 |
| -virtual viewport through which to pass our scene rays. For the standard pixel spacing (equally |
490 |
| -spaced in both the horizontal and vertical direction), the viewport's aspect ratio should be the |
491 |
| -same as our rendered image. We'll just pick a viewport two units in height. We'll also set the |
492 |
| -distance between the projection plane and the projection point to be one unit. This is referred to |
493 |
| -as the “focal length”, not to be confused with “focus distance”, which we'll present later. |
494 |
| - |
495 |
| -I’ll put the “eye” (or camera center if you think of a camera) at $(0,0,0)$. I will have the y-axis |
496 |
| -go up, and the x-axis to the right. In order to respect the convention of a right handed coordinate |
497 |
| -system, into the screen is the negative z-axis. I will traverse the screen from the upper left hand |
498 |
| -corner, and use two offset vectors along the screen sides to move the ray endpoint across the |
499 |
| -screen. Note that I do not make the ray direction a unit length vector because I think not doing |
500 |
| -that makes for simpler and slightly faster code. |
| 492 | +virtual viewport through which to pass our scene rays. |
| 493 | +For the standard pixel spacing (equally spaced in both the horizontal and vertical direction), the |
| 494 | +viewport's aspect ratio should be the same as our rendered image. |
| 495 | +We'll just pick a viewport two units in height. |
| 496 | +We'll also set the distance between the projection plane and the projection point to be one unit. |
| 497 | +This is referred to as the “focal length”, not to be confused with “focus distance”, which we'll |
| 498 | +present later. |
| 499 | + |
| 500 | +I’ll put the “eye” (or camera center if you think of a camera) at $(0,0,0)$. |
| 501 | +I will have the y-axis go up, and the x-axis to the right. |
| 502 | +In order to respect the convention of a right handed coordinate system, into the screen is the |
| 503 | +negative z-axis. |
| 504 | +I will traverse the screen from the upper left hand corner, and use two offset vectors along the |
| 505 | +screen sides to move the ray endpoint across the screen. |
| 506 | +Note that I do not make the ray direction a unit length vector because I think not doing that makes |
| 507 | +for simpler and slightly faster code. |
501 | 508 |
|
502 | 509 | ![Figure [cam-geom]: Camera geometry](../images/fig-1.03-cam-geom.jpg)
|
503 | 510 |
|
|
569 | 576 |
|
570 | 577 | <div class='together'>
|
571 | 578 | The `ray_color(ray)` function linearly blends white and blue depending on the height of the $y$
|
572 |
| -coordinate _after_ scaling the ray direction to unit length (so $-1.0 < y < 1.0$). Because we're |
573 |
| -looking at the $y$ height after normalizing the vector, you'll notice a horizontal gradient to the |
574 |
| -color in addition to the vertical gradient. |
575 |
| - |
576 |
| -I then did a standard graphics trick of scaling that to $0.0 ≤ t ≤ 1.0$. When $t = 1.0$ I want blue. |
577 |
| -When $t = 0.0$ I want white. In between, I want a blend. This forms a “linear blend”, or “linear |
578 |
| -interpolation”, or “lerp” for short, between two things. A lerp is always of the form |
| 579 | +coordinate _after_ scaling the ray direction to unit length (so $-1.0 < y < 1.0$). |
| 580 | +Because we're looking at the $y$ height after normalizing the vector, you'll notice a horizontal |
| 581 | +gradient to the color in addition to the vertical gradient. |
| 582 | + |
| 583 | +I then did a standard graphics trick of scaling that to $0.0 ≤ t ≤ 1.0$. |
| 584 | +When $t = 1.0$ I want blue. |
| 585 | +When $t = 0.0$ I want white. |
| 586 | +In between, I want a blend. |
| 587 | +This forms a “linear blend”, or “linear interpolation”: commonly referred to as a _lerp_, between |
| 588 | +two things. |
| 589 | +A lerp is always of the form |
579 | 590 |
|
580 | 591 | $$ \text{blendedValue} = (1-t)\cdot\text{startValue} + t\cdot\text{endValue}, $$
|
581 | 592 |
|
582 |
| -with $t$ going from zero to one. In our case this produces: |
| 593 | +with $t$ going from zero to one. |
| 594 | +In our case this produces: |
583 | 595 |
|
584 | 596 | 
|
|
0 commit comments