|
7 | 7 | Peter Shirley
|
8 | 8 | edited by Steve Hollasch and Trevor David Black
|
9 | 9 | <br>
|
10 |
| - Version 3.0.1, 2020-03-31 |
| 10 | + Version 3.1.0-wip, 2020-03-31 |
11 | 11 | <br>
|
12 | 12 | Copyright 2018-2020 Peter Shirley. All rights reserved.
|
13 | 13 |
|
|
355 | 355 | std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush;
|
356 | 356 | for (int i = 0; i < image_width; ++i) {
|
357 | 357 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
358 |
| - vec3 pixel_color(double(i)/(image_width-1), double(j)/(image_height-1), 0.25); |
| 358 | + color pixel_color(double(i)/(image_width-1), double(j)/(image_height-1), 0.25); |
359 | 359 | pixel_color.write_color(std::cout);
|
360 | 360 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
361 | 361 | }
|
|
444 | 444 |
|
445 | 445 | #include <iostream>
|
446 | 446 |
|
447 |
| - vec3 ray_color(const ray& r) { |
| 447 | + color ray_color(const ray& r) { |
448 | 448 | vec3 unit_direction = unit_vector(r.direction());
|
449 | 449 | auto t = 0.5*(unit_direction.y() + 1.0);
|
450 |
| - return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); |
| 450 | + return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5, 0.7, 1.0); |
451 | 451 | }
|
452 | 452 |
|
453 | 453 | int main() {
|
|
470 | 470 | auto u = double(i) / (image_width-1);
|
471 | 471 | auto v = double(j) / (image_height-1);
|
472 | 472 | ray r(origin, lower_left_corner + u*horizontal + v*vertical);
|
473 |
| - vec3 pixel_color = ray_color(r); |
| 473 | + color pixel_color = ray_color(r); |
474 | 474 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
475 | 475 | pixel_color.write_color(std::cout);
|
476 | 476 | }
|
|
593 | 593 | vec3 ray_color(const ray& r) {
|
594 | 594 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
595 | 595 | if (hit_sphere(vec3(0,0,-1), 0.5, r))
|
596 |
| - return vec3(1, 0, 0); |
| 596 | + return color(1, 0, 0); |
597 | 597 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
598 | 598 | vec3 unit_direction = unit_vector(r.direction());
|
599 | 599 | auto t = 0.5*(unit_direction.y() + 1.0);
|
600 |
| - return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); |
| 600 | + return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5, 0.7, 1.0); |
601 | 601 | }
|
602 | 602 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
603 | 603 | [Listing [main-red-sphere]: <kbd>[main.cc]</kbd> Rendering a red sphere]
|
|
667 | 667 | auto t = hit_sphere(vec3(0,0,-1), 0.5, r);
|
668 | 668 | if (t > 0.0) {
|
669 | 669 | vec3 N = unit_vector(r.at(t) - vec3(0,0,-1));
|
670 |
| - return 0.5*vec3(N.x()+1, N.y()+1, N.z()+1); |
| 670 | + return 0.5*color(N.x()+1, N.y()+1, N.z()+1); |
671 | 671 | }
|
672 | 672 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
673 | 673 | vec3 unit_direction = unit_vector(r.direction());
|
674 | 674 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
675 | 675 | t = 0.5*(unit_direction.y() + 1.0);
|
676 | 676 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
677 |
| - return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); |
| 677 | + return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5, 0.7, 1.0); |
678 | 678 | }
|
679 | 679 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
680 | 680 | [Listing [render-surface-normal]: <kbd>[main.cc]</kbd> Rendering surface normals on a sphere]
|
|
1124 | 1124 | #include <iostream>
|
1125 | 1125 |
|
1126 | 1126 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1127 |
| - vec3 ray_color(const ray& r, const hittable& world) { |
| 1127 | + color ray_color(const ray& r, const hittable& world) { |
1128 | 1128 | hit_record rec;
|
1129 | 1129 | if (world.hit(r, 0, infinity, rec)) {
|
1130 |
| - return 0.5 * (rec.normal + vec3(1,1,1)); |
| 1130 | + return 0.5 * (rec.normal + color(1,1,1)); |
1131 | 1131 | }
|
1132 | 1132 |
|
1133 | 1133 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1134 | 1134 | vec3 unit_direction = unit_vector(r.direction());
|
1135 | 1135 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1136 | 1136 | auto t = 0.5*(unit_direction.y() + 1.0);
|
1137 | 1137 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1138 |
| - return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); |
| 1138 | + return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5, 0.7, 1.0); |
1139 | 1139 | }
|
1140 | 1140 |
|
1141 | 1141 | int main() {
|
|
1165 | 1165 |
|
1166 | 1166 |
|
1167 | 1167 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1168 |
| - vec3 pixel_color = ray_color(r, world); |
| 1168 | + color pixel_color = ray_color(r, world); |
1169 | 1169 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1170 | 1170 |
|
1171 | 1171 | pixel_color.write_color(std::cout);
|
|
1345 | 1345 | std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush;
|
1346 | 1346 | for (int i = 0; i < image_width; ++i) {
|
1347 | 1347 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1348 |
| - vec3 pixel_color(0, 0, 0); |
| 1348 | + color pixel_color(0, 0, 0); |
1349 | 1349 | for (int s = 0; s < samples_per_pixel; ++s) {
|
1350 | 1350 | auto u = (i + random_double()) / (image_width-1);
|
1351 | 1351 | auto v = (j + random_double()) / (image_height-1);
|
|
1455 | 1455 | Then update the `ray_color()` function to use the new random direction generator:
|
1456 | 1456 |
|
1457 | 1457 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1458 |
| - vec3 ray_color(const ray& r, const hittable& world) { |
| 1458 | + color ray_color(const ray& r, const hittable& world) { |
1459 | 1459 | hit_record rec;
|
1460 | 1460 |
|
1461 | 1461 | if (world.hit(r, 0, infinity, rec)) {
|
|
1467 | 1467 |
|
1468 | 1468 | vec3 unit_direction = unit_vector(r.direction());
|
1469 | 1469 | auto t = 0.5*(unit_direction.y() + 1.0);
|
1470 |
| - return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); |
| 1470 | + return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5, 0.7, 1.0); |
1471 | 1471 | }
|
1472 | 1472 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1473 | 1473 | [Listing [ray-color-random-unit]: <kbd>[main.cc]</kbd> ray_color() using a random ray direction]
|
|
1480 | 1480 | depth, returning no light contribution at the maximum depth:
|
1481 | 1481 |
|
1482 | 1482 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1483 |
| - vec3 ray_color(const ray& r, const hittable& world, int depth) { |
| 1483 | + color ray_color(const ray& r, const hittable& world, int depth) { |
1484 | 1484 | hit_record rec;
|
1485 | 1485 |
|
1486 | 1486 | // If we've exceeded the ray bounce limit, no more light is gathered.
|
1487 | 1487 | if (depth <= 0)
|
1488 |
| - return vec3(0,0,0); |
| 1488 | + return color(0,0,0); |
1489 | 1489 |
|
1490 | 1490 | if (world.hit(r, 0, infinity, rec)) {
|
1491 | 1491 | vec3 target = rec.p + rec.normal + random_in_unit_sphere();
|
|
1495 | 1495 |
|
1496 | 1496 | vec3 unit_direction = unit_vector(r.direction());
|
1497 | 1497 | auto t = 0.5*(unit_direction.y() + 1.0);
|
1498 |
| - return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); |
| 1498 | + return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5, 0.7, 1.0); |
1499 | 1499 | }
|
| 1500 | + |
1500 | 1501 | ...
|
| 1502 | + |
1501 | 1503 | int main() {
|
1502 | 1504 | const int image_width = 200;
|
1503 | 1505 | const int image_height = 100;
|
|
1510 | 1512 | for (int j = image_height-1; j >= 0; --j) {
|
1511 | 1513 | std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush;
|
1512 | 1514 | for (int i = 0; i < image_width; ++i) {
|
1513 |
| - vec3 pixel_color(0, 0, 0); |
| 1515 | + color pixel_color(0, 0, 0); |
1514 | 1516 | for (int s = 0; s < samples_per_pixel; ++s) {
|
1515 | 1517 | auto u = (i + random_double()) / (image_width-1);
|
1516 | 1518 | auto v = (j + random_double()) / (image_height-1);
|
|
1629 | 1631 | function.
|
1630 | 1632 |
|
1631 | 1633 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1632 |
| - vec3 ray_color(const ray& r, const hittable& world, int depth) { |
| 1634 | + color ray_color(const ray& r, const hittable& world, int depth) { |
1633 | 1635 | hit_record rec;
|
1634 | 1636 |
|
1635 | 1637 | // If we've exceeded the ray bounce limit, no more light is gathered.
|
1636 | 1638 | if (depth <= 0)
|
1637 |
| - return vec3(0,0,0); |
| 1639 | + return color(0,0,0); |
1638 | 1640 |
|
1639 | 1641 | if (world.hit(r, 0.001, infinity, rec)) {
|
1640 | 1642 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
|
1645 | 1647 |
|
1646 | 1648 | vec3 unit_direction = unit_vector(r.direction());
|
1647 | 1649 | auto t = 0.5*(unit_direction.y() + 1.0);
|
1648 |
| - return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); |
| 1650 | + return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5, 0.7, 1.0); |
1649 | 1651 | }
|
1650 | 1652 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1651 | 1653 | [Listing [ray-color-unit-sphere]: <kbd>[main.cc]</kbd> ray_color() with replacement diffuse]
|
|
1711 | 1713 | Plugging the new formula into the `ray_color()` function:
|
1712 | 1714 |
|
1713 | 1715 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1714 |
| - vec3 ray_color(const ray& r, const hittable& world, int depth) { |
| 1716 | + color ray_color(const ray& r, const hittable& world, int depth) { |
1715 | 1717 | hit_record rec;
|
1716 | 1718 |
|
1717 | 1719 | // If we've exceeded the ray bounce limit, no more light is gathered.
|
1718 | 1720 | if (depth <= 0)
|
1719 |
| - return vec3(0,0,0); |
| 1721 | + return color(0,0,0); |
1720 | 1722 |
|
1721 | 1723 | if (world.hit(r, 0.001, infinity, rec)) {
|
1722 | 1724 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
|
1727 | 1729 |
|
1728 | 1730 | vec3 unit_direction = unit_vector(r.direction());
|
1729 | 1731 | auto t = 0.5*(unit_direction.y() + 1.0);
|
1730 |
| - return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); |
| 1732 | + return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5, 0.7, 1.0); |
1731 | 1733 | }
|
1732 | 1734 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1733 | 1735 | [Listing [ray-color-hemisphere]: <kbd>[main.cc]</kbd> ray_color() with hemispherical scattering]
|
|
1965 | 1967 | We need to modify the `ray_color()` function to use this:
|
1966 | 1968 |
|
1967 | 1969 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1968 |
| - vec3 ray_color(const ray& r, const hittable& world, int depth) { |
| 1970 | + color ray_color(const ray& r, const hittable& world, int depth) { |
1969 | 1971 | hit_record rec;
|
1970 | 1972 |
|
1971 | 1973 | // If we've exceeded the ray bounce limit, no more light is gathered.
|
1972 | 1974 | if (depth <= 0)
|
1973 |
| - return vec3(0,0,0); |
| 1975 | + return color(0,0,0); |
1974 | 1976 |
|
1975 | 1977 | if (world.hit(r, 0.001, infinity, rec)) {
|
1976 | 1978 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1977 | 1979 | ray scattered;
|
1978 |
| - vec3 attenuation; |
| 1980 | + color attenuation; |
1979 | 1981 | if (rec.mat_ptr->scatter(r, rec, attenuation, scattered))
|
1980 | 1982 | return attenuation * ray_color(scattered, world, depth-1);
|
1981 |
| - return vec3(0,0,0); |
| 1983 | + return color(0,0,0); |
1982 | 1984 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1983 | 1985 | }
|
1984 | 1986 |
|
1985 | 1987 | vec3 unit_direction = unit_vector(r.direction());
|
1986 | 1988 | auto t = 0.5*(unit_direction.y() + 1.0);
|
1987 |
| - return (1.0-t)*vec3(1.0, 1.0, 1.0) + t*vec3(0.5, 0.7, 1.0); |
| 1989 | + return (1.0-t)*color(1.0, 1.0, 1.0) + t*color(0.5, 0.7, 1.0); |
1988 | 1990 | }
|
1989 | 1991 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1990 | 1992 | [Listing [ray-color-scatter]: <kbd>[main.cc]</kbd> Ray color with scattered reflectance]
|
|
2020 | 2022 | for (int j = image_height-1; j >= 0; --j) {
|
2021 | 2023 | std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush;
|
2022 | 2024 | for (int i = 0; i < image_width; ++i) {
|
2023 |
| - vec3 pixel_color(0, 0, 0); |
| 2025 | + color pixel_color(0, 0, 0); |
2024 | 2026 | for (int s = 0; s < samples_per_pixel; ++s) {
|
2025 | 2027 | auto u = (i + random_double()) / (image_width-1);
|
2026 | 2028 | auto v = (j + random_double()) / (image_height-1);
|
|
0 commit comments