Skip to content

Commit 416f7b6

Browse files
committed
Make linear_to_gamma robust for negative inputs
Without this hardening, we will return NaNs for negative inputs, which can happen from time to time. I also ran across fmin/fmax in one implementation, which we never commented on in the books. Added an explanation for these two functions for readers unfamiliar with C++. Resolves #1202
1 parent dce6110 commit 416f7b6

File tree

4 files changed

+21
-5
lines changed

4 files changed

+21
-5
lines changed

books/RayTracingInOneWeekend.html

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2598,12 +2598,16 @@
25982598
viewer can more accurately display our image. As a simple approximation, we can use “gamma 2” as our
25992599
transform, which is the power that you use when going from gamma space to linear space. We need to
26002600
go from linear space to gamma space, which means taking the inverse of "gamma 2", which means an
2601-
exponent of $1/\mathit{gamma}$, which is just the square-root.
2601+
exponent of $1/\mathit{gamma}$, which is just the square-root. We'll also want to ensure that we
2602+
robustly handle negative inputs.
26022603

26032604
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
26042605
inline double linear_to_gamma(double linear_component)
26052606
{
2606-
return sqrt(linear_component);
2607+
if (linear_component > 0)
2608+
return sqrt(linear_component);
2609+
2610+
return 0;
26072611
}
26082612
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
26092613

@@ -3173,6 +3177,9 @@
31733177

31743178
</div>
31753179

3180+
(Note here that we use the C++ standard function `fmin()`, which returns the minimum of the two
3181+
arguments. Similarly, we will later use `fmax()`, which returns the maximum of the two arguments.)
3182+
31763183
<div class='together'>
31773184
And the dielectric material that always refracts is:
31783185

src/InOneWeekend/color.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ using color = vec3;
1919

2020
inline double linear_to_gamma(double linear_component)
2121
{
22-
return sqrt(linear_component);
22+
if (linear_component > 0)
23+
return sqrt(linear_component);
24+
25+
return 0;
2326
}
2427

2528
void write_color(std::ostream &out, color pixel_color, int samples_per_pixel) {

src/TheNextWeek/color.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ using color = vec3;
1919

2020
inline double linear_to_gamma(double linear_component)
2121
{
22-
return sqrt(linear_component);
22+
if (linear_component > 0)
23+
return sqrt(linear_component);
24+
25+
return 0;
2326
}
2427

2528
void write_color(std::ostream &out, color pixel_color, int samples_per_pixel) {

src/TheRestOfYourLife/color.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ using color = vec3;
1919

2020
inline double linear_to_gamma(double linear_component)
2121
{
22-
return sqrt(linear_component);
22+
if (linear_component > 0)
23+
return sqrt(linear_component);
24+
25+
return 0;
2326
}
2427

2528
void write_color(std::ostream &out, color pixel_color, int samples_per_pixel) {

0 commit comments

Comments
 (0)