Skip to content

Commit 8416196

Browse files
committed
Update books: refactored dielectric::scatter()
- Simpler reflection/refraction branching - Global `schlick` function moved to dielectric private `reflectance` function.
1 parent 8d3e88d commit 8416196

File tree

3 files changed

+27
-54
lines changed

3 files changed

+27
-54
lines changed

books/RayTracingInOneWeekend.html

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2405,6 +2405,7 @@
24052405

24062406
vec3 unit_direction = unit_vector(r_in.direction());
24072407
vec3 refracted = refract(unit_direction, rec.normal, refraction_ratio);
2408+
24082409
scattered = ray(rec.p, refracted);
24092410
return true;
24102411
}
@@ -2520,17 +2521,15 @@
25202521
double sin_theta = sqrt(1.0 - cos_theta*cos_theta);
25212522

25222523
bool cannot_refract = refraction_ratio * sin_theta > 1.0;
2524+
vec3 direction;
25232525

2524-
// If the ray cannot refract, then return the reflected path.
25252526
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);
25312530

2532-
vec3 refracted = refract(unit_direction, rec.normal, refraction_ratio);
2533-
scattered = ray(rec.p, refracted);
2531+
scattered = ray(rec.p, direction);
2532+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
25342533
return true;
25352534
}
25362535

@@ -2566,20 +2565,9 @@
25662565
<div class='together'>
25672566
Now real glass has reflectivity that varies with angle -- look at a window at a steep angle and it
25682567
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:
25802570

2581-
<div class='together'>
2582-
This yields our full glass material:
25832571
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
25842572
class dielectric : public material {
25852573
public:
@@ -2596,24 +2584,31 @@
25962584
double sin_theta = sqrt(1.0 - cos_theta*cos_theta);
25972585

25982586
bool cannot_refract = refraction_ratio * sin_theta > 1.0;
2587+
vec3 direction;
25992588

26002589
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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())
26042591
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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);
26092595

2610-
vec3 refracted = refract(unit_direction, rec.normal, refraction_ratio);
2611-
scattered = ray(rec.p, refracted);
2596+
scattered = ray(rec.p, direction);
26122597
return true;
26132598
}
26142599

26152600
public:
26162601
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++
26172612
};
26182613
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26192614
[Listing [glass]: <kbd>[material.h]</kbd> Full glass material]

books/RayTracingTheNextWeek.html

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -308,21 +308,9 @@
308308
class dielectric : public material {
309309
...
310310
virtual bool scatter(
311-
const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
312-
) const override {
313-
314311
...
315-
if (cannot_refract || random_double() < schlick(cos_theta, refraction_ratio)) {
316-
vec3 reflected = reflect(unit_direction, rec.normal);
317-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
318-
scattered = ray(rec.p, reflected, r_in.time());
319-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
320-
return true;
321-
}
322-
323-
vec3 refracted = refract(unit_direction, rec.normal, etai_over_etat);
324312
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
325-
scattered = ray(rec.p, refracted, r_in.time());
313+
scattered = ray(rec.p, direction, r_in.time());
326314
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
327315
return true;
328316
}

books/RayTracingTheRestOfYourLife.html

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,19 +2161,9 @@
21612161
srec.attenuation = color(1.0, 1.0, 1.0);
21622162
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
21632163
double refraction_ratio = rec.front_face ? (1.0/ir) : ir;
2164-
21652164
...
2166-
if (cannot_refract || random_double() < schlick(cos_theta, refraction_ratio)) {
2167-
vec3 reflected = reflect(unit_direction, rec.normal);
2168-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
2169-
srec.specular_ray = ray(rec.p, reflected, r_in.time());
2170-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
2171-
return true;
2172-
}
2173-
2174-
vec3 refracted = refract(unit_direction, rec.normal, refraction_ratio);
21752165
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
2176-
srec.specular_ray = ray(rec.p, refracted, r_in.time());
2166+
srec.specular_ray = ray(rec.p, direction, r_in.time());
21772167
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
21782168
return true;
21792169
}

0 commit comments

Comments
 (0)