|
2395 | 2395 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2396 | 2396 | class dielectric : public material { |
2397 | 2397 | public: |
2398 | | - dielectric(double ri) : ref_idx(ri) {} |
| 2398 | + dielectric(double index_of_refraction) : ir(index_of_refraction) {} |
2399 | 2399 |
|
2400 | 2400 | virtual bool scatter( |
2401 | 2401 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered |
2402 | 2402 | ) const override { |
2403 | 2403 | attenuation = color(1.0, 1.0, 1.0); |
2404 | | - double etai_over_etat = rec.front_face ? (1.0 / ref_idx) : ref_idx; |
| 2404 | + double refraction_ratio = rec.front_face ? (1.0/ir) : ir; |
2405 | 2405 |
|
2406 | 2406 | vec3 unit_direction = unit_vector(r_in.direction()); |
2407 | | - vec3 refracted = refract(unit_direction, rec.normal, etai_over_etat); |
| 2407 | + vec3 refracted = refract(unit_direction, rec.normal, refraction_ratio); |
2408 | 2408 | scattered = ray(rec.p, refracted); |
2409 | 2409 | return true; |
2410 | 2410 | } |
2411 | 2411 |
|
2412 | | - double ref_idx; |
| 2412 | + public: |
| 2413 | + double ir; // Index of Refraction |
2413 | 2414 | }; |
2414 | 2415 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2415 | 2416 | [Listing [dielectric]: <kbd>[material.h]</kbd> Dielectric material class that always refracts] |
|
2458 | 2459 | solution does not exist, the glass cannot refract, and therefore must reflect the ray: |
2459 | 2460 |
|
2460 | 2461 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2461 | | - if (etai_over_etat * sin_theta > 1.0) { |
| 2462 | + if (refraction_ratio * sin_theta > 1.0) { |
2462 | 2463 | // Must Reflect |
2463 | 2464 | ... |
2464 | 2465 | } else { |
|
2487 | 2488 | double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0); |
2488 | 2489 | double sin_theta = sqrt(1.0 - cos_theta*cos_theta); |
2489 | 2490 |
|
2490 | | - if (etai_over_etat * sin_theta > 1.0) { |
| 2491 | + if (refraction_ratio * sin_theta > 1.0) { |
2491 | 2492 | // Must Reflect |
2492 | 2493 | ... |
2493 | 2494 | } else { |
|
2505 | 2506 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2506 | 2507 | class dielectric : public material { |
2507 | 2508 | public: |
2508 | | - dielectric(double ri) : ref_idx(ri) {} |
| 2509 | + dielectric(double index_of_refraction) : ir(index_of_refraction) {} |
2509 | 2510 |
|
2510 | 2511 | virtual bool scatter( |
2511 | 2512 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered |
2512 | 2513 | ) const override { |
2513 | 2514 | attenuation = color(1.0, 1.0, 1.0); |
2514 | | - double etai_over_etat = rec.front_face ? (1.0 / ref_idx) : ref_idx; |
| 2515 | + double refraction_ratio = rec.front_face ? (1.0/ir) : ir; |
2515 | 2516 |
|
2516 | 2517 | vec3 unit_direction = unit_vector(r_in.direction()); |
2517 | | - |
2518 | | - |
2519 | 2518 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
2520 | 2519 | double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0); |
2521 | 2520 | double sin_theta = sqrt(1.0 - cos_theta*cos_theta); |
2522 | | - if (etai_over_etat * sin_theta > 1.0 ) { |
| 2521 | + |
| 2522 | + bool cannot_refract = refraction_ratio * sin_theta > 1.0; |
| 2523 | + |
| 2524 | + // If the ray cannot refract, then return the reflected path. |
| 2525 | + if (cannot_refract) { |
2523 | 2526 | vec3 reflected = reflect(unit_direction, rec.normal); |
2524 | 2527 | scattered = ray(rec.p, reflected); |
2525 | 2528 | return true; |
2526 | 2529 | } |
2527 | 2530 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2528 | 2531 |
|
2529 | | - vec3 refracted = refract(unit_direction, rec.normal, etai_over_etat); |
| 2532 | + vec3 refracted = refract(unit_direction, rec.normal, refraction_ratio); |
2530 | 2533 | scattered = ray(rec.p, refracted); |
2531 | 2534 | return true; |
2532 | 2535 | } |
2533 | 2536 |
|
2534 | 2537 | public: |
2535 | | - double ref_idx; |
| 2538 | + double ir; // Index of Refraction |
2536 | 2539 | }; |
2537 | 2540 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2538 | 2541 | [Listing [dielectric]: <kbd>[material.h]</kbd> Dielectric material class with reflection] |
|
2580 | 2583 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2581 | 2584 | class dielectric : public material { |
2582 | 2585 | public: |
2583 | | - dielectric(double ri) : ref_idx(ri) {} |
| 2586 | + dielectric(double index_of_refraction) : ir(index_of_refraction) {} |
2584 | 2587 |
|
2585 | 2588 | virtual bool scatter( |
2586 | 2589 | const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered |
2587 | 2590 | ) const override { |
2588 | 2591 | attenuation = color(1.0, 1.0, 1.0); |
2589 | | - double etai_over_etat = rec.front_face ? (1.0 / ref_idx) : ref_idx; |
| 2592 | + double refraction_ratio = rec.front_face ? (1.0/ir) : ir; |
2590 | 2593 |
|
2591 | 2594 | vec3 unit_direction = unit_vector(r_in.direction()); |
2592 | 2595 | double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0); |
2593 | 2596 | double sin_theta = sqrt(1.0 - cos_theta*cos_theta); |
2594 | | - if (etai_over_etat * sin_theta > 1.0 ) { |
2595 | | - vec3 reflected = reflect(unit_direction, rec.normal); |
2596 | | - scattered = ray(rec.p, reflected); |
2597 | | - return true; |
2598 | | - } |
| 2597 | + |
| 2598 | + bool cannot_refract = refraction_ratio * sin_theta > 1.0; |
| 2599 | + |
2599 | 2600 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
2600 | | - double reflect_prob = schlick(cos_theta, etai_over_etat); |
2601 | | - if (random_double() < reflect_prob) |
2602 | | - { |
| 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)) { |
| 2604 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2603 | 2605 | vec3 reflected = reflect(unit_direction, rec.normal); |
2604 | 2606 | scattered = ray(rec.p, reflected); |
2605 | 2607 | return true; |
2606 | 2608 | } |
2607 | | - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2608 | | - vec3 refracted = refract(unit_direction, rec.normal, etai_over_etat); |
| 2609 | + |
| 2610 | + vec3 refracted = refract(unit_direction, rec.normal, refraction_ratio); |
2609 | 2611 | scattered = ray(rec.p, refracted); |
2610 | 2612 | return true; |
2611 | 2613 | } |
2612 | 2614 |
|
2613 | 2615 | public: |
2614 | | - double ref_idx; |
| 2616 | + double ir; // Index of Refraction |
2615 | 2617 | }; |
2616 | 2618 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2617 | 2619 | [Listing [glass]: <kbd>[material.h]</kbd> Full glass material] |
|
0 commit comments