|
3067 | 3067 | auto material_right = make_shared<metal>(color(0.8, 0.6, 0.2));
|
3068 | 3068 |
|
3069 | 3069 | 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)); |
3071 | 3071 | world.add(make_shared<sphere>(point3(-1.0, 0.0, -1.0), 0.5, material_left));
|
3072 | 3072 | world.add(make_shared<sphere>(point3( 1.0, 0.0, -1.0), 0.5, material_right));
|
3073 | 3073 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
|
3309 | 3309 | </div>
|
3310 | 3310 |
|
3311 | 3311 | <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. |
3313 | 3314 |
|
3314 | 3315 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
3315 | 3316 | 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)); |
3316 | 3318 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
3317 |
| - auto material_center = make_shared<dielectric>(1.5); |
3318 | 3319 | auto material_left = make_shared<dielectric>(1.5);
|
3319 | 3320 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
3320 | 3321 | auto material_right = make_shared<metal>(color(0.8, 0.6, 0.2), 1.0);
|
3321 | 3322 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
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] |
3323 | 3324 |
|
3324 | 3325 | </div>
|
3325 | 3326 |
|
|
3334 | 3335 |
|
3335 | 3336 | Total Internal Reflection
|
3336 | 3337 | --------------------------
|
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°. If we refer back to |
| 3341 | +Snell's law and the derivation of $\sin\theta'$: |
3340 | 3342 |
|
3341 | 3343 | $$ \sin\theta' = \frac{\eta}{\eta'} \cdot \sin\theta $$
|
3342 | 3344 |
|
|
3366 | 3368 | </div>
|
3367 | 3369 |
|
3368 | 3370 | 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. |
3371 | 3375 |
|
3372 | 3376 | We can solve for `sin_theta` using the trigonometric qualities:
|
3373 | 3377 |
|
|
3434 | 3438 |
|
3435 | 3439 | </div>
|
3436 | 3440 |
|
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. |
3440 | 3442 |
|
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++ |
3442 | 3461 | auto material_ground = make_shared<lambertian>(color(0.8, 0.8, 0.0));
|
3443 | 3462 | 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); |
3446 | 3467 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
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] |
3450 | 3469 |
|
3451 | 3470 | <div class='together'>
|
3452 |
| -We get: |
| 3471 | +This change yields the following render: |
| 3472 | + |
| 3473 | +  |
3453 | 3475 |
|
3454 |
| -  |
| 3476 | +Here you can see that more-or-less direct rays refract, while glancing rays reflect. |
3456 | 3477 |
|
3457 | 3478 | </div>
|
3458 | 3479 |
|
|
3544 | 3565 | auto material_right = make_shared<metal>(color(0.8, 0.6, 0.2), 0.0);
|
3545 | 3566 |
|
3546 | 3567 | 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)); |
3548 | 3569 | world.add(make_shared<sphere>(point3(-1.0, 0.0, -1.0), 0.5, material_left));
|
3549 | 3570 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
3550 | 3571 | world.add(make_shared<sphere>(point3(-1.0, 0.0, -1.0), 0.4, material_bubble));
|
|
3812 | 3833 | auto material_right = make_shared<metal>(color(0.8, 0.6, 0.2), 0.0);
|
3813 | 3834 |
|
3814 | 3835 | 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)); |
3816 | 3837 | world.add(make_shared<sphere>(point3(-1.0, 0.0, -1.0), 0.5, material_left));
|
3817 | 3838 | world.add(make_shared<sphere>(point3(-1.0, 0.0, -1.0), 0.4, material_bubble));
|
3818 | 3839 | world.add(make_shared<sphere>(point3( 1.0, 0.0, -1.0), 0.5, material_right));
|
|
0 commit comments