|
275 | 275 | return e[0]*e[0] + e[1]*e[1] + e[2]*e[2];
|
276 | 276 | }
|
277 | 277 |
|
278 |
| - void write_color(std::ostream &out) { |
279 |
| - // Write the translated [0,255] value of each color component. |
280 |
| - out << static_cast<int>(255.999 * e[0]) << ' ' |
281 |
| - << static_cast<int>(255.999 * e[1]) << ' ' |
282 |
| - << static_cast<int>(255.999 * e[2]) << '\n'; |
283 |
| - } |
284 |
| - |
285 | 278 | public:
|
286 | 279 | double e[3];
|
287 | 280 | };
|
|
352 | 345 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
353 | 346 | [Listing [vec3-utility]: <kbd>[vec3.h]</kbd> vec3 utility functions]
|
354 | 347 |
|
| 348 | + |
| 349 | +Color Utility Functions |
| 350 | +------------------------ |
| 351 | +Using our new `vec3` class, we'll create a utility function to write a single pixel's color out to |
| 352 | +the standard output stream. |
| 353 | + |
| 354 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 355 | + #ifndef COLOR_H |
| 356 | + #define COLOR_H |
| 357 | + |
| 358 | + #include "vec3.h" |
| 359 | + |
| 360 | + #include <iostream> |
| 361 | + |
| 362 | + void write_color(std::ostream &out, color pixel_color) { |
| 363 | + // Write the translated [0,255] value of each color component. |
| 364 | + out << static_cast<int>(255.999 * pixel_color.x()) << ' ' |
| 365 | + << static_cast<int>(255.999 * pixel_color.y()) << ' ' |
| 366 | + << static_cast<int>(255.999 * pixel_color.z()) << '\n'; |
| 367 | + } |
| 368 | + |
| 369 | + #endif |
| 370 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 371 | + [Listing [color]: <kbd>[color.h]</kbd> color utility functions] |
| 372 | + |
| 373 | + |
| 374 | + |
355 | 375 | <div class='together'>
|
356 | 376 | Now we can change our main to use this:
|
357 | 377 |
|
358 | 378 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
| 379 | + #include "color.h" |
359 | 380 | #include "vec3.h"
|
360 | 381 |
|
361 | 382 | #include <iostream>
|
|
371 | 392 | for (int i = 0; i < image_width; ++i) {
|
372 | 393 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
373 | 394 | color pixel_color(double(i)/(image_width-1), double(j)/(image_height-1), 0.25);
|
374 |
| - pixel_color.write_color(std::cout); |
| 395 | + write_color(std::cout, pixel_color); |
375 | 396 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
376 | 397 | }
|
377 | 398 | }
|
|
492 | 513 | ray r(origin, lower_left_corner + u*horizontal + v*vertical);
|
493 | 514 | color pixel_color = ray_color(r);
|
494 | 515 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
495 |
| - pixel_color.write_color(std::cout); |
| 516 | + write_color(std::cout, pixel_color); |
496 | 517 | }
|
497 | 518 | }
|
498 | 519 |
|
|
1217 | 1238 | color pixel_color = ray_color(r, world);
|
1218 | 1239 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1219 | 1240 |
|
1220 |
| - pixel_color.write_color(std::cout); |
| 1241 | + write_color(std::cout, pixel_color); |
1221 | 1242 | }
|
1222 | 1243 | }
|
1223 | 1244 |
|
|
1344 | 1365 | [Listing [camera-initial]: <kbd>[camera.h]</kbd> The camera class]
|
1345 | 1366 | </div>
|
1346 | 1367 |
|
1347 |
| -To handle the multi-sampled color computation, we update the `vec3::write_color()` function. Rather |
| 1368 | +To handle the multi-sampled color computation, we'll update the `write_color()` function. Rather |
1348 | 1369 | than adding in a fractional contribution each time we accumulate more light to the color, just add
|
1349 | 1370 | the full color each iteration, and then perform a single divide at the end (by the number of
|
1350 | 1371 | samples) when writing out the color. In addition, we'll add a handy utility function to the
|
|
1360 | 1381 | [Listing [clamp]: <kbd>[rtweekend.h]</kbd> The clamp() utility function]
|
1361 | 1382 |
|
1362 | 1383 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1363 |
| - void write_color(std::ostream &out, int samples_per_pixel) { |
| 1384 | + void write_color(std::ostream &out, color pixel_color, int samples_per_pixel) { |
| 1385 | + auto r = pixel_color.x(); |
| 1386 | + auto g = pixel_color.y(); |
| 1387 | + auto b = pixel_color.z(); |
| 1388 | + |
1364 | 1389 | // Divide the color total by the number of samples.
|
1365 | 1390 | auto scale = 1.0 / samples_per_pixel;
|
1366 |
| - auto r = scale * e[0]; |
1367 |
| - auto g = scale * e[1]; |
1368 |
| - auto b = scale * e[2]; |
| 1391 | + r *= scale; |
| 1392 | + g *= scale; |
| 1393 | + b *= scale; |
1369 | 1394 |
|
1370 | 1395 | // Write the translated [0,255] value of each color component.
|
1371 | 1396 | out << static_cast<int>(256 * clamp(r, 0.0, 0.999)) << ' '
|
1372 | 1397 | << static_cast<int>(256 * clamp(g, 0.0, 0.999)) << ' '
|
1373 | 1398 | << static_cast<int>(256 * clamp(b, 0.0, 0.999)) << '\n';
|
1374 | 1399 | }
|
1375 | 1400 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1376 |
| - [Listing [write-color-clamped]: <kbd>[vec3.h]</kbd> The write_color() function] |
| 1401 | + [Listing [write-color-clamped]: <kbd>[color.h]</kbd> The multi-sample write_color() function] |
1377 | 1402 |
|
1378 | 1403 | <div class='together'>
|
1379 | 1404 | Main is also changed:
|
|
1407 | 1432 | ray r = cam.get_ray(u, v);
|
1408 | 1433 | pixel_color += ray_color(r, world);
|
1409 | 1434 | }
|
1410 |
| - pixel_color.write_color(std::cout, samples_per_pixel); |
| 1435 | + write_color(std::cout, pixel_color, samples_per_pixel); |
1411 | 1436 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1412 | 1437 | }
|
1413 | 1438 | }
|
|
1588 | 1613 | pixel_color += ray_color(r, world, max_depth);
|
1589 | 1614 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1590 | 1615 | }
|
1591 |
| - pixel_color.write_color(std::cout, samples_per_pixel); |
| 1616 | + write_color(std::cout, pixel_color, samples_per_pixel); |
1592 | 1617 | }
|
1593 | 1618 | }
|
1594 | 1619 |
|
|
1623 | 1648 | square-root:
|
1624 | 1649 |
|
1625 | 1650 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1626 |
| - void write_color(std::ostream &out, int samples_per_pixel) { |
| 1651 | + void write_color(std::ostream &out, color pixel_color, int samples_per_pixel) { |
| 1652 | + auto r = pixel_color.x(); |
| 1653 | + auto g = pixel_color.y(); |
| 1654 | + auto b = pixel_color.z(); |
| 1655 | + |
1627 | 1656 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1628 |
| - // Divide the color total by the number of samples and gamma-correct |
1629 |
| - // for a gamma value of 2.0. |
| 1657 | + // Divide the color total by the number of samples and gamma-correct for gamma=2.0. |
1630 | 1658 | auto scale = 1.0 / samples_per_pixel;
|
1631 |
| - auto r = sqrt(scale * e[0]); |
1632 |
| - auto g = sqrt(scale * e[1]); |
1633 |
| - auto b = sqrt(scale * e[2]); |
| 1659 | + r = sqrt(scale * r); |
| 1660 | + g = sqrt(scale * g); |
| 1661 | + b = sqrt(scale * b); |
1634 | 1662 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1635 | 1663 |
|
1636 | 1664 | // Write the translated [0,255] value of each color component.
|
|
1639 | 1667 | << static_cast<int>(256 * clamp(b, 0.0, 0.999)) << '\n';
|
1640 | 1668 | }
|
1641 | 1669 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1642 |
| - [Listing [write-color-gamma]: <kbd>[vec3.h]</kbd> write_color(), with gamma correction] |
| 1670 | + [Listing [write-color-gamma]: <kbd>[color.h]</kbd> write_color(), with gamma correction] |
1643 | 1671 |
|
1644 | 1672 | </div>
|
1645 | 1673 |
|
|
2127 | 2155 | ray r = cam.get_ray(u, v);
|
2128 | 2156 | pixel_color += ray_color(r, world, max_depth);
|
2129 | 2157 | }
|
2130 |
| - pixel_color.write_color(std::cout, samples_per_pixel); |
| 2158 | + write_color(std::cout, pixel_color, samples_per_pixel); |
2131 | 2159 | }
|
2132 | 2160 | }
|
2133 | 2161 |
|
|
0 commit comments