|
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