|
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