Skip to content

Commit 98ef644

Browse files
authored
Fix section describing total internal reflection
With a sphere of index of refraction greater than the surrounding medium, there is no incoming ray that can be chosen to show total internal reflection. An incoming ray will be bent to a smaller angle relative to the surface normal, and then bent back to the original angle on exit. To illustrate total reflection, this change renders a bubble of air inside water. Glancing rays are then reflected off the surface instead of refracted. In the service of this change, I've also moved the center sphere back a bit from the left and right spheres so you can see the affected side more clearly. This will invalidate all of the other three-sphere images, which will be fixed up in #1358 (Alpha.2 milestone verify Book 1 progression). Resolves #900
1 parent bede2f9 commit 98ef644

File tree

4 files changed

+44
-23
lines changed

4 files changed

+44
-23
lines changed

books/RayTracingInOneWeekend.html

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3067,7 +3067,7 @@
30673067
auto material_right = make_shared<metal>(color(0.8, 0.6, 0.2));
30683068

30693069
world.add(make_shared<sphere>(point3( 0.0, -100.5, -1.0), 100.0, material_ground));
3070-
world.add(make_shared<sphere>(point3( 0.0, 0.0, -1.0), 0.5, material_center));
3070+
world.add(make_shared<sphere>(point3( 0.0, 0.0, -1.2), 0.5, material_center));
30713071
world.add(make_shared<sphere>(point3(-1.0, 0.0, -1.0), 0.5, material_left));
30723072
world.add(make_shared<sphere>(point3( 1.0, 0.0, -1.0), 0.5, material_right));
30733073
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
@@ -3309,17 +3309,18 @@
33093309
</div>
33103310

33113311
<div class='together'>
3312-
Now we'll update the scene to change the left and center spheres to glass:
3312+
Now we'll update the scene to illustrate refraction by changing the left sphere to glass, which has
3313+
an index of refraction of approximately 1.5.
33133314

33143315
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
33153316
auto material_ground = make_shared<lambertian>(color(0.8, 0.8, 0.0));
3317+
auto material_center = make_shared<lambertian>(color(0.1, 0.2, 0.5));
33163318
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
3317-
auto material_center = make_shared<dielectric>(1.5);
33183319
auto material_left = make_shared<dielectric>(1.5);
33193320
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
33203321
auto material_right = make_shared<metal>(color(0.8, 0.6, 0.2), 1.0);
33213322
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3322-
[Listing [two-glass]: <kbd>[main.cc]</kbd> Changing left and center spheres to glass]
3323+
[Listing [two-glass]: <kbd>[main.cc]</kbd> Changing the left sphere to glass]
33233324

33243325
</div>
33253326

@@ -3334,9 +3335,10 @@
33343335

33353336
Total Internal Reflection
33363337
--------------------------
3337-
That definitely doesn't look right. One troublesome practical issue is that when the ray is in the
3338-
material with the higher refractive index, there is no real solution to Snell’s law, and thus there
3339-
is no refraction possible. If we refer back to Snell's law and the derivation of $\sin\theta'$:
3338+
One troublesome practical issue with refraction is that there are ray angles for which no solution
3339+
is possible using Snell's law. When a ray enters a medium of lower index of refraction at a
3340+
sufficiently glancing angle, it can refract with an angle greater than 90&deg;. If we refer back to
3341+
Snell's law and the derivation of $\sin\theta'$:
33403342

33413343
$$ \sin\theta' = \frac{\eta}{\eta'} \cdot \sin\theta $$
33423344

@@ -3366,8 +3368,10 @@
33663368
</div>
33673369

33683370
Here all the light is reflected, and because in practice that is usually inside solid objects, it is
3369-
called “total internal reflection”. This is why sometimes the water-air boundary acts as a perfect
3370-
mirror when you are submerged.
3371+
called _total internal reflection_. This is why sometimes the water-to-air boundary acts as a
3372+
perfect mirror when you are submerged -- if you're under water looking up, you can see things above
3373+
the water, but when you are close to the surface and looking sideways, the water surface looks like
3374+
a mirror.
33713375

33723376
We can solve for `sin_theta` using the trigonometric qualities:
33733377

@@ -3434,25 +3438,42 @@
34343438

34353439
</div>
34363440

3437-
<div class='together'>
3438-
Attenuation is always 1 -- the glass surface absorbs nothing. If we try that out with these
3439-
parameters:
3441+
Attenuation is always 1 -- the glass surface absorbs nothing.
34403442

3441-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ Highlight
3443+
If we render the prior scene with the new `dielectric::scatter()` function, we see … no change. Huh?
3444+
3445+
Well, it turns out that given a sphere of material with an index of refraction greater than air,
3446+
there's no incident angle that will yield total internal reflection -- neither at the ray-sphere
3447+
entrance point nor at the ray exit. This is due to the geometry of spheres, as a grazing incoming
3448+
ray will always be bent to a smaller angle, and then bent back to the original angle on exit.
3449+
3450+
So how can we illustrate total internal reflection? Well, if the sphere has an index of refraction
3451+
_less_ than the medium it's in, then we can hit it with shallow grazing angles, getting total
3452+
_external_ reflection. That should be good enough to observe the effect.
3453+
3454+
We'll model a world filled with water (index of refraction approximately 1.33), and change the
3455+
sphere material to air (index of refraction 1.00) -- an air bubble! To do this, change the left
3456+
sphere material's index of refraction to
3457+
3458+
$$\frac{\text{index of refraction of air}}{\text{index of refraction of water}}$$
3459+
3460+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
34423461
auto material_ground = make_shared<lambertian>(color(0.8, 0.8, 0.0));
34433462
auto material_center = make_shared<lambertian>(color(0.1, 0.2, 0.5));
3444-
auto material_left = make_shared<dielectric>(1.5);
3445-
auto material_right = make_shared<metal>(color(0.8, 0.6, 0.2), 0.0);
3463+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
3464+
auto material_left = make_shared<dielectric>(1.00 / 1.33);
3465+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
3466+
auto material_right = make_shared<metal>(color(0.8, 0.6, 0.2), 1.0);
34463467
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3447-
[Listing [scene-dielectric]: <kbd>[main.cc]</kbd> Scene with dielectric and shiny sphere]
3448-
3449-
</div>
3468+
[Listing [two-glass]: <kbd>[main.cc]</kbd> Left sphere is an air bubble in water]
34503469

34513470
<div class='together'>
3452-
We get:
3471+
This change yields the following render:
3472+
3473+
![<span class='num'>Image 17:</span> Air bubble sometimes refracts, sometimes reflects
3474+
](../images/img-1.17-air-bubble-total-reflection.png class='pixel')
34533475

3454-
![<span class='num'>Image 17:</span> Glass sphere that sometimes refracts
3455-
](../images/img-1.17-glass-sometimes-refract.png class='pixel')
3476+
Here you can see that more-or-less direct rays refract, while glancing rays reflect.
34563477

34573478
</div>
34583479

@@ -3544,7 +3565,7 @@
35443565
auto material_right = make_shared<metal>(color(0.8, 0.6, 0.2), 0.0);
35453566

35463567
world.add(make_shared<sphere>(point3( 0.0, -100.5, -1.0), 100.0, material_ground));
3547-
world.add(make_shared<sphere>(point3( 0.0, 0.0, -1.0), 0.5, material_center));
3568+
world.add(make_shared<sphere>(point3( 0.0, 0.0, -1.2), 0.5, material_center));
35483569
world.add(make_shared<sphere>(point3(-1.0, 0.0, -1.0), 0.5, material_left));
35493570
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
35503571
world.add(make_shared<sphere>(point3(-1.0, 0.0, -1.0), 0.4, material_bubble));
@@ -3812,7 +3833,7 @@
38123833
auto material_right = make_shared<metal>(color(0.8, 0.6, 0.2), 0.0);
38133834

38143835
world.add(make_shared<sphere>(point3( 0.0, -100.5, -1.0), 100.0, material_ground));
3815-
world.add(make_shared<sphere>(point3( 0.0, 0.0, -1.0), 0.5, material_center));
3836+
world.add(make_shared<sphere>(point3( 0.0, 0.0, -1.2), 0.5, material_center));
38163837
world.add(make_shared<sphere>(point3(-1.0, 0.0, -1.0), 0.5, material_left));
38173838
world.add(make_shared<sphere>(point3(-1.0, 0.0, -1.0), 0.4, material_bubble));
38183839
world.add(make_shared<sphere>(point3( 1.0, 0.0, -1.0), 0.5, material_right));
6.31 KB
Loading
72 KB
Loading
-73.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)