Skip to content

Commit e2304a0

Browse files
committed
Book 1 render updates: code changes
- Add more double-line spacers - Organize main() chunks: image params, then world definitions, then camera defs, then render - Change class order in material.h to match book definition order - Eliminate duplicated code in dielectric::scatter() - Delete vestigal vec3::write_color() method (now in color.h)
1 parent 44717c5 commit e2304a0

File tree

13 files changed

+200
-201
lines changed

13 files changed

+200
-201
lines changed

src/InOneWeekend/hittable.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
class material;
1818

19+
1920
struct hit_record {
2021
point3 p;
2122
vec3 normal;
@@ -35,4 +36,5 @@ class hittable {
3536
virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const = 0;
3637
};
3738

39+
3840
#endif

src/InOneWeekend/main.cc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,21 @@ hittable_list random_scene() {
8989

9090

9191
int main() {
92+
93+
// Image
94+
9295
const auto aspect_ratio = 16.0 / 9.0;
9396
const int image_width = 1200;
9497
const int image_height = static_cast<int>(image_width / aspect_ratio);
9598
const int samples_per_pixel = 10;
9699
const int max_depth = 50;
97100

98-
std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";
101+
// World
99102

100103
auto world = random_scene();
101104

105+
// Camera
106+
102107
point3 lookfrom(13,2,3);
103108
point3 lookat(0,0,0);
104109
vec3 vup(0,1,0);
@@ -107,10 +112,14 @@ int main() {
107112

108113
camera cam(lookfrom, lookat, vup, 20, aspect_ratio, aperture, dist_to_focus);
109114

115+
// Render
116+
117+
std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";
118+
110119
for (int j = image_height-1; j >= 0; --j) {
111120
std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush;
112121
for (int i = 0; i < image_width; ++i) {
113-
color pixel_color;
122+
color pixel_color(0,0,0);
114123
for (int s = 0; s < samples_per_pixel; ++s) {
115124
auto u = (i + random_double()) / (image_width-1);
116125
auto v = (j + random_double()) / (image_height-1);

src/InOneWeekend/material.h

Lines changed: 35 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -24,58 +24,21 @@ double schlick(double cosine, double ref_idx) {
2424
}
2525

2626

27-
class material {
27+
class material {
2828
public:
2929
virtual bool scatter(
3030
const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
3131
) const = 0;
3232
};
3333

3434

35-
class dielectric : public material {
36-
public:
37-
dielectric(double ri) : ref_idx(ri) {}
38-
39-
virtual bool scatter(
40-
const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
41-
) const {
42-
attenuation = color(1.0, 1.0, 1.0);
43-
double etai_over_etat = (rec.front_face) ? (1.0 / ref_idx) : (ref_idx);
44-
45-
vec3 unit_direction = unit_vector(r_in.direction());
46-
double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0);
47-
double sin_theta = sqrt(1.0 - cos_theta*cos_theta);
48-
if (etai_over_etat * sin_theta > 1.0 ) {
49-
vec3 reflected = reflect(unit_direction, rec.normal);
50-
scattered = ray(rec.p, reflected);
51-
return true;
52-
}
53-
54-
double reflect_prob = schlick(cos_theta, etai_over_etat);
55-
if (random_double() < reflect_prob)
56-
{
57-
vec3 reflected = reflect(unit_direction, rec.normal);
58-
scattered = ray(rec.p, reflected);
59-
return true;
60-
}
61-
62-
vec3 refracted = refract(unit_direction, rec.normal, etai_over_etat);
63-
scattered = ray(rec.p, refracted);
64-
return true;
65-
}
66-
67-
public:
68-
double ref_idx;
69-
};
70-
71-
7235
class lambertian : public material {
7336
public:
7437
lambertian(const color& a) : albedo(a) {}
7538

7639
virtual bool scatter(
7740
const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
78-
) const {
41+
) const {
7942
vec3 scatter_direction = rec.normal + random_unit_vector();
8043
scattered = ray(rec.p, scatter_direction);
8144
attenuation = albedo;
@@ -93,7 +56,7 @@ class metal : public material {
9356

9457
virtual bool scatter(
9558
const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
96-
) const {
59+
) const {
9760
vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal);
9861
scattered = ray(rec.p, reflected + fuzz*random_in_unit_sphere());
9962
attenuation = albedo;
@@ -106,4 +69,36 @@ class metal : public material {
10669
};
10770

10871

72+
class dielectric : public material {
73+
public:
74+
dielectric(double ri) : ref_idx(ri) {}
75+
76+
virtual bool scatter(
77+
const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
78+
) const {
79+
attenuation = color(1.0, 1.0, 1.0);
80+
double etai_over_etat = rec.front_face ? (1.0 / ref_idx) : ref_idx;
81+
82+
vec3 unit_direction = unit_vector(r_in.direction());
83+
double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0);
84+
double sin_theta = sqrt(1.0 - cos_theta*cos_theta);
85+
86+
if ( (etai_over_etat * sin_theta > 1.0)
87+
|| (random_double() < schlick(cos_theta, etai_over_etat))
88+
) {
89+
vec3 reflected = reflect(unit_direction, rec.normal);
90+
scattered = ray(rec.p, reflected);
91+
return true;
92+
}
93+
94+
vec3 refracted = refract(unit_direction, rec.normal, etai_over_etat);
95+
scattered = ray(rec.p, refracted);
96+
return true;
97+
}
98+
99+
public:
100+
double ref_idx;
101+
};
102+
103+
109104
#endif

src/InOneWeekend/sphere.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#include "hittable.h"
1717

1818

19-
class sphere: public hittable {
19+
class sphere : public hittable {
2020
public:
2121
sphere() {}
2222

@@ -42,7 +42,7 @@ bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) cons
4242
if (discriminant > 0) {
4343
auto root = sqrt(discriminant);
4444

45-
auto temp = (-half_b - root)/a;
45+
auto temp = (-half_b - root) / a;
4646
if (temp < t_max && temp > t_min) {
4747
rec.t = temp;
4848
rec.p = r.at(rec.t);
@@ -62,7 +62,9 @@ bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) cons
6262
return true;
6363
}
6464
}
65+
6566
return false;
6667
}
6768

69+
6870
#endif

src/TheNextWeek/main.cc

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -328,21 +328,22 @@ hittable_list final_scene() {
328328

329329

330330
int main() {
331+
332+
// Image
333+
331334
const auto aspect_ratio = 1.0 / 1.0;
332335
const int image_width = 600;
333336
const int image_height = static_cast<int>(image_width / aspect_ratio);
334-
335-
hittable_list world;
336-
337337
int samples_per_pixel = 100;
338338
int max_depth = 50;
339339

340+
// World
341+
342+
hittable_list world;
343+
340344
point3 lookfrom;
341345
point3 lookat;
342-
vec3 vup(0,1,0);
343346
auto vfov = 40.0;
344-
auto aperture = 0.0;
345-
auto dist_to_focus = 10.0;
346347
color background(0,0,0);
347348

348349
switch (0) {
@@ -422,14 +423,22 @@ int main() {
422423
break;
423424
}
424425

425-
std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";
426+
// Camera
427+
428+
vec3 vup(0,1,0);
429+
auto aperture = 0.0;
430+
auto dist_to_focus = 10.0;
426431

427432
camera cam(lookfrom, lookat, vup, vfov, aspect_ratio, aperture, dist_to_focus, 0.0, 1.0);
428433

434+
// Render
435+
436+
std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";
437+
429438
for (int j = image_height-1; j >= 0; --j) {
430439
std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush;
431440
for (int i = 0; i < image_width; ++i) {
432-
color pixel_color;
441+
color pixel_color(0,0,0);
433442
for (int s = 0; s < samples_per_pixel; ++s) {
434443
auto u = (i + random_double()) / (image_width-1);
435444
auto v = (j + random_double()) / (image_height-1);

src/TheNextWeek/material.h

Lines changed: 43 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919

2020
double schlick(double cosine, double ref_idx) {
21-
double r0 = (1-ref_idx) / (1+ref_idx);
21+
auto r0 = (1-ref_idx) / (1+ref_idx);
2222
r0 = r0*r0;
2323
return r0 + (1-r0)*pow((1 - cosine),5);
2424
}
@@ -36,6 +36,44 @@ class material {
3636
};
3737

3838

39+
class lambertian : public material {
40+
public:
41+
lambertian(const color& a) : albedo(make_shared<solid_color>(a)) {}
42+
lambertian(shared_ptr<texture> a) : albedo(a) {}
43+
44+
virtual bool scatter(
45+
const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
46+
) const {
47+
vec3 scatter_direction = rec.normal + random_unit_vector();
48+
scattered = ray(rec.p, scatter_direction, r_in.time());
49+
attenuation = albedo->value(rec.u, rec.v, rec.p);
50+
return true;
51+
}
52+
53+
public:
54+
shared_ptr<texture> albedo;
55+
};
56+
57+
58+
class metal : public material {
59+
public:
60+
metal(const color& a, double f) : albedo(a), fuzz(f < 1 ? f : 1) {}
61+
62+
virtual bool scatter(
63+
const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
64+
) const {
65+
vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal);
66+
scattered = ray(rec.p, reflected + fuzz*random_in_unit_sphere(), r_in.time());
67+
attenuation = albedo;
68+
return (dot(scattered.direction(), rec.normal) > 0);
69+
}
70+
71+
public:
72+
color albedo;
73+
double fuzz;
74+
};
75+
76+
3977
class dielectric : public material {
4078
public:
4179
dielectric(double ri) : ref_idx(ri) {}
@@ -44,20 +82,15 @@ class dielectric : public material {
4482
const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
4583
) const {
4684
attenuation = color(1.0, 1.0, 1.0);
47-
double etai_over_etat = (rec.front_face) ? (1.0 / ref_idx) : (ref_idx);
85+
double etai_over_etat = (rec.front_face) ? (1.0 / ref_idx) : ref_idx;
4886

4987
vec3 unit_direction = unit_vector(r_in.direction());
5088
double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0);
5189
double sin_theta = sqrt(1.0 - cos_theta*cos_theta);
52-
if (etai_over_etat * sin_theta > 1.0 ) {
53-
vec3 reflected = reflect(unit_direction, rec.normal);
54-
scattered = ray(rec.p, reflected, r_in.time());
55-
return true;
56-
}
5790

58-
double reflect_prob = schlick(cos_theta, etai_over_etat);
59-
if (random_double() < reflect_prob)
60-
{
91+
if ( (etai_over_etat * sin_theta > 1.0)
92+
|| (random_double() < schlick(cos_theta, etai_over_etat))
93+
) {
6194
vec3 reflected = reflect(unit_direction, rec.normal);
6295
scattered = ray(rec.p, reflected, r_in.time());
6396
return true;
@@ -110,42 +143,4 @@ class isotropic : public material {
110143
};
111144

112145

113-
class lambertian : public material {
114-
public:
115-
lambertian(const color& a) : albedo(make_shared<solid_color>(a)) {}
116-
lambertian(shared_ptr<texture> a) : albedo(a) {}
117-
118-
virtual bool scatter(
119-
const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
120-
) const {
121-
vec3 scatter_direction = rec.normal + random_unit_vector();
122-
scattered = ray(rec.p, scatter_direction, r_in.time());
123-
attenuation = albedo->value(rec.u, rec.v, rec.p);
124-
return true;
125-
}
126-
127-
public:
128-
shared_ptr<texture> albedo;
129-
};
130-
131-
132-
class metal : public material {
133-
public:
134-
metal(const color& a, double f) : albedo(a), fuzz(f < 1 ? f : 1) {}
135-
136-
virtual bool scatter(
137-
const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
138-
) const {
139-
vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal);
140-
scattered = ray(rec.p, reflected + fuzz*random_in_unit_sphere(), r_in.time());
141-
attenuation = albedo;
142-
return (dot(scattered.direction(), rec.normal) > 0);
143-
}
144-
145-
public:
146-
color albedo;
147-
double fuzz;
148-
};
149-
150-
151146
#endif

src/TheNextWeek/sphere.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) cons
4949
if (discriminant > 0) {
5050
auto root = sqrt(discriminant);
5151

52-
auto temp = (-half_b - root)/a;
52+
auto temp = (-half_b - root) / a;
5353
if (temp < t_max && temp > t_min) {
5454
rec.t = temp;
5555
rec.p = r.at(rec.t);
@@ -60,7 +60,7 @@ bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) cons
6060
return true;
6161
}
6262

63-
temp = (-half_b + root)/a;
63+
temp = (-half_b + root) / a;
6464
if (temp < t_max && temp > t_min) {
6565
rec.t = temp;
6666
rec.p = r.at(rec.t);
@@ -75,4 +75,5 @@ bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) cons
7575
return false;
7676
}
7777

78+
7879
#endif

0 commit comments

Comments
 (0)