Skip to content

Commit 1602c7c

Browse files
authored
Merge pull request #761 from RayTracing/fix-random-unit-vec
Fix `random_unit_vector()`
2 parents 8b4f5ac + 8a80522 commit 1602c7c

File tree

4 files changed

+20
-41
lines changed

4 files changed

+20
-41
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ Change Log -- Ray Tracing in One Weekend
44
# v3.2.2 (in progress)
55

66
### Common
7-
- Fix: Added `fmin` to book text for `cos_theta` of `refract`
7+
- Fix: Added `fmin` to book text for `cos_theta` of `refract` (#732)
88
- Fix: Standardized naming for ray-t and time parameters (#746)
9+
- Fix: `random_unit_vector()` was incorrect (#697)
910

1011
### In One Weekend
1112

books/RayTracingInOneWeekend.html

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,16 +1764,18 @@
17641764

17651765
However, we are interested in a Lambertian distribution, which has a distribution of $\cos (\phi)$.
17661766
True Lambertian has the probability higher for ray scattering close to the normal, but the
1767-
distribution is more uniform. This is achieved by picking points on the surface of the unit sphere,
1768-
offset along the surface normal. Picking points on the sphere can be achieved by picking points in
1769-
the unit ball, and then normalizing those.
1767+
distribution is more uniform. This is achieved by picking random points on the surface of the unit
1768+
sphere, offset along the surface normal. Picking random points on the unit sphere can be achieved by
1769+
picking random points _in_ the unit sphere, and then normalizing those.
17701770

17711771
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
1772+
inline vec3 random_in_unit_sphere() {
1773+
...
1774+
}
1775+
1776+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
17721777
vec3 random_unit_vector() {
1773-
auto a = random_double(0, 2*pi);
1774-
auto z = random_double(-1, 1);
1775-
auto r = sqrt(1 - z*z);
1776-
return vec3(r*cos(a), r*sin(a), z);
1778+
return unit_vector(random_in_unit_sphere());
17771779
}
17781780
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17791781
[Listing [random-unit-vector]: <kbd>[vec3.h]</kbd> The random_unit_vector() function]

books/RayTracingTheRestOfYourLife.html

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -544,33 +544,12 @@
544544

545545
$$ \int cos^2(\theta) $$
546546

547-
<div class='together'>
548547
By MC integration, we should just be able to sample $\cos^2(\theta) / p(\text{direction})$, but what
549-
is direction in that context? We could make it based on polar coordinates, so $p$ would be in terms
550-
of $(\theta, \phi)$. However you do it, remember that a PDF has to integrate to 1 and represent the
551-
relative probability of that direction being sampled. We have a method from the last books to take
552-
uniform random samples in or on a unit sphere:
553-
554-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
555-
vec3 random_unit_vector() {
556-
auto a = random_double(0, 2*pi);
557-
auto z = random_double(-1, 1);
558-
auto r = sqrt(1 - z*z);
559-
return vec3(r*cos(a), r*sin(a), z);
560-
}
561-
562-
...
563-
564-
vec3 random_in_unit_sphere() {
565-
while (true) {
566-
auto p = vec3::random(-1,1);
567-
if (p.length_squared() >= 1) continue;
568-
return p;
569-
}
570-
}
571-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
572-
[Listing [random-unit-vector]: <kbd>[vec3.h]</kbd> Random vector of unit length]
573-
</div>
548+
is _direction_ in that context? We could make it based on polar coordinates, so $p$ would be in
549+
terms of $(\theta, \phi)$. However you do it, remember that a PDF has to integrate to 1 and
550+
represent the relative probability of that direction being sampled. Recall that we have vec3
551+
functions to take uniform random samples in (`random_in_unit_sphere()`) or on
552+
(`random_unit_vector()`) a unit sphere.
574553

575554
<div class='together'>
576555
Now what is the PDF of these uniform points? As a density on the unit sphere, it is $1/\text{area}$

src/common/vec3.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -119,13 +119,6 @@ inline vec3 unit_vector(vec3 v) {
119119
return v / v.length();
120120
}
121121

122-
inline vec3 random_unit_vector() {
123-
auto a = random_double(0, 2*pi);
124-
auto z = random_double(-1, 1);
125-
auto r = sqrt(1 - z*z);
126-
return vec3(r*cos(a), r*sin(a), z);
127-
}
128-
129122
inline vec3 random_in_unit_disk() {
130123
while (true) {
131124
auto p = vec3(random_double(-1,1), random_double(-1,1), 0);
@@ -142,6 +135,10 @@ inline vec3 random_in_unit_sphere() {
142135
}
143136
}
144137

138+
inline vec3 random_unit_vector() {
139+
return unit_vector(random_in_unit_sphere());
140+
}
141+
145142
inline vec3 random_in_hemisphere(const vec3& normal) {
146143
vec3 in_unit_sphere = random_in_unit_sphere();
147144
if (dot(in_unit_sphere, normal) > 0.0) // In the same hemisphere as the normal

0 commit comments

Comments
 (0)