Skip to content

Commit 7808a46

Browse files
committed
Move image width & aspect ratio from scene to cam
This change does several things. Primarily, it's a refinement of the division between the scene class and the camera class. The scene class holds the world description (which includes all scene geometry and lighting) and the camera. It is responsible for using the camera to interrogate the world, using the main render loop (all samples for all pixels). The camera class is responsible for all 2D rendered image parameters, and uses these to generate rays one at a time. The net effect of these changes are: 1. The image_width and aspect_ratio member variables move from the scene class to the camera class. 2. camera::initialize() no longer needs to take the aspect ratio argument. 3. camera::get_image_height() is a new public function that returns the image height, computed from the image width and the desired aspect ratio. 4. `camera::aperture` is now `camera::defocus_diameter`. `camera::lens_radius` is now `camera::defocus_radius`. 5. The scene and camera parameter assignments have been reordered to logical groupings based on the updated mental model. 6. In TheNextWeek/main.cc, we assigned background color, camera up, and focus distance before handing the scene off to the scene generators. There's been at least one case where a reader was confused about the state of the scene object because values were set in two different locations. This saved repeating some lines of code, but the simplicity of assigning everything in one place for each scene is better. These two changes solidify the responsibilities of the two classes in preparation for future changes to the camera class, addressing the following issues: - #546 Confusion surrounding use of the word "aperture" - #682 Camera UV coordinates - handle images with width or height of one - #858 Improve camera.h naming, commentary - #1042 camera::get_ray() function should perform all sample jittering - #1076 Book 1 Chapter 13.2 dev-major: Generating Sample Rays One question left is that now that everything's assigned in the scene generator functions, why not just have them allocate and return the generated scene? I've decided to leave the current approach of mutating the scene -- passed by reference -- purely because it's simpler code. In my opinion, there's not a whole lot of advantage to the returned value approach.
1 parent 9bc0066 commit 7808a46

File tree

7 files changed

+161
-110
lines changed

7 files changed

+161
-110
lines changed

src/InOneWeekend/main.cc

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,19 @@
2020

2121

2222
void random_spheres(scene& scene_desc) {
23-
scene_desc.image_width = 1200;
24-
scene_desc.aspect_ratio = 16.0 / 9.0;
25-
scene_desc.samples_per_pixel = 10;
23+
scene_desc.cam.lookfrom = vec3(13,2,3);
24+
scene_desc.cam.lookat = vec3(0,0,0);
25+
scene_desc.cam.vup = vec3(0,1,0);
26+
scene_desc.cam.vfov = 20;
27+
28+
scene_desc.cam.aspect_ratio = 16.0 / 9.0;
29+
scene_desc.cam.image_width = 1200;
2630

27-
scene_desc.cam.vfov = 20;
28-
scene_desc.cam.focus_dist = 10.0;
29-
scene_desc.cam.aperture = 0.1;
30-
scene_desc.cam.lookfrom = vec3(13,2,3);
31-
scene_desc.cam.lookat = vec3(0,0,0);
32-
scene_desc.cam.vup = vec3(0,1,0);
31+
scene_desc.cam.defocus_diameter = 0.1;
32+
scene_desc.cam.focus_dist = 10;
33+
34+
scene_desc.samples_per_pixel = 10;
35+
scene_desc.max_depth = 20;
3336

3437
hittable_list& world = scene_desc.world;
3538

src/InOneWeekend/scene.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
class scene {
2121
public:
2222
void render() {
23-
const int image_height = static_cast<int>(image_width / aspect_ratio);
23+
cam.initialize();
2424

25-
cam.initialize(aspect_ratio);
25+
auto image_width = cam.image_width;
26+
auto image_height = cam.get_image_height();
2627

2728
std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";
2829

@@ -47,8 +48,7 @@ class scene {
4748
hittable_list world;
4849
camera cam;
4950

50-
double aspect_ratio = 1.0;
51-
int image_width = 100;
51+
// Scene sampling parameters
5252
int samples_per_pixel = 10;
5353
int max_depth = 20;
5454

src/TheNextWeek/main.cc

Lines changed: 102 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,20 @@
2525

2626

2727
void random_spheres(scene& scene_desc) {
28-
scene_desc.aspect_ratio = 16.0 / 9.0;
29-
scene_desc.image_width = 400;
30-
scene_desc.samples_per_pixel = 100;
28+
scene_desc.cam.lookfrom = point3(13,2,3);
29+
scene_desc.cam.lookat = point3(0,0,0);
30+
scene_desc.cam.vup = vec3(0,1,0);
31+
scene_desc.cam.vfov = 20.0;
32+
33+
scene_desc.cam.aspect_ratio = 16.0 / 9.0;
34+
scene_desc.cam.image_width = 400;
3135

32-
scene_desc.cam.lookfrom = point3(13,2,3);
33-
scene_desc.cam.lookat = point3(0,0,0);
34-
scene_desc.cam.vup = vec3(0,1,0);
35-
scene_desc.cam.vfov = 20.0;
36-
scene_desc.cam.aperture = 0.1;
37-
scene_desc.cam.focus_dist = 10.0;
36+
scene_desc.cam.defocus_diameter = 0.1;
37+
scene_desc.cam.focus_dist = 10;
38+
39+
scene_desc.samples_per_pixel = 100;
40+
scene_desc.max_depth = 20;
41+
scene_desc.background = color(0.70, 0.80, 1.00);
3842

3943
hittable_list& world = scene_desc.world;
4044

@@ -85,14 +89,19 @@ void random_spheres(scene& scene_desc) {
8589

8690

8791
void two_spheres(scene& scene_desc) {
88-
scene_desc.image_width = 400;
89-
scene_desc.aspect_ratio = 16.0 / 9.0;
90-
scene_desc.samples_per_pixel = 100;
91-
92-
scene_desc.cam.aperture = 0.0;
93-
scene_desc.cam.vfov = 20.0;
9492
scene_desc.cam.lookfrom = point3(13,2,3);
9593
scene_desc.cam.lookat = point3(0,0,0);
94+
scene_desc.cam.vup = vec3(0,1,0);
95+
scene_desc.cam.vfov = 20.0;
96+
97+
scene_desc.cam.aspect_ratio = 16.0 / 9.0;
98+
scene_desc.cam.image_width = 400;
99+
100+
scene_desc.cam.defocus_diameter = 0.0;
101+
102+
scene_desc.samples_per_pixel = 100;
103+
scene_desc.max_depth = 20;
104+
scene_desc.background = color(0.70, 0.80, 1.00);
96105

97106
hittable_list& world = scene_desc.world;
98107

@@ -104,14 +113,19 @@ void two_spheres(scene& scene_desc) {
104113

105114

106115
void two_perlin_spheres(scene& scene_desc) {
107-
scene_desc.image_width = 400;
108-
scene_desc.aspect_ratio = 16.0 / 9.0;
109-
scene_desc.samples_per_pixel = 100;
110-
111-
scene_desc.cam.aperture = 0.0;
112-
scene_desc.cam.vfov = 20.0;
113116
scene_desc.cam.lookfrom = point3(13,2,3);
114117
scene_desc.cam.lookat = point3(0,0,0);
118+
scene_desc.cam.vup = vec3(0,1,0);
119+
scene_desc.cam.vfov = 20.0;
120+
121+
scene_desc.cam.aspect_ratio = 16.0 / 9.0;
122+
scene_desc.cam.image_width = 400;
123+
124+
scene_desc.cam.defocus_diameter = 0.0;
125+
126+
scene_desc.samples_per_pixel = 100;
127+
scene_desc.max_depth = 20;
128+
scene_desc.background = color(0.70, 0.80, 1.00);
115129

116130
hittable_list& world = scene_desc.world;
117131

@@ -122,14 +136,19 @@ void two_perlin_spheres(scene& scene_desc) {
122136

123137

124138
void earth(scene& scene_desc) {
125-
scene_desc.image_width = 400;
126-
scene_desc.aspect_ratio = 16.0 / 9.0;
127-
scene_desc.samples_per_pixel = 100;
128-
129-
scene_desc.cam.aperture = 0.0;
130-
scene_desc.cam.vfov = 20.0;
131139
scene_desc.cam.lookfrom = point3(0,0,12);
132140
scene_desc.cam.lookat = point3(0,0,0);
141+
scene_desc.cam.vup = vec3(0,1,0);
142+
scene_desc.cam.vfov = 20.0;
143+
144+
scene_desc.cam.aspect_ratio = 16.0 / 9.0;
145+
scene_desc.cam.image_width = 400;
146+
147+
scene_desc.cam.defocus_diameter = 0.0;
148+
149+
scene_desc.samples_per_pixel = 100;
150+
scene_desc.max_depth = 20;
151+
scene_desc.background = color(0.70, 0.80, 1.00);
133152

134153
auto earth_texture = make_shared<image_texture>("earthmap.jpg");
135154
auto earth_surface = make_shared<lambertian>(earth_texture);
@@ -140,14 +159,19 @@ void earth(scene& scene_desc) {
140159

141160

142161
void quads(scene& scene_desc) {
143-
scene_desc.image_width = 400;
144-
scene_desc.aspect_ratio = 1.0;
145-
scene_desc.samples_per_pixel = 100;
146-
147-
scene_desc.cam.aperture = 0.0;
148-
scene_desc.cam.vfov = 80.0;
149162
scene_desc.cam.lookfrom = point3(0,0,9);
150163
scene_desc.cam.lookat = point3(0,0,0);
164+
scene_desc.cam.vup = vec3(0,1,0);
165+
scene_desc.cam.vfov = 80.0;
166+
167+
scene_desc.cam.aspect_ratio = 1.0;
168+
scene_desc.cam.image_width = 400;
169+
170+
scene_desc.cam.defocus_diameter = 0.0;
171+
172+
scene_desc.samples_per_pixel = 100;
173+
scene_desc.max_depth = 20;
174+
scene_desc.background = color(0.70, 0.80, 1.00);
151175

152176
hittable_list& world = scene_desc.world;
153177

@@ -168,15 +192,19 @@ void quads(scene& scene_desc) {
168192

169193

170194
void simple_light(scene& scene_desc) {
171-
scene_desc.image_width = 400;
172-
scene_desc.aspect_ratio = 16.0 / 9.0;
173-
scene_desc.samples_per_pixel = 100;
174-
scene_desc.background = color(0,0,0);
175-
176-
scene_desc.cam.aperture = 0.0;
177-
scene_desc.cam.vfov = 20.0;
178195
scene_desc.cam.lookfrom = point3(26,3,6);
179196
scene_desc.cam.lookat = point3(0,2,0);
197+
scene_desc.cam.vup = vec3(0,1,0);
198+
scene_desc.cam.vfov = 20.0;
199+
200+
scene_desc.cam.aspect_ratio = 16.0 / 9.0;
201+
scene_desc.cam.image_width = 400;
202+
203+
scene_desc.cam.defocus_diameter = 0.0;
204+
205+
scene_desc.samples_per_pixel = 100;
206+
scene_desc.max_depth = 20;
207+
scene_desc.background = color(0,0,0);
180208

181209
hittable_list& world = scene_desc.world;
182210

@@ -191,15 +219,19 @@ void simple_light(scene& scene_desc) {
191219

192220

193221
void cornell_box(scene& scene_desc) {
194-
scene_desc.image_width = 600;
195-
scene_desc.aspect_ratio = 1.0;
196-
scene_desc.samples_per_pixel = 200;
197-
scene_desc.background = color(0,0,0);
198-
199222
scene_desc.cam.lookfrom = point3(278, 278, -800);
200223
scene_desc.cam.lookat = point3(278, 278, 0);
224+
scene_desc.cam.vup = vec3(0,1,0);
201225
scene_desc.cam.vfov = 40.0;
202-
scene_desc.cam.aperture = 0.0;
226+
227+
scene_desc.cam.aspect_ratio = 1.0;
228+
scene_desc.cam.image_width = 600;
229+
230+
scene_desc.cam.defocus_diameter = 0.0;
231+
232+
scene_desc.samples_per_pixel = 200;
233+
scene_desc.max_depth = 20;
234+
scene_desc.background = color(0,0,0);
203235

204236
hittable_list& world = scene_desc.world;
205237

@@ -228,15 +260,19 @@ void cornell_box(scene& scene_desc) {
228260

229261

230262
void cornell_smoke(scene& scene_desc) {
231-
scene_desc.image_width = 600;
232-
scene_desc.aspect_ratio = 1.0;
233-
scene_desc.samples_per_pixel = 200;
234-
scene_desc.background = color(0,0,0);
235-
236-
scene_desc.cam.aperture = 0.0;
237-
scene_desc.cam.vfov = 40.0;
238263
scene_desc.cam.lookfrom = point3(278, 278, -800);
239264
scene_desc.cam.lookat = point3(278, 278, 0);
265+
scene_desc.cam.vup = vec3(0,1,0);
266+
scene_desc.cam.vfov = 40.0;
267+
268+
scene_desc.cam.aspect_ratio = 1.0;
269+
scene_desc.cam.image_width = 600;
270+
271+
scene_desc.cam.defocus_diameter = 0.0;
272+
273+
scene_desc.samples_per_pixel = 200;
274+
scene_desc.max_depth = 20;
275+
scene_desc.background = color(0,0,0);
240276

241277
hittable_list& world = scene_desc.world;
242278

@@ -266,15 +302,19 @@ void cornell_smoke(scene& scene_desc) {
266302

267303

268304
void final_scene(scene& scene_desc) {
269-
scene_desc.image_width = 800;
270-
scene_desc.aspect_ratio = 1.0;
271-
scene_desc.samples_per_pixel = 10000;
272-
scene_desc.background = color(0,0,0);
273-
274-
scene_desc.cam.aperture = 0.0;
275-
scene_desc.cam.vfov = 40.0;
276305
scene_desc.cam.lookfrom = point3(478, 278, -600);
277306
scene_desc.cam.lookat = point3(278, 278, 0);
307+
scene_desc.cam.vup = vec3(0,1,0);
308+
scene_desc.cam.vfov = 40.0;
309+
310+
scene_desc.cam.aspect_ratio = 1.0;
311+
scene_desc.cam.image_width = 800;
312+
313+
scene_desc.cam.defocus_diameter = 0.0;
314+
315+
scene_desc.samples_per_pixel = 10000;
316+
scene_desc.max_depth = 20;
317+
scene_desc.background = color(0,0,0);
278318

279319
hittable_list boxes1;
280320
auto ground = make_shared<lambertian>(color(0.48, 0.83, 0.53));
@@ -340,7 +380,8 @@ void final_scene(scene& scene_desc) {
340380

341381
void default_scene(scene& scene_desc) {
342382
final_scene(scene_desc);
343-
scene_desc.image_width = 400;
383+
384+
scene_desc.cam.image_width = 400;
344385
scene_desc.samples_per_pixel = 250;
345386
scene_desc.max_depth = 4;
346387
}
@@ -349,10 +390,6 @@ void default_scene(scene& scene_desc) {
349390
int main() {
350391
scene scene_desc;
351392

352-
scene_desc.background = color(0.70, 0.80, 1.00);
353-
scene_desc.cam.vup = vec3(0,1,0);
354-
scene_desc.cam.focus_dist = 10.0;
355-
356393
switch (0) {
357394
case 1: random_spheres(scene_desc); break;
358395
case 2: two_spheres(scene_desc); break;

src/TheNextWeek/scene.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,10 @@
2020
class scene {
2121
public:
2222
void render() {
23-
const int image_height = static_cast<int>(image_width / aspect_ratio);
23+
cam.initialize();
2424

25-
cam.initialize(aspect_ratio);
25+
auto image_width = cam.image_width;
26+
auto image_height = cam.get_image_height();
2627

2728
std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";
2829

@@ -47,8 +48,7 @@ class scene {
4748
hittable_list world;
4849
camera cam;
4950

50-
double aspect_ratio = 1.0;
51-
int image_width = 100;
51+
// Scene sampling parameters
5252
int samples_per_pixel = 10;
5353
int max_depth = 50;
5454
color background = color(0,0,0);

src/TheRestOfYourLife/main.cc

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,19 @@
2222

2323

2424
void cornell_box(scene& scene_desc) {
25-
scene_desc.image_width = 600;
26-
scene_desc.aspect_ratio = 1.0;
25+
scene_desc.cam.lookfrom = point3(278, 278, -800);
26+
scene_desc.cam.lookat = point3(278, 278, 0);
27+
scene_desc.cam.vup = vec3(0, 1, 0);
28+
scene_desc.cam.vfov = 40.0;
29+
30+
scene_desc.cam.aspect_ratio = 1.0;
31+
scene_desc.cam.image_width = 600;
32+
33+
scene_desc.cam.defocus_diameter = 0.0;
34+
2735
scene_desc.samples_per_pixel = 100;
28-
scene_desc.max_depth = 50;
29-
scene_desc.background = color(0,0,0);
30-
31-
scene_desc.cam.lookfrom = point3(278, 278, -800);
32-
scene_desc.cam.lookat = point3(278, 278, 0);
33-
scene_desc.cam.vup = vec3(0, 1, 0);
34-
scene_desc.cam.vfov = 40.0;
35-
scene_desc.cam.aperture = 0.0;
36-
scene_desc.cam.focus_dist = 10.0;
36+
scene_desc.max_depth = 50;
37+
scene_desc.background = color(0,0,0);
3738

3839
hittable_list& world = scene_desc.world;
3940

0 commit comments

Comments
 (0)