diff --git a/books/RayTracingInOneWeekend.html b/books/RayTracingInOneWeekend.html index cf45109e..3ad04c22 100644 --- a/books/RayTracingInOneWeekend.html +++ b/books/RayTracingInOneWeekend.html @@ -3056,7 +3056,7 @@ auto material_right = make_shared(color(0.8, 0.6, 0.2)); world.add(make_shared(point3( 0.0, -100.5, -1.0), 100.0, material_ground)); - world.add(make_shared(point3( 0.0, 0.0, -1.0), 0.5, material_center)); + world.add(make_shared(point3( 0.0, 0.0, -1.2), 0.5, material_center)); world.add(make_shared(point3(-1.0, 0.0, -1.0), 0.5, material_left)); world.add(make_shared(point3( 1.0, 0.0, -1.0), 0.5, material_right)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ @@ -3277,17 +3277,18 @@
-Now we'll update the scene to change the left and center spheres to glass: +Now we'll update the scene to illustrate refraction by changing the left sphere to glass, which has +an index of refraction of approximately 1.5. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ auto material_ground = make_shared(color(0.8, 0.8, 0.0)); + auto material_center = make_shared(color(0.1, 0.2, 0.5)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight - auto material_center = make_shared(1.5); auto material_left = make_shared(1.5); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ auto material_right = make_shared(color(0.8, 0.6, 0.2), 1.0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - [Listing [two-glass]: [main.cc] Changing left and center spheres to glass] + [Listing [two-glass]: [main.cc] Changing the left sphere to glass]
@@ -3302,9 +3303,10 @@ Total Internal Reflection -------------------------- -That definitely doesn't look right. One troublesome practical issue is that when the ray is in the -material with the higher refractive index, there is no real solution to Snell’s law, and thus there -is no refraction possible. If we refer back to Snell's law and the derivation of $\sin\theta'$: +One troublesome practical issue with refraction is that there are ray angles for which no solution +is possible using Snell's law. When a ray enters a medium of lower index of refraction at a +sufficiently glancing angle, it can refract with an angle greater than 90°. If we refer back to +Snell's law and the derivation of $\sin\theta'$: $$ \sin\theta' = \frac{\eta}{\eta'} \cdot \sin\theta $$ @@ -3334,8 +3336,10 @@ Here all the light is reflected, and because in practice that is usually inside solid objects, it is -called “total internal reflection”. This is why sometimes the water-air boundary acts as a perfect -mirror when you are submerged. +called _total internal reflection_. This is why sometimes the water-to-air boundary acts as a +perfect mirror when you are submerged -- if you're under water looking up, you can see things above +the water, but when you are close to the surface and looking sideways, the water surface looks like +a mirror. We can solve for `sin_theta` using the trigonometric qualities: @@ -3400,25 +3404,42 @@ -
-Attenuation is always 1 -- the glass surface absorbs nothing. If we try that out with these -parameters: +Attenuation is always 1 -- the glass surface absorbs nothing. - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ Highlight +If we render the prior scene with the new `dielectric::scatter()` function, we see … no change. Huh? + +Well, it turns out that given a sphere of material with an index of refraction greater than air, +there's no incident angle that will yield total internal reflection -- neither at the ray-sphere +entrance point nor at the ray exit. This is due to the geometry of spheres, as a grazing incoming +ray will always be bent to a smaller angle, and then bent back to the original angle on exit. + +So how can we illustrate total internal reflection? Well, if the sphere has an index of refraction +_less_ than the medium it's in, then we can hit it with shallow grazing angles, getting total +_external_ reflection. That should be good enough to observe the effect. + +We'll model a world filled with water (index of refraction approximately 1.33), and change the +sphere material to air (index of refraction 1.00) -- an air bubble! To do this, change the left +sphere material's index of refraction to + + $$\frac{\text{index of refraction of air}}{\text{index of refraction of water}}$$ + + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ auto material_ground = make_shared(color(0.8, 0.8, 0.0)); auto material_center = make_shared(color(0.1, 0.2, 0.5)); - auto material_left = make_shared(1.5); - auto material_right = make_shared(color(0.8, 0.6, 0.2), 0.0); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight + auto material_left = make_shared(1.00 / 1.33); + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ + auto material_right = make_shared(color(0.8, 0.6, 0.2), 1.0); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - [Listing [scene-dielectric]: [main.cc] Scene with dielectric and shiny sphere] - -
+ [Listing [two-glass]: [main.cc] Left sphere is an air bubble in water]
-We get: +This change yields the following render: + + ![Image 17: Air bubble sometimes refracts, sometimes reflects + ](../images/img-1.17-air-bubble-total-reflection.png class='pixel') - ![Image 17: Glass sphere that sometimes refracts - ](../images/img-1.17-glass-sometimes-refract.png class='pixel') +Here you can see that more-or-less direct rays refract, while glancing rays reflect.
@@ -3509,7 +3530,7 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ ... world.add(make_shared(point3( 0.0, -100.5, -1.0), 100.0, material_ground)); - world.add(make_shared(point3( 0.0, 0.0, -1.0), 0.5, material_center)); + world.add(make_shared(point3( 0.0, 0.0, -1.2), 0.5, material_center)); world.add(make_shared(point3(-1.0, 0.0, -1.0), 0.5, material_left)); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight world.add(make_shared(point3(-1.0, 0.0, -1.0), -0.4, material_left)); @@ -3776,7 +3797,7 @@ auto material_right = make_shared(color(0.8, 0.6, 0.2), 0.0); world.add(make_shared(point3( 0.0, -100.5, -1.0), 100.0, material_ground)); - world.add(make_shared(point3( 0.0, 0.0, -1.0), 0.5, material_center)); + world.add(make_shared(point3( 0.0, 0.0, -1.2), 0.5, material_center)); world.add(make_shared(point3(-1.0, 0.0, -1.0), 0.5, material_left)); world.add(make_shared(point3(-1.0, 0.0, -1.0), -0.4, material_left)); world.add(make_shared(point3( 1.0, 0.0, -1.0), 0.5, material_right)); diff --git a/images/img-1.16-glass-always-refract.png b/images/img-1.16-glass-always-refract.png index df89a382..61e7b4be 100644 Binary files a/images/img-1.16-glass-always-refract.png and b/images/img-1.16-glass-always-refract.png differ diff --git a/images/img-1.17-air-bubble-total-reflection.png b/images/img-1.17-air-bubble-total-reflection.png new file mode 100644 index 00000000..b9e84bf5 Binary files /dev/null and b/images/img-1.17-air-bubble-total-reflection.png differ diff --git a/images/img-1.17-glass-sometimes-refract.png b/images/img-1.17-glass-sometimes-refract.png deleted file mode 100644 index 70f9ff4a..00000000 Binary files a/images/img-1.17-glass-sometimes-refract.png and /dev/null differ