Skip to content

Commit 0e34a73

Browse files
authored
Merge pull request #168 from RayTracing/hollasch/image-pass
Hollasch/image pass
2 parents ddd0e18 + 463d4b2 commit 0e34a73

File tree

103 files changed

+118
-96
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+118
-96
lines changed

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
Ray Tracing In One Weekend Book Series
22
====================================================================================================
33

4-
| ![Ray Tracing in One Weekend][cover1] | ![Ray Tracing: The Next Week][cover2] | ![Ray Tracing: The Rest Of Your Life][cover3]
5-
|:------------------:|:-----------------:|:-------------------------:|
6-
| [In One Weekend][] | [The Next Week][] | [The Rest Of Your Life][] |
4+
| ![RT in One Weekend][cover1] | ![RT The Next Week][cover2] | ![RT The Rest Of Your Life][cover3] |
5+
|:----------------------------:|:---------------------------:|:-----------------------------------:|
6+
| [In One Weekend][] | [The Next Week][] | [The Rest Of Your Life][] |
77

88

99
Getting the Books
@@ -32,10 +32,10 @@ review the [CONTRIBUTING][] document for the most effective way to proceed.
3232
[cover1]: images/RTOneWeekend-small.jpg
3333
[cover2]: images/RTNextWeek-small.jpg
3434
[cover3]: images/RTRestOfYourLife-small.jpg
35-
[In One Weekend]: InOneWeekend
35+
[In One Weekend]: books/RayTracingInOneWeekend.html
3636
[releases]: https://github.com/RayTracing/raytracing.github.io/releases/
3737
[Hack the Hood]: https://hackthehood.org/
3838
[Real-Time Rendering]: https://realtimerendering.com/#books-small-table
3939
[submit issues via GitHub]: https://github.com/raytracing/raytracing.github.io/issues/
40-
[The Next Week]: TheNextWeek
41-
[The Rest Of Your Life]: TheRestOfYourLife
40+
[The Next Week]: books/RayTracingTheNextWeek.html
41+
[The Rest Of Your Life]: books/RayTracingTheRestOfYourLife.html

books/RayTracingInOneWeekend.html

Lines changed: 37 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
<meta charset="utf-8">
2+
<!-- Markdeep: https://casual-effects.com/markdeep/ -->
3+
4+
25

36
**Ray Tracing in One Weekend**
47
Peter Shirley
@@ -63,7 +66,7 @@
6366
write it to a file. The catch is, there are so many formats and many of those are complex. I always
6467
start with a plain text ppm file. Here’s a nice description from Wikipedia:
6568

66-
![Image 1-1: PPM Example](../images/img-1-01-1.jpg)
69+
![Image 2-1: PPM Example](../images/img-1-02-1.jpg)
6770

6871
Let’s make some C++ code to output such a thing:
6972

@@ -105,7 +108,7 @@
105108
Opening the output file (in ToyViewer on my mac, but try it in your favorite viewer and google “ppm
106109
viewer” if your viewer doesn’t support it) shows:
107110

108-
![Image 1-2](../images/img-1-01-2.jpg)
111+
![Image 2-2](../images/img-1-02-2.jpg)
109112

110113
Hooray! This is the graphics “hello world”. If your image doesn’t look like that, open the output
111114
file in a text editor and see what it looks like. It should start something like this:
@@ -329,7 +332,7 @@
329332
front of $A$, and this is what is often called a half-line or ray. The example $C = p(2)$ is shown
330333
here:
331334

332-
![Figure 3-1](../images/fig-1-03-1.jpg)
335+
![Figure 4-1](../images/fig-1-04-1.jpg)
333336

334337
The function $p(t)$ in more verbose code form I call “point_at_parameter(t)”:
335338

@@ -369,7 +372,7 @@
369372
sides to move the ray endpoint across the screen. Note that I do not make the ray direction a unit
370373
length vector because I think not doing that makes for simpler and slightly faster code.
371374

372-
![Figure 3-2](../images/fig-1-03-2.jpg)
375+
![Figure 4-2](../images/fig-1-04-2.jpg)
373376

374377
Below in code, the ray $r$ goes to approximately the pixel centers (I won’t worry about exactness
375378
for now because we’ll add antialiasing later):
@@ -418,7 +421,7 @@
418421

419422
with $t$ going from zero to one. In our case this produces:
420423

421-
![Image 3-1](../images/img-1-03-1.jpg)
424+
![Image 4-1](../images/img-1-04-1.jpg)
422425

423426

424427

@@ -464,7 +467,7 @@
464467
(meaning no real solutions), or zero (meaning one real solution). In graphics, the algebra almost
465468
always relates very directly to the geometry. What we have is:
466469

467-
![Figure 4-1](../images/fig-1-04-1.jpg)
470+
![Figure 5-1](../images/fig-1-05-1.jpg)
468471

469472
If we take that math and hard-code it into our program, we can test it by coloring red any pixel
470473
that hits a small sphere we place at -1 on the z-axis:
@@ -490,7 +493,7 @@
490493

491494
What we get is this:
492495

493-
![Image 4-1](../images/img-1-04-1.jpg)
496+
![Image 5-1](../images/img-1-05-1.jpg)
494497

495498
Now this lacks all sorts of things -- like shading and reflection rays and more than one object --
496499
but we are closer to halfway done than we are to our start! One thing to be aware of is that we
@@ -510,7 +513,7 @@
510513
as are most design decisions like that. For a sphere, the normal is in the direction of the hitpoint
511514
minus the center:
512515

513-
![Figure 5-1](../images/fig-1-05-1.jpg)
516+
![Figure 6-1](../images/fig-1-06-1.jpg)
514517

515518
On the earth, this implies that the vector from the earth’s center to you points straight up. Let’s
516519
throw that into the code now, and shade it. We don’t have any lights or anything yet, so let’s just
@@ -549,7 +552,7 @@
549552

550553
And that yields this picture:
551554

552-
![Image 5-1](../images/img-1-05-1.jpg)
555+
![Image 6-1](../images/img-1-06-1.jpg)
553556

554557
Now, how about several spheres? While it is tempting to have an array of spheres, a very clean
555558
solution is the make an “abstract class” for anything a ray might hit and make both a sphere and a
@@ -725,7 +728,7 @@
725728
This yields a picture that is really just a visualization of where the spheres are along with their
726729
surface normal. This is often a great way to look at your model for flaws and characteristics.
727730

728-
![Image 5-2](../images/img-1-05-2.jpg)
731+
![Image 6-2](../images/img-1-06-2.jpg)
729732

730733

731734

@@ -783,7 +786,7 @@
783786
For a given pixel we have several samples within that pixel and send rays through each of the
784787
samples. The colors of these rays are then averaged:
785788

786-
![Figure 6-1](../images/fig-1-06-1.jpg)
789+
![Figure 7-1](../images/fig-1-07-1.jpg)
787790

788791
Putting that all together yields a camera class encapsulating our simple axis-aligned camera from
789792
before:
@@ -850,7 +853,7 @@
850853
Zooming into the image that is produced, the big change is in edge pixels that are part background
851854
and part foreground:
852855

853-
![Image 6-1](../images/img-1-06-1.jpg)
856+
![Image 7-1](../images/img-1-07-1.jpg)
854857

855858

856859

@@ -869,7 +872,7 @@
869872
direction randomized. So, if we send three rays into a crack between two diffuse surfaces they will
870873
each have different random behavior:
871874

872-
![Figure 7-1](../images/fig-1-07-1.jpg)
875+
![Figure 8-1](../images/fig-1-08-1.jpg)
873876

874877
They also might be absorbed rather than reflected. The darker the surface, the more likely
875878
absorption is. (That’s why it is dark!) Really any algorithm that randomizes direction will produce
@@ -880,7 +883,7 @@
880883
Pick a random point s from the unit radius sphere that is tangent to the hitpoint, and send a ray
881884
from the hitpoint $p$ to the random point $s$. That sphere has center $(p + N)$:
882885

883-
![Figure 7-2](../images/fig-1-07-2.jpg)
886+
![Figure 8-2](../images/fig-1-08-2.jpg)
884887

885888
We also need a way to pick a random point in a unit radius sphere centered at the origin. We’ll use
886889
what is usually the easiest algorithm: a rejection method. First, we pick a random point in the unit
@@ -914,7 +917,7 @@
914917

915918
This gives us:
916919

917-
![Image 7-1](../images/img-1-07-1.jpg)
920+
![Image 8-1](../images/img-1-08-1.jpg)
918921

919922
Note the shadowing under the sphere. This picture is very dark, but our spheres only absorb half the
920923
energy on each bounce, so they are 50% reflectors. If you can’t see the shadow, don’t worry, we will
@@ -936,7 +939,7 @@
936939

937940
That yields light grey, as we desire:
938941

939-
![Image 7-2](../images/img-1-07-2.jpg)
942+
![Image 8-2](../images/img-1-08-2.jpg)
940943

941944
There’s also a subtle bug in there. Some of the reflected rays hit the object they are reflecting
942945
off of not at exactly $t=0$, but instead at $t=-0.0000001$ or $t=0.00000001$ or whatever floating
@@ -1079,7 +1082,7 @@
10791082
For smooth metals the ray won’t be randomly scattered. The key math is: how does a ray get
10801083
reflected from a metal mirror? Vector math is our friend here:
10811084

1082-
![Figure 8-1](../images/fig-1-08-1.jpg)
1085+
![Figure 9-1](../images/fig-1-09-1.jpg)
10831086

10841087
The reflected ray direction in red is just $(v + 2B)$. In our design, $N$ is a unit vector, but $v$
10851088
may not be. The length of $B$ should be $dot(v,N)$. Because $v$ points in, we will need a minus
@@ -1171,12 +1174,12 @@
11711174

11721175
Which gives:
11731176

1174-
![Image 8-1](../images/img-1-08-1.jpg)
1177+
![Image 9-1](../images/img-1-09-1.jpg)
11751178

11761179
We can also randomize the reflected direction by using a small sphere and choosing a new endpoint
11771180
for the ray:
11781181

1179-
![Figure 8-2](../images/fig-1-08-2.jpg)
1182+
![Figure 9-2](../images/fig-1-09-2.jpg)
11801183

11811184
The bigger the sphere, the fuzzier the reflections will be. This suggests adding a fuzziness
11821185
parameter that is just the radius of the sphere (so zero is no perturbation). The catch is that for
@@ -1205,7 +1208,7 @@
12051208

12061209
We can try that out by adding fuzziness 0.3 and 1.0 to the metals:
12071210

1208-
![Image 8-2](../images/img-1-08-2.jpg)
1211+
![Image 9-2](../images/img-1-09-2.jpg)
12091212

12101213

12111214

@@ -1220,7 +1223,7 @@
12201223
there is a refraction ray at all. For this project, I tried to put two glass balls in our scene, and
12211224
I got this (I have not told you how to do this right or wrong yet, but soon!):
12221225

1223-
![Image 9-1](../images/img-1-09-1.jpg)
1226+
![Image 10-1](../images/img-1-10-1.jpg)
12241227

12251228
Is that right? Glass balls look odd in real life. But no, it isn’t right. The world should be
12261229
flipped upside down and no weird black stuff. I just printed out the ray straight through the middle
@@ -1233,7 +1236,7 @@
12331236
Where $n$ and $n'$ are the refractive indices (typically air = 1, glass = 1.3–1.7, diamond = 2.4)
12341237
and the geometry is:
12351238

1236-
![Figure 9-1](../images/fig-1-09-1.jpg)
1239+
![Figure 10-1](../images/fig-1-10-1.jpg)
12371240

12381241
One troublesome practical issue is that when the ray is in the material with the higher refractive
12391242
index, there is no real solution to Snell’s law and thus there is no refraction possible. Here all
@@ -1306,7 +1309,7 @@
13061309

13071310
We get:
13081311

1309-
![Image 9-2](../images/img-1-09-2.jpg)
1312+
![Image 10-2](../images/img-1-10-2.jpg)
13101313

13111314
(The reader Becker has pointed out that when there is a reflection ray the function returns `false`
13121315
so there are no reflections. He is right, and that is why there are none in the image above. I
@@ -1388,7 +1391,7 @@
13881391

13891392
This gives:
13901393

1391-
![Image 9-3](../images/img-1-09-3.jpg)
1394+
![Image 10-3](../images/img-1-10-3.jpg)
13921395

13931396

13941397

@@ -1404,7 +1407,7 @@
14041407
I first keep the rays coming from the origin and heading to the $z = -1$ plane. We could make it the
14051408
$z = -2$ plane, or whatever, as long as we made $h$ a ratio to that distance. Here is our setup:
14061409

1407-
![Figure 10-1](../images/fig-1-10-1.jpg)
1410+
![Figure 11-1](../images/fig-1-11-1.jpg)
14081411

14091412
This implies $h = tan(\theta/2)$. Our camera now becomes:
14101413

@@ -1449,7 +1452,7 @@
14491452

14501453
gives:
14511454

1452-
![Image 10-1](../images/img-1-10-1.jpg)
1455+
![Image 11-1](../images/img-1-11-1.jpg)
14531456

14541457
To get an arbitrary viewpoint, let’s first name the points we care about. We’ll call the position
14551458
where we place the camera _lookfrom_, and the point we look at _lookat_. (Later, if you want, you
@@ -1461,13 +1464,13 @@
14611464
vector for the camera. Notice we already we already have a plane that the up vector should be in,
14621465
the plane orthogonal to the view direction.
14631466

1464-
![Figure 10-2](../images/fig-1-10-2.jpg)
1467+
![Figure 11-2](../images/fig-1-11-2.jpg)
14651468

14661469
We can actually use any up vector we want, and simply project it onto this plane to get an up vector
14671470
for the camera. I use the common convention of naming a “view up” (_vup_) vector. A couple of cross
14681471
products, and we now have a complete orthonormal basis (u,v,w) to describe our camera’s orientation.
14691472

1470-
![Figure 10-3](../images/fig-1-10-3.jpg)
1473+
![Figure 11-3](../images/fig-1-11-3.jpg)
14711474

14721475
Remember that `vup`, `v`, and `w` are all in the same plane. Note that, like before when our fixed
14731476
camera faced -Z, our arbitrary view camera faces -w. And keep in mind that we can -- but we don’t
@@ -1517,11 +1520,11 @@
15171520

15181521
to get:
15191522

1520-
![Image 10-2](../images/img-1-10-2.jpg)
1523+
![Image 11-2](../images/img-1-11-2.jpg)
15211524

15221525
And we can change field of view to get:
15231526

1524-
![Image 10-3](../images/img-1-10-3.jpg)
1527+
![Image 11-3](../images/img-1-11-3.jpg)
15251528

15261529

15271530

@@ -1546,14 +1549,14 @@
15461549
computed (the image is projected upside down on the film). Graphics people usually use a thin lens
15471550
approximation.
15481551

1549-
![Figure 11-1](../images/fig-1-11-1.jpg)
1552+
![Figure 12-1](../images/fig-1-12-1.jpg)
15501553

15511554
We also don’t need to simulate any of the inside of the camera. For the purposes of rendering an
15521555
image outside the camera, that would be unnecessary complexity. Instead I usually start rays from
15531556
the surface of the lens, and send them toward a virtual film plane, by finding the projection of the
15541557
film on the plane that is in focus (at the distance `focus_dist`).
15551558

1556-
![Figure 11-2](../images/fig-1-11-2.jpg)
1559+
![Figure 12-2](../images/fig-1-12-2.jpg)
15571560

15581561
For that we just need to have the ray origins be on a disk around `lookfrom` rather than from a
15591562
point:
@@ -1625,7 +1628,7 @@
16251628

16261629
We get:
16271630

1628-
![Image 11-1](../images/img-1-11-1.jpg)
1631+
![Image 12-1](../images/img-1-12-1.jpg)
16291632

16301633

16311634

@@ -1677,7 +1680,7 @@
16771680

16781681
This gives:
16791682

1680-
![Image 12-1](../images/img-1-12-1.jpg)
1683+
![Image 13-1](../images/img-1-13-1.jpg)
16811684

16821685
An interesting thing you might note is the glass balls don’t really have shadows which makes them
16831686
look like they are floating. This is not a bug (you don’t see glass balls much in real life, where

0 commit comments

Comments
 (0)