Skip to content

Commit dffe4d2

Browse files
committed
Merge development changes (hitvect.2) onto normals_and_dielectrics
2 parents e8c65a9 + 8410152 commit dffe4d2

File tree

14 files changed

+1017
-863
lines changed

14 files changed

+1017
-863
lines changed

books/RayTracingInOneWeekend.html

Lines changed: 77 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -618,8 +618,7 @@
618618
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
619619
if (discriminant < 0) {
620620
return -1.0;
621-
}
622-
else {
621+
} else {
623622
return (-b - sqrt(discriminant) ) / (2.0*a);
624623
}
625624
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
@@ -684,8 +683,7 @@
684683

685684
if (discriminant < 0) {
686685
return -1.0;
687-
}
688-
else {
686+
} else {
689687
return (-half_b - sqrt(discriminant) ) / a;
690688
}
691689
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -938,27 +936,35 @@
938936
#define HITTABLE_LIST_H
939937

940938
#include "hittable.h"
939+
#include <vector>
941940

942941
class hittable_list: public hittable {
943942
public:
944943
hittable_list() {}
945-
hittable_list(hittable **l, int n) {list = l; list_size = n; }
944+
hittable_list(hittable* object) { add(object); }
945+
946+
void clear() { objects.clear(); }
947+
void add(hittable* object) { objects.push_back(object); }
948+
946949
virtual bool hit(const ray& r, double tmin, double tmax, hit_record& rec) const;
947-
hittable **list;
948-
int list_size;
950+
951+
public:
952+
std::vector<hittable*> objects;
949953
};
950954

951955
bool hittable_list::hit(const ray& r, double t_min, double t_max, hit_record& rec) const {
952956
hit_record temp_rec;
953957
bool hit_anything = false;
954-
double closest_so_far = t_max;
955-
for (int i = 0; i < list_size; i++) {
956-
if (list[i]->hit(r, t_min, closest_so_far, temp_rec)) {
958+
auto closest_so_far = t_max;
959+
960+
for (auto object : objects) {
961+
if (object->hit(r, t_min, closest_so_far, temp_rec)) {
957962
hit_anything = true;
958963
closest_so_far = temp_rec.t;
959964
rec = temp_rec;
960965
}
961966
}
967+
962968
return hit_anything;
963969
}
964970

@@ -967,6 +973,11 @@
967973
[Listing [hittable-list-initial]: <kbd>[hittable_list.h]</kbd> The hittable_list class]
968974
</div>
969975

976+
If you're unfamiliar with C++'s `std::vector`, this is a generic array-like collection of an
977+
arbitrary type. Above, we use a collection of pointers to `hittable`. `std::vector` automatically
978+
grows as more values are added: `objects.push_back(object)` adds a value to the end of the
979+
`std::vector` member variable `objects`.
980+
970981
<div class='together'></div>
971982
We need some math constants that we conveniently define in their own header file. For now we only
972983
need infinity, but we will also throw our own definition of pi in there, which we will need later.
@@ -1022,10 +1033,10 @@
10221033
#include <iostream>
10231034

10241035
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
1025-
vec3 ray_color(const ray& r, hittable *world) {
1036+
vec3 ray_color(const ray& r, hittable& world) {
10261037
hit_record rec;
1027-
if (world->hit(r, 0.0, infinity, rec)) {
1028-
return 0.5*vec3(rec.normal.x()+1, rec.normal.y()+1, rec.normal.z()+1);
1038+
if (world.hit(r, 0.0, infinity, rec)) {
1039+
return 0.5 * (rec.normal + vec3(1,1,1));
10291040
}
10301041

10311042
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
@@ -1039,18 +1050,19 @@
10391050
int main() {
10401051
int nx = 200;
10411052
int ny = 100;
1053+
10421054
std::cout << "P3\n" << nx << ' ' << ny << "\n255\n";
1055+
10431056
vec3 lower_left_corner(-2.0, -1.0, -1.0);
10441057
vec3 horizontal(4.0, 0.0, 0.0);
10451058
vec3 vertical(0.0, 2.0, 0.0);
10461059
vec3 origin(0.0, 0.0, 0.0);
10471060

10481061

10491062
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
1050-
hittable *list[2];
1051-
list[0] = new sphere(vec3(0,0,-1), 0.5);
1052-
list[1] = new sphere(vec3(0,-100.5,-1), 100);
1053-
hittable *world = new hittable_list(list,2);
1063+
hittable_list world;
1064+
world.add(new sphere(vec3(0,0,-1), 0.5));
1065+
world.add(new sphere(vec3(0,-100.5,-1), 100));
10541066
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
10551067

10561068
for (int j = ny-1; j >= 0; --j) {
@@ -1223,12 +1235,12 @@
12231235
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
12241236
int num_samples = 100;
12251237
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
1238+
12261239
std::cout << "P3\n" << nx << " " << ny << "\n255\n";
12271240

1228-
hittable *list[2];
1229-
list[0] = new sphere(vec3(0,0,-1), 0.5);
1230-
list[1] = new sphere(vec3(0,-100.5,-1), 100);
1231-
hittable *world = new hittable_list(list,2);
1241+
hittable_list world;
1242+
world.add(new sphere(vec3(0,0,-1), 0.5));
1243+
world.add(new sphere(vec3(0,-100.5,-1), 100));
12321244

12331245
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
12341246
camera cam;
@@ -1342,9 +1354,9 @@
13421354
Then update the `ray_color()` function to use the new random direction generator:
13431355

13441356
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
1345-
vec3 ray_color(const ray& r, hittable *world) {
1357+
vec3 ray_color(const ray& r, hittable& world) {
13461358
hit_record rec;
1347-
if (world->hit(r, 0.0, infinity, rec)) {
1359+
if (world.hit(r, 0.0, infinity, rec)) {
13481360
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
13491361
vec3 target = rec.p + rec.normal + random_in_unit_sphere();
13501362
return 0.5 * ray_color(ray(rec.p, target - rec.p), world);
@@ -1366,9 +1378,10 @@
13661378
depth, returning no light contribution at the maximum depth:
13671379

13681380
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
1369-
vec3 ray_color(const ray& r, hittable *world, int depth) {
1381+
vec3 ray_color(const ray& r, hittable& world, int depth) {
13701382
hit_record rec;
1371-
if (world->hit(r, 0.0, infinity, rec)) {
1383+
if (world.hit(r, 0.0, infinity, rec)) {
1384+
// If we've exceeded the ray bounce limit, no more light is gathered.
13721385
if (depth <= 0)
13731386
return vec3(0,0,0);
13741387
vec3 target = rec.p + rec.normal + random_in_unit_sphere();
@@ -1388,6 +1401,7 @@
13881401
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
13891402
int max_depth = 50;
13901403
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
1404+
13911405
...
13921406
for (int j = ny-1; j >= 0; --j) {
13931407
std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush;
@@ -1462,7 +1476,7 @@
14621476
point approximation the sphere intersector gives us. So we need to ignore hits very near zero:
14631477

14641478
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
1465-
if (world->hit(r, 0.001, infinity, rec)) {
1479+
if (world.hit(r, 0.001, infinity, rec)) {
14661480
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
14671481
[Listing [reflect-tolerance]: <kbd>[main.cc]</kbd> Calculating reflected ray origins with tolerance]
14681482

@@ -1503,9 +1517,10 @@
15031517
function.
15041518

15051519
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
1506-
vec3 ray_color(const ray& r, hittable *world, int depth) {
1520+
vec3 ray_color(const ray& r, hittable& world, int depth) {
15071521
hit_record rec;
1508-
if (world->hit(r, 0.0, infinity, rec)) {
1522+
if (world.hit(r, 0.0, infinity, rec)) {
1523+
// If we've exceeded the ray bounce limit, no more light is gathered.
15091524
if (depth <= 0)
15101525
return vec3(0,0,0);
15111526
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
@@ -1578,9 +1593,10 @@
15781593
Plugging the new formula into the `ray_color()` function:
15791594

15801595
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
1581-
vec3 ray_color(const ray& r, hittable *world, int depth) {
1596+
vec3 ray_color(const ray& r, hittable& world, int depth) {
15821597
hit_record rec;
1583-
if (world->hit(r, 0.0, infinity, rec)) {
1598+
if (world.hit(r, 0.0, infinity, rec)) {
1599+
// If we've exceeded the ray bounce limit, no more light is gathered.
15841600
if (depth <= 0)
15851601
return vec3(0,0,0);
15861602
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
@@ -1826,12 +1842,13 @@
18261842
We need to modify the color function to use this:
18271843

18281844
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
1829-
vec3 ray_color(const ray& r, hittable *world, int depth) {
1845+
vec3 ray_color(const ray& r, hittable& world, int depth) {
18301846
hit_record rec;
1831-
if (world->hit(r, 0.001, infinity, rec)) {
1847+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
1848+
if (world.hit(r, 0.001, infinity, rec)) {
1849+
// If we've exceeded the ray bounce limit, no more light is gathered.
18321850
if (depth <= 0)
18331851
return vec3(0,0,0);
1834-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
18351852
ray scattered;
18361853
vec3 attenuation;
18371854
if (rec.mat_ptr->scatter(r, rec, attenuation, scattered))
@@ -1862,12 +1879,11 @@
18621879

18631880

18641881
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
1865-
hittable *list[4];
1866-
list[0] = new sphere(vec3(0,0,-1), 0.5, new lambertian(vec3(0.7, 0.3, 0.3)));
1867-
list[1] = new sphere(vec3(0,-100.5,-1), 100, new lambertian(vec3(0.8, 0.8, 0.0)));
1868-
list[2] = new sphere(vec3(1,0,-1), 0.5, new metal(vec3(0.8, 0.6, 0.2)));
1869-
list[3] = new sphere(vec3(-1,0,-1), 0.5, new metal(vec3(0.8, 0.8, 0.8)));
1870-
hittable *world = new hittable_list(list,4);
1882+
hittable_list world;
1883+
world.add(new sphere(vec3(0,0,-1), 0.5, new lambertian(vec3(0.7, 0.3, 0.3))));
1884+
world.add(new sphere(vec3(0,-100.5,-1), 100, new lambertian(vec3(0.8, 0.8, 0.0))));
1885+
world.add(new sphere(vec3(1,0,-1), 0.5, new metal(vec3(0.8, 0.6, 0.2))));
1886+
world.add(new sphere(vec3(-1,0,-1), 0.5, new metal(vec3(0.8, 0.8, 0.8))));
18711887
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
18721888

18731889
camera cam;
@@ -2321,9 +2337,9 @@
23212337

23222338
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
23232339
auto R = cos(pi/4);
2324-
list[0] = new sphere(vec3(-R,0,-1), R, new lambertian(vec3(0, 0, 1)));
2325-
list[1] = new sphere(vec3( R,0,-1), R, new lambertian(vec3(1, 0, 0)));
2326-
hittable *world = new hittable_list(list,2);
2340+
hittable_list world;
2341+
world.add(new sphere(vec3(-R,0,-1), R, new lambertian(vec3(0, 0, 1))));
2342+
world.add(new sphere(vec3( R,0,-1), R, new lambertian(vec3(1, 0, 0))));
23272343
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23282344
[Listing [scene-wide-angle]: <kbd>[main.cc]</kbd> Scene with wide-angle camera]
23292345

@@ -2560,38 +2576,45 @@
25602576
First let’s make the image on the cover of this book -- lots of random spheres:
25612577

25622578
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
2563-
hittable *random_scene() {
2564-
int n = 500;
2565-
hittable **list = new hittable*[n+1];
2566-
list[0] = new sphere(vec3(0,-1000,0), 1000, new lambertian(vec3(0.5, 0.5, 0.5)));
2579+
hittable_list random_scene() {
2580+
hittable_list objects;
2581+
2582+
objects.add(new sphere(vec3(0,-1000,0), 1000, new lambertian(vec3(0.5, 0.5, 0.5))));
2583+
25672584
int i = 1;
25682585
for (int a = -11; a < 11; a++) {
25692586
for (int b = -11; b < 11; b++) {
25702587
auto choose_mat = random_double();
25712588
vec3 center(a + 0.9*random_double(), 0.2, b + 0.9*random_double());
2572-
if ((center-vec3(4,0.2,0)).length() > 0.9) {
2589+
if ((center - vec3(4, 0.2, 0)).length() > 0.9) {
25732590
if (choose_mat < 0.8) {
25742591
// diffuse
25752592
auto albedo = vec3::random() * vec3::random();
2576-
list[i++] = new sphere(center, 0.2, new lambertian(albedo));
2593+
objects.add(new sphere(center, 0.2, new lambertian(albedo)));
25772594
} else if (choose_mat < 0.95) {
25782595
// metal
25792596
auto albedo = vec3::random(.5, 1);
25802597
auto fuzz = random_double(0, .5);
2581-
list[i++] = new sphere(center, 0.2, new metal(albedo, fuzz));
2598+
objects.add(new sphere(center, 0.2, new metal(albedo, fuzz)));
25822599
} else {
25832600
// glass
2584-
list[i++] = new sphere(center, 0.2, new dielectric(1.5));
2601+
objects.add(new sphere(center, 0.2, new dielectric(1.5)));
25852602
}
25862603
}
25872604
}
25882605
}
25892606

2590-
list[i++] = new sphere(vec3(0, 1, 0), 1.0, new dielectric(1.5));
2591-
list[i++] = new sphere(vec3(-4, 1, 0), 1.0, new lambertian(vec3(0.4, 0.2, 0.1)));
2592-
list[i++] = new sphere(vec3(4, 1, 0), 1.0, new metal(vec3(0.7, 0.6, 0.5), 0.0));
2607+
objects.add(new sphere(vec3(0, 1, 0), 1.0, new dielectric(1.5)));
2608+
objects.add(new sphere(vec3(-4, 1, 0), 1.0, new lambertian(vec3(0.4, 0.2, 0.1))));
2609+
objects.add(new sphere(vec3(4, 1, 0), 1.0, new metal(vec3(0.7, 0.6, 0.5), 0.0)));
25932610

2594-
return new hittable_list(list,i);
2611+
return objects;
2612+
}
2613+
2614+
int main() {
2615+
...
2616+
auto world = random_scene();
2617+
...
25952618
}
25962619
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25972620
[Listing [scene-final]: <kbd>[main.cc]</kbd> Final scene]

0 commit comments

Comments
 (0)