|
274 | 274 | return e[0]*e[0] + e[1]*e[1] + e[2]*e[2];
|
275 | 275 | }
|
276 | 276 |
|
277 |
| - void write_color(std::ostream &out) { |
278 |
| - // Write the translated [0,255] value of each color component. |
279 |
| - out << static_cast<int>(255.999 * e[0]) << ' ' |
280 |
| - << static_cast<int>(255.999 * e[1]) << ' ' |
281 |
| - << static_cast<int>(255.999 * e[2]) << '\n'; |
282 |
| - } |
283 |
| - |
284 | 277 | public:
|
285 | 278 | double e[3];
|
286 | 279 | };
|
|
351 | 344 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
352 | 345 | [Listing [vec3-utility]: <kbd>[vec3.h]</kbd> vec3 utility functions]
|
353 | 346 |
|
| 347 | + |
| 348 | +Color Utility Functions |
| 349 | +------------------------ |
| 350 | +Using our new `vec3` class, we'll create a utility function to write a single pixel's color out to |
| 351 | +the standard output stream. |
| 352 | + |
| 353 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 354 | + #ifndef COLOR_H |
| 355 | + #define COLOR_H |
| 356 | + |
| 357 | + #include "vec3.h" |
| 358 | + |
| 359 | + #include <iostream> |
| 360 | + |
| 361 | + void write_color(std::ostream &out, color pixel_color) { |
| 362 | + // Write the translated [0,255] value of each color component. |
| 363 | + out << static_cast<int>(255.999 * pixel_color.x()) << ' ' |
| 364 | + << static_cast<int>(255.999 * pixel_color.y()) << ' ' |
| 365 | + << static_cast<int>(255.999 * pixel_color.z()) << '\n'; |
| 366 | + } |
| 367 | + |
| 368 | + #endif |
| 369 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 370 | + [Listing [color]: <kbd>[color.h]</kbd> color utility functions] |
| 371 | + |
| 372 | + |
| 373 | + |
354 | 374 | <div class='together'>
|
355 | 375 | Now we can change our main to use this:
|
356 | 376 |
|
357 | 377 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
| 378 | + #include "color.h" |
358 | 379 | #include "vec3.h"
|
359 | 380 |
|
360 | 381 | #include <iostream>
|
|
370 | 391 | for (int i = 0; i < image_width; ++i) {
|
371 | 392 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
372 | 393 | color pixel_color(double(i)/(image_width-1), double(j)/(image_height-1), 0.25);
|
373 |
| - pixel_color.write_color(std::cout); |
| 394 | + write_color(std::cout, pixel_color); |
374 | 395 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
375 | 396 | }
|
376 | 397 | }
|
|
491 | 512 | ray r(origin, lower_left_corner + u*horizontal + v*vertical);
|
492 | 513 | color pixel_color = ray_color(r);
|
493 | 514 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
494 |
| - pixel_color.write_color(std::cout); |
| 515 | + write_color(std::cout, pixel_color); |
495 | 516 | }
|
496 | 517 | }
|
497 | 518 |
|
|
1204 | 1225 | color pixel_color = ray_color(r, world);
|
1205 | 1226 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1206 | 1227 |
|
1207 |
| - pixel_color.write_color(std::cout); |
| 1228 | + write_color(std::cout, pixel_color); |
1208 | 1229 | }
|
1209 | 1230 | }
|
1210 | 1231 |
|
|
1328 | 1349 | [Listing [camera-initial]: <kbd>[camera.h]</kbd> The camera class]
|
1329 | 1350 | </div>
|
1330 | 1351 |
|
1331 |
| -To handle the multi-sampled color computation, we update the `vec3::write_color()` function. Rather |
| 1352 | +To handle the multi-sampled color computation, we'll update the `write_color()` function. Rather |
1332 | 1353 | than adding in a fractional contribution each time we accumulate more light to the color, just add
|
1333 | 1354 | the full color each iteration, and then perform a single divide at the end (by the number of
|
1334 | 1355 | samples) when writing out the color. In addition, we'll add a handy utility function to the
|
|
1344 | 1365 | [Listing [clamp]: <kbd>[rtweekend.h]</kbd> The clamp() utility function]
|
1345 | 1366 |
|
1346 | 1367 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1347 |
| - void write_color(std::ostream &out, int samples_per_pixel) { |
| 1368 | + void write_color(std::ostream &out, color pixel_color, int samples_per_pixel) { |
| 1369 | + auto r = pixel_color.x(); |
| 1370 | + auto g = pixel_color.y(); |
| 1371 | + auto b = pixel_color.z(); |
| 1372 | + |
1348 | 1373 | // Divide the color total by the number of samples.
|
1349 | 1374 | auto scale = 1.0 / samples_per_pixel;
|
1350 |
| - auto r = scale * e[0]; |
1351 |
| - auto g = scale * e[1]; |
1352 |
| - auto b = scale * e[2]; |
| 1375 | + r *= scale; |
| 1376 | + g *= scale; |
| 1377 | + b *= scale; |
1353 | 1378 |
|
1354 | 1379 | // Write the translated [0,255] value of each color component.
|
1355 | 1380 | out << static_cast<int>(256 * clamp(r, 0.0, 0.999)) << ' '
|
1356 | 1381 | << static_cast<int>(256 * clamp(g, 0.0, 0.999)) << ' '
|
1357 | 1382 | << static_cast<int>(256 * clamp(b, 0.0, 0.999)) << '\n';
|
1358 | 1383 | }
|
1359 | 1384 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1360 |
| - [Listing [write-color-clamped]: <kbd>[vec3.h]</kbd> The write_color() function] |
| 1385 | + [Listing [write-color-clamped]: <kbd>[color.h]</kbd> The multi-sample write_color() function] |
1361 | 1386 |
|
1362 | 1387 | <div class='together'>
|
1363 | 1388 | Main is also changed:
|
|
1391 | 1416 | ray r = cam.get_ray(u, v);
|
1392 | 1417 | pixel_color += ray_color(r, world);
|
1393 | 1418 | }
|
1394 |
| - pixel_color.write_color(std::cout, samples_per_pixel); |
| 1419 | + write_color(std::cout, pixel_color, samples_per_pixel); |
1395 | 1420 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1396 | 1421 | }
|
1397 | 1422 | }
|
|
1568 | 1593 | pixel_color += ray_color(r, world, max_depth);
|
1569 | 1594 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1570 | 1595 | }
|
1571 |
| - pixel_color.write_color(std::cout, samples_per_pixel); |
| 1596 | + write_color(std::cout, pixel_color, samples_per_pixel); |
1572 | 1597 | }
|
1573 | 1598 | }
|
1574 | 1599 |
|
|
1599 | 1624 | square-root:
|
1600 | 1625 |
|
1601 | 1626 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1602 |
| - void write_color(std::ostream &out, int samples_per_pixel) { |
| 1627 | + void write_color(std::ostream &out, color pixel_color, int samples_per_pixel) { |
| 1628 | + auto r = pixel_color.x(); |
| 1629 | + auto g = pixel_color.y(); |
| 1630 | + auto b = pixel_color.z(); |
| 1631 | + |
1603 | 1632 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1604 |
| - // Divide the color total by the number of samples and gamma-correct |
1605 |
| - // for a gamma value of 2.0. |
| 1633 | + // Divide the color total by the number of samples and gamma-correct for gamma=2.0. |
1606 | 1634 | auto scale = 1.0 / samples_per_pixel;
|
1607 |
| - auto r = sqrt(scale * e[0]); |
1608 |
| - auto g = sqrt(scale * e[1]); |
1609 |
| - auto b = sqrt(scale * e[2]); |
| 1635 | + r = sqrt(scale * r); |
| 1636 | + g = sqrt(scale * g); |
| 1637 | + b = sqrt(scale * b); |
1610 | 1638 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1611 | 1639 |
|
1612 | 1640 | // Write the translated [0,255] value of each color component.
|
|
1615 | 1643 | << static_cast<int>(256 * clamp(b, 0.0, 0.999)) << '\n';
|
1616 | 1644 | }
|
1617 | 1645 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1618 |
| - [Listing [write-color-gamma]: <kbd>[vec3.h]</kbd> write_color(), with gamma correction] |
| 1646 | + [Listing [write-color-gamma]: <kbd>[color.h]</kbd> write_color(), with gamma correction] |
1619 | 1647 |
|
1620 | 1648 | </div>
|
1621 | 1649 |
|
|
2092 | 2120 | ray r = cam.get_ray(u, v);
|
2093 | 2121 | pixel_color += ray_color(r, world, max_depth);
|
2094 | 2122 | }
|
2095 |
| - pixel_color.write_color(std::cout, samples_per_pixel); |
| 2123 | + write_color(std::cout, pixel_color, samples_per_pixel); |
2096 | 2124 | }
|
2097 | 2125 | }
|
2098 | 2126 |
|
|
0 commit comments