|
2405 | 2405 |
|
2406 | 2406 | vec3 unit_direction = unit_vector(r_in.direction());
|
2407 | 2407 | vec3 refracted = refract(unit_direction, rec.normal, refraction_ratio);
|
| 2408 | + |
2408 | 2409 | scattered = ray(rec.p, refracted);
|
2409 | 2410 | return true;
|
2410 | 2411 | }
|
|
2520 | 2521 | double sin_theta = sqrt(1.0 - cos_theta*cos_theta);
|
2521 | 2522 |
|
2522 | 2523 | bool cannot_refract = refraction_ratio * sin_theta > 1.0;
|
| 2524 | + vec3 direction; |
2523 | 2525 |
|
2524 |
| - // If the ray cannot refract, then return the reflected path. |
2525 | 2526 | if (cannot_refract) {
|
2526 |
| - vec3 reflected = reflect(unit_direction, rec.normal); |
2527 |
| - scattered = ray(rec.p, reflected); |
2528 |
| - return true; |
2529 |
| - } |
2530 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 2527 | + direction = reflect(unit_direction, rec.normal); |
| 2528 | + else |
| 2529 | + direction = refract(unit_direction, rec.normal, refraction_ratio); |
2531 | 2530 |
|
2532 |
| - vec3 refracted = refract(unit_direction, rec.normal, refraction_ratio); |
2533 |
| - scattered = ray(rec.p, refracted); |
| 2531 | + scattered = ray(rec.p, direction); |
| 2532 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2534 | 2533 | return true;
|
2535 | 2534 | }
|
2536 | 2535 |
|
|
2566 | 2565 | <div class='together'>
|
2567 | 2566 | Now real glass has reflectivity that varies with angle -- look at a window at a steep angle and it
|
2568 | 2567 | becomes a mirror. There is a big ugly equation for that, but almost everybody uses a cheap and
|
2569 |
| -surprisingly accurate polynomial approximation by Christophe Schlick: |
2570 |
| - |
2571 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2572 |
| - double schlick(double cosine, double ref_idx) { |
2573 |
| - auto r0 = (1-ref_idx) / (1+ref_idx); |
2574 |
| - r0 = r0*r0; |
2575 |
| - return r0 + (1-r0)*pow((1 - cosine),5); |
2576 |
| - } |
2577 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2578 |
| - [Listing [schlick]: <kbd>[material.h]</kbd> Schlick approximation] |
2579 |
| -</div> |
| 2568 | +surprisingly accurate polynomial approximation by Christophe Schlick. This yields our full glass |
| 2569 | +material: |
2580 | 2570 |
|
2581 |
| -<div class='together'> |
2582 |
| -This yields our full glass material: |
2583 | 2571 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
2584 | 2572 | class dielectric : public material {
|
2585 | 2573 | public:
|
|
2596 | 2584 | double sin_theta = sqrt(1.0 - cos_theta*cos_theta);
|
2597 | 2585 |
|
2598 | 2586 | bool cannot_refract = refraction_ratio * sin_theta > 1.0;
|
| 2587 | + vec3 direction; |
2599 | 2588 |
|
2600 | 2589 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
2601 |
| - // If the ray cannot refract, or if it probabilistically reflects because of its |
2602 |
| - // grazing angle, then return the reflected path. |
2603 |
| - if (cannot_refract || random_double() < schlick(cos_theta, refraction_ratio)) { |
| 2590 | + if (cannot_refract || reflectance(cos_theta, refraction_ratio) > random_double()) |
2604 | 2591 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
2605 |
| - vec3 reflected = reflect(unit_direction, rec.normal); |
2606 |
| - scattered = ray(rec.p, reflected); |
2607 |
| - return true; |
2608 |
| - } |
| 2592 | + direction = reflect(unit_direction, rec.normal); |
| 2593 | + else |
| 2594 | + direction = refract(unit_direction, rec.normal, refraction_ratio); |
2609 | 2595 |
|
2610 |
| - vec3 refracted = refract(unit_direction, rec.normal, refraction_ratio); |
2611 |
| - scattered = ray(rec.p, refracted); |
| 2596 | + scattered = ray(rec.p, direction); |
2612 | 2597 | return true;
|
2613 | 2598 | }
|
2614 | 2599 |
|
2615 | 2600 | public:
|
2616 | 2601 | double ir; // Index of Refraction
|
| 2602 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 2603 | + |
| 2604 | + private: |
| 2605 | + static double reflectance(double cosine, double ref_idx) { |
| 2606 | + // Use Schlick's approximation for reflectance. |
| 2607 | + auto r0 = (1-ref_idx) / (1+ref_idx); |
| 2608 | + r0 = r0*r0; |
| 2609 | + return r0 + (1-r0)*pow((1 - cosine),5); |
| 2610 | + } |
| 2611 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2617 | 2612 | };
|
2618 | 2613 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2619 | 2614 | [Listing [glass]: <kbd>[material.h]</kbd> Full glass material]
|
|
0 commit comments