Skip to content

Commit a82bb45

Browse files
committed
Add background color to restOfYourLife
In addition, I've renamed the `light_shape` parameter to `lights`.
1 parent 4e7d7af commit a82bb45

File tree

2 files changed

+58
-31
lines changed

2 files changed

+58
-31
lines changed

books/RayTracingTheRestOfYourLife.html

Lines changed: 43 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -848,7 +848,7 @@
848848
And the color function gets a minor modification:
849849

850850
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
851-
vec3 ray_color(const ray& r, hittable& world, int depth) {
851+
vec3 ray_color(const ray& r, const vec3& background, hittable& world, int depth) {
852852
hit_record rec;
853853

854854
// If we've exceeded the ray bounce limit, no more light is gathered.
@@ -857,7 +857,7 @@
857857

858858
// If the ray hits nothing, return the background color.
859859
if (!world.hit(r, 0.001, infinity, rec))
860-
return vec3(0,0,0);
860+
return background;
861861

862862
ray scattered;
863863
vec3 attenuation;
@@ -872,7 +872,7 @@
872872

873873
return emitted
874874
+ albedo * rec.mat_ptr->scattering_pdf(r, rec, scattered)
875-
* ray_color(scattered, world, depth-1) / pdf;
875+
* ray_color(scattered, background, world, depth-1) / pdf;
876876
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
877877
}
878878
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1306,7 +1306,7 @@
13061306
that math and get the concept, we can add it (see the highlighted region):
13071307

13081308
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
1309-
vec3 ray_color(const ray& r, hittable& world, int depth) {
1309+
vec3 ray_color(const ray& r, const vec3& background, hittable& world, int depth) {
13101310
hit_record rec;
13111311

13121312
// If we've exceeded the ray bounce limit, no more light is gathered.
@@ -1315,7 +1315,7 @@
13151315

13161316
// If the ray hits nothing, return the background color.
13171317
if (!world.hit(r, 0.001, infinity, rec))
1318-
return vec3(0,0,0);
1318+
return background;
13191319

13201320
ray scattered;
13211321
vec3 attenuation;
@@ -1345,7 +1345,7 @@
13451345

13461346
return emitted
13471347
+ albedo * rec.mat_ptr->scattering_pdf(r, rec, scattered)
1348-
* ray_color(scattered, world, depth-1) / pdf;
1348+
* ray_color(scattered, background, world, depth-1) / pdf;
13491349
}
13501350
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
13511351
[Listing [ray-color-lights]: <kbd>[main.cc]</kbd> Ray color with light sampling]
@@ -1477,7 +1477,7 @@
14771477
change variable `pdf` to some other variable name to avoid a name conflict with the new `pdf` class.
14781478

14791479
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
1480-
vec3 ray_color(const ray& r, hittable& world, int depth) {
1480+
vec3 ray_color(const ray& r, const vec3& background, hittable& world, int depth) {
14811481
hit_record rec;
14821482

14831483
// If we've exceeded the ray bounce limit, no more light is gathered.
@@ -1486,7 +1486,7 @@
14861486

14871487
// If the ray hits nothing, return the background color.
14881488
if (!world.hit(r, 0.001, infinity, rec))
1489-
return vec3(0,0,0);
1489+
return background;
14901490

14911491
ray scattered;
14921492
vec3 attenuation;
@@ -1504,7 +1504,7 @@
15041504

15051505
return emitted
15061506
+ albedo * rec.mat_ptr->scattering_pdf(r, rec, scattered)
1507-
* ray_color(scattered, world, depth-1)
1507+
* ray_color(scattered, background, world, depth-1)
15081508
/ pdf_val;
15091509
}
15101510
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1612,7 +1612,7 @@
16121612
And then change `ray_color()`:
16131613

16141614
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
1615-
vec3 ray_color(const ray& r, hittable& world, int depth) {
1615+
vec3 ray_color(const ray& r, const vec3& background, hittable& world, int depth) {
16161616
hit_record rec;
16171617

16181618
// If we've exceeded the ray bounce limit, no more light is gathered.
@@ -1621,7 +1621,7 @@
16211621

16221622
// If the ray hits nothing, return the background color.
16231623
if (!world.hit(r, 0.001, infinity, rec))
1624-
return vec3(0,0,0);
1624+
return background;
16251625

16261626
ray scattered;
16271627
vec3 attenuation;
@@ -1642,7 +1642,7 @@
16421642

16431643
return emitted
16441644
+ albedo * rec.mat_ptr->scattering_pdf(r, rec, scattered)
1645-
* ray_color(scattered, world, depth-1)
1645+
* ray_color(scattered, background, world, depth-1)
16461646
/ pdf_val;
16471647
}
16481648
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1690,7 +1690,13 @@
16901690
And plugging it into `ray_color()`:
16911691

16921692
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
1693-
vec3 ray_color(const ray& r, hittable& world, shared_ptr<hittable> light_shape, int depth) {
1693+
vec3 ray_color(
1694+
const ray& r,
1695+
const vec3& background,
1696+
hittable& world,
1697+
shared_ptr<hittable> lights,
1698+
int depth
1699+
) {
16941700
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
16951701
hit_record rec;
16961702

@@ -1700,7 +1706,7 @@
17001706

17011707
// If the ray hits nothing, return the background color.
17021708
if (!world.hit(r, 0.001, infinity, rec))
1703-
return vec3(0,0,0);
1709+
return background;
17041710

17051711
ray scattered;
17061712
vec3 attenuation;
@@ -1724,7 +1730,7 @@
17241730

17251731
return emitted
17261732
+ albedo * rec.mat_ptr->scattering_pdf(r, rec, scattered)
1727-
* ray_color(scattered, world, depth-1)
1733+
* ray_color(scattered, background, world, lights, depth-1)
17281734
/ pdf_val;
17291735
}
17301736
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1884,7 +1890,13 @@
18841890
And `ray_color()` changes are small:
18851891

18861892
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
1887-
vec3 ray_color(const ray& r, hittable& world, shared_ptr<hittable> light_shape, int depth) {
1893+
vec3 ray_color(
1894+
const ray& r,
1895+
const vec3& background,
1896+
hittable& world,
1897+
shared_ptr<hittable> lights,
1898+
int depth
1899+
) {
18881900
hit_record rec;
18891901

18901902
// If we've exceeded the ray bounce limit, no more light is gathered.
@@ -1893,23 +1905,23 @@
18931905

18941906
// If the ray hits nothing, return the background color.
18951907
if (!world.hit(r, 0.001, infinity, rec))
1896-
return vec3(0,0,0);
1908+
return background;
18971909

18981910
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
18991911
scatter_record srec;
19001912
vec3 emitted = rec.mat_ptr->emitted(r, rec, rec.u, rec.v, rec.p);
19011913
if (!rec.mat_ptr->scatter(r, rec, srec))
19021914
return emitted;
19031915

1904-
auto light_ptr = make_shared<hittable_pdf>(light_shape, rec.p);
1916+
auto light_ptr = make_shared<hittable_pdf>(lights, rec.p);
19051917
mixture_pdf p(light_ptr, srec.pdf_ptr);
19061918

19071919
ray scattered = ray(rec.p, p.generate(), r.time());
19081920
auto pdf_val = p.value(scattered.direction());
19091921

19101922
return emitted
19111923
+ srec.attenuation * rec.mat_ptr->scattering_pdf(r, rec, scattered)
1912-
* ray_color(scattered, world, light_shape, depth-1)
1924+
* ray_color(scattered, background, world, lights, depth-1)
19131925
/ pdf_val;
19141926
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
19151927
}
@@ -1954,7 +1966,13 @@
19541966
`ray_color()` just needs a new case to generate an implicitly sampled ray:
19551967

19561968
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
1957-
vec3 ray_color(const ray& r, hittable& world, shared_ptr<hittable> light_shape, int depth) {
1969+
vec3 ray_color(
1970+
const ray& r,
1971+
const vec3& background,
1972+
hittable& world,
1973+
shared_ptr<hittable> lights,
1974+
int depth
1975+
) {
19581976
hit_record rec;
19591977

19601978
// If we've exceeded the ray bounce limit, no more light is gathered.
@@ -1963,7 +1981,7 @@
19631981

19641982
// If the ray hits nothing, return the background color.
19651983
if (!world.hit(r, 0.001, infinity, rec))
1966-
return vec3(0,0,0);
1984+
return background;
19671985

19681986
scatter_record srec;
19691987
vec3 emitted = rec.mat_ptr->emitted(r, rec, rec.u, rec.v, rec.p);
@@ -1973,11 +1991,11 @@
19731991
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
19741992
if (srec.is_specular) {
19751993
return srec.attenuation
1976-
* ray_color(srec.specular_ray, world, light_shape, depth-1);
1994+
* ray_color(srec.specular_ray, background, world, lights, depth-1);
19771995
}
19781996
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
19791997

1980-
shared_ptr<pdf> light_ptr = make_shared<hittable_pdf>(light_shape, rec.p);
1998+
shared_ptr<pdf> light_ptr = make_shared<hittable_pdf>(lights, rec.p);
19811999
mixture_pdf p(light_ptr, srec.pdf_ptr);
19822000

19832001
ray scattered = ray(rec.p, p.generate(), r.time());
@@ -1986,7 +2004,7 @@
19862004

19872005
return emitted + srec.attenuation
19882006
* rec.mat_ptr->scattering_pdf(r, rec, scattered)
1989-
* ray_color(scattered, world, light_shape, depth-1)
2007+
* ray_color(scattered, background, world, lights, depth-1)
19902008
/ pdf_val;
19912009
}
19922010
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2174,7 +2192,7 @@
21742192
auto u = (i + random_double()) / image_width;
21752193
auto v = (j + random_double()) / image_height;
21762194
ray r = cam->get_ray(u, v);
2177-
col += ray_color(r, world, glass_sphere, max_depth);
2195+
col += ray_color(r, background, world, glass_sphere, max_depth);
21782196
}
21792197
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21802198
[Listing [sampling-sphere]: <kbd>[main.cc]</kbd> Sampling just the sphere]

src/TheRestOfYourLife/main.cc

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@
1919
#include <iostream>
2020

2121

22-
vec3 ray_color(const ray& r, hittable& world, shared_ptr<hittable> light_shape, int depth) {
22+
vec3 ray_color(
23+
const ray& r,
24+
const vec3& background,
25+
hittable& world,
26+
shared_ptr<hittable> lights,
27+
int depth
28+
) {
2329
hit_record rec;
2430

2531
// If we've exceeded the ray bounce limit, no more light is gathered.
@@ -28,7 +34,7 @@ vec3 ray_color(const ray& r, hittable& world, shared_ptr<hittable> light_shape,
2834

2935
// If the ray hits nothing, return the background color.
3036
if (!world.hit(r, 0.001, infinity, rec))
31-
return vec3(0,1,1);
37+
return background;
3238

3339
scatter_record srec;
3440
vec3 emitted = rec.mat_ptr->emitted(r, rec, rec.u, rec.v, rec.p);
@@ -37,17 +43,18 @@ vec3 ray_color(const ray& r, hittable& world, shared_ptr<hittable> light_shape,
3743
return emitted;
3844

3945
if (srec.is_specular) {
40-
return srec.attenuation * ray_color(srec.specular_ray, world, light_shape, depth-1);
46+
return srec.attenuation
47+
* ray_color(srec.specular_ray, background, world, lights, depth-1);
4148
}
4249

43-
auto light_ptr = make_shared<hittable_pdf>(light_shape, rec.p);
50+
auto light_ptr = make_shared<hittable_pdf>(lights, rec.p);
4451
mixture_pdf p(light_ptr, srec.pdf_ptr);
4552
ray scattered = ray(rec.p, p.generate(), r.time());
4653
auto pdf_val = p.value(scattered.direction());
4754

4855
return emitted
4956
+ srec.attenuation * rec.mat_ptr->scattering_pdf(r, rec, scattered)
50-
* ray_color(scattered, world, light_shape, depth-1)
57+
* ray_color(scattered, background, world, lights, depth-1)
5158
/ pdf_val;
5259
}
5360

@@ -99,6 +106,8 @@ int main() {
99106

100107
std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";
101108

109+
vec3 background(0,0,0);
110+
102111
camera cam;
103112
auto world = cornell_box(cam, aspect_ratio);
104113

@@ -114,7 +123,7 @@ int main() {
114123
auto u = (i + random_double()) / image_width;
115124
auto v = (j + random_double()) / image_height;
116125
ray r = cam.get_ray(u, v);
117-
color += ray_color(r, world, lights, max_depth);
126+
color += ray_color(r, background, world, lights, max_depth);
118127
}
119128
color.write_color(std::cout, samples_per_pixel);
120129
}

0 commit comments

Comments
 (0)