Skip to content

Commit 59fa57e

Browse files
committed
Fixed the error where the perpendicular and parallel components of a refracted ray were labelled as the other
1 parent 58da8d4 commit 59fa57e

File tree

3 files changed

+14
-13
lines changed

3 files changed

+14
-13
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ Change Log -- Ray Tracing in One Weekend
2929
- Change: Listing 52: Refactored assignment of `etai_over_etat`
3030
- Change: Listing 56: Refactored material declarations
3131
- Change: Listing 61: Refactored material and geometry declarations
32+
- Fix: Rewrote refracted ray perpendicular and parallel components for correctness
3233
- Fix: Corrected various missed change highlights in code listings
3334
- Fix: Listing 7: Added missing `color.h`, `vec3.h` includes
3435
- Fix: Listing 18: Add missing `double t` member of struct `hit_record` (#428)

books/RayTracingInOneWeekend.html

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2346,14 +2346,14 @@
23462346

23472347
On the refracted side of the surface there is a refracted ray $\mathbf{R'}$ and a normal
23482348
$\mathbf{n'}$, and there exists an angle, $\theta'$, between them. We can split $\mathbf{R'}$ into
2349-
the parts of the ray that are parallel to $\mathbf{n'}$ and perpendicular to $\mathbf{n'}$:
2349+
the parts of the ray that are perpendicular to $\mathbf{n'}$ and parallel to $\mathbf{n'}$:
23502350

2351-
$$ \mathbf{R'} = \mathbf{R'}_{\parallel} + \mathbf{R'}_{\bot} $$
2351+
$$ \mathbf{R'} = \mathbf{R'}_{\bot} + \mathbf{R'}_{\parallel} $$
23522352

2353-
If we solve for $\mathbf{R'}_{\parallel}$ and $\mathbf{R'}_{\bot}$ we get:
2353+
If we solve for $\mathbf{R'}_{\bot}$ and $\mathbf{R'}_{\parallel}$ we get:
23542354

2355-
$$ \mathbf{R'}_{\parallel} = \frac{\eta}{\eta'} (\mathbf{R} + \cos\theta \mathbf{n}) $$
2356-
$$ \mathbf{R'}_{\bot} = -\sqrt{1 - |\mathbf{R'}_{\parallel}|^2} \mathbf{n} $$
2355+
$$ \mathbf{R'}_{\bot} = \frac{\eta}{\eta'} (\mathbf{R} + \cos\theta \mathbf{n}) $$
2356+
$$ \mathbf{R'}_{\parallel} = -\sqrt{1 - |\mathbf{R'}_{\bot}|^2} \mathbf{n} $$
23572357

23582358
You can go ahead and prove this for yourself if you want, but we will treat it as fact and move on.
23592359
The rest of the book will not require you to understand the proof.
@@ -2367,19 +2367,19 @@
23672367

23682368
$$ \mathbf{a} \cdot \mathbf{b} = \cos\theta $$
23692369

2370-
We can now rewrite $\mathbf{R'}_{\parallel}$ in terms of known quantities:
2370+
We can now rewrite $\mathbf{R'}_{\bot}$ in terms of known quantities:
23712371

2372-
$$ \mathbf{R'}_{\parallel} =
2372+
$$ \mathbf{R'}_{\bot} =
23732373
\frac{\eta}{\eta'} (\mathbf{R} + (\mathbf{-R} \cdot \mathbf{n}) \mathbf{n}) $$
23742374

23752375
When we combine them back together, we can write a function to calculate $\mathbf{R'}$:
23762376

23772377
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
23782378
vec3 refract(const vec3& uv, const vec3& n, double etai_over_etat) {
23792379
auto cos_theta = dot(-uv, n);
2380-
vec3 r_out_parallel = etai_over_etat * (uv + cos_theta*n);
2381-
vec3 r_out_perp = -sqrt(fabs(1.0 - r_out_parallel.length_squared())) * n;
2382-
return r_out_parallel + r_out_perp;
2380+
vec3 r_out_perp = etai_over_etat * (uv + cos_theta*n);
2381+
vec3 r_out_parallel = -sqrt(fabs(1.0 - r_out_perp.length_squared())) * n;
2382+
return r_out_perp + r_out_parallel;
23832383
}
23842384
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23852385
[Listing [refract]: <kbd>[vec3.h]</kbd> Refraction function]

src/common/vec3.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,9 @@ vec3 reflect(const vec3& v, const vec3& n) {
156156

157157
vec3 refract(const vec3& uv, const vec3& n, double etai_over_etat) {
158158
auto cos_theta = fmin(dot(-uv, n), 1.0);
159-
vec3 r_out_parallel = etai_over_etat * (uv + cos_theta*n);
160-
vec3 r_out_perp = -sqrt(1.0 - r_out_parallel.length_squared()) * n;
161-
return r_out_parallel + r_out_perp;
159+
vec3 r_out_perp = etai_over_etat * (uv + cos_theta*n);
160+
vec3 r_out_parallel = -sqrt(fabs(1.0 - r_out_perp.length_squared())) * n;
161+
return r_out_perp + r_out_parallel;
162162
}
163163

164164

0 commit comments

Comments
 (0)