|
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