|
90 | 90 |
|
91 | 91 | std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";
|
92 | 92 |
|
93 |
| - for (int j = image_height-1; j >= 0; --j) { |
| 93 | + for (int j = 0; j < image_height; ++j) { |
94 | 94 | for (int i = 0; i < image_width; ++i) {
|
95 | 95 | auto r = double(i) / (image_width-1);
|
96 | 96 | auto g = double(j) / (image_height-1);
|
|
189 | 189 | instead write to the logging output stream (`std::clog`):
|
190 | 190 |
|
191 | 191 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
192 |
| - for (int j = image_height-1; j >= 0; --j) { |
| 192 | + for (int j = 0; j < image_height; ++j) { |
193 | 193 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
194 |
| - std::clog << "\rScanlines remaining: " << j << ' ' << std::flush; |
| 194 | + std::clog << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush; |
195 | 195 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
196 | 196 | for (int i = 0; i < image_width; ++i) {
|
197 | 197 | auto r = double(i) / (image_width-1);
|
|
401 | 401 |
|
402 | 402 | std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";
|
403 | 403 |
|
404 |
| - for (int j = image_height-1; j >= 0; --j) { |
405 |
| - std::clog << "\rScanlines remaining: " << j << ' ' << std::flush; |
| 404 | + for (int j = 0; j < image_height; ++j) { |
| 405 | + std::clog << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush; |
406 | 406 | for (int i = 0; i < image_width; ++i) {
|
407 | 407 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
408 | 408 | color pixel_color(double(i)/(image_width-1), double(j)/(image_height-1), 0.25);
|
|
484 | 484 | often, so I’ll use a non-square image. For now we'll use a 16:9 aspect ratio, since that's so
|
485 | 485 | common.
|
486 | 486 |
|
| 487 | + |
487 | 488 | In addition to setting up the pixel dimensions for the rendered image, we also need to set up a
|
488 | 489 | virtual viewport through which to pass our scene rays. For the standard pixel spacing (equally
|
489 | 490 | spaced in both the horizontal and vertical direction), the viewport's aspect ratio should be the
|
|
547 | 548 |
|
548 | 549 | std::cout << "P3\n" << image_width << " " << image_height << "\n255\n";
|
549 | 550 |
|
550 |
| - for (int j = image_height-1; j >= 0; --j) { |
551 |
| - std::clog << "\rScanlines remaining: " << j << ' ' << std::flush; |
| 551 | + for (int j = 0; j < image_height; ++j) { |
| 552 | + std::clog << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush; |
552 | 553 | for (int i = 0; i < image_width; ++i) {
|
553 | 554 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
554 |
| - auto u = double(i) / (image_width-1); |
555 |
| - auto v = double(j) / (image_height-1); |
556 |
| - ray r(origin, lower_left_corner + u*horizontal + v*vertical - origin); |
| 555 | + auto s = double(i) / (image_width-1); |
| 556 | + auto t = double(j) / (image_height-1); |
| 557 | + ray r(origin, lower_left_corner + s*horizontal + (1-t)*vertical - origin); |
557 | 558 | color pixel_color = ray_color(r);
|
558 | 559 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
559 | 560 | write_color(std::cout, pixel_color);
|
|
1253 | 1254 |
|
1254 | 1255 | std::cout << "P3\n" << image_width << ' ' << image_height << "\n255\n";
|
1255 | 1256 |
|
1256 |
| - for (int j = image_height-1; j >= 0; --j) { |
1257 |
| - std::clog << "\rScanlines remaining: " << j << ' ' << std::flush; |
| 1257 | + for (int j = 0; j < image_height; ++j) { |
| 1258 | + std::clog << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush; |
1258 | 1259 | for (int i = 0; i < image_width; ++i) {
|
1259 |
| - auto u = double(i) / (image_width-1); |
1260 |
| - auto v = double(j) / (image_height-1); |
1261 |
| - ray r(origin, lower_left_corner + u*horizontal + v*vertical); |
| 1260 | + auto s = double(i) / (image_width-1); |
| 1261 | + auto t = double(j) / (image_height-1); |
| 1262 | + ray r(origin, lower_left_corner + s*horizontal + (1-t)*vertical); |
1262 | 1263 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1263 | 1264 | color pixel_color = ray_color(r, world);
|
1264 | 1265 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
|
1489 | 1490 | }
|
1490 | 1491 |
|
1491 | 1492 | ray get_ray(double s, double t) const {
|
1492 |
| - return ray(origin, lower_left_corner + s*horizontal + t*vertical - origin); |
| 1493 | + // Return the ray from the projection point to the indicated pixel. Coordinates s,t are |
| 1494 | + // the normalized image-based coordinates of the pixel. Image left is s=0, image right |
| 1495 | + // is s=1, image top is t=0, image bottom is t=1. |
| 1496 | + |
| 1497 | + return ray(origin, lower_left_corner + s*horizontal + (1-t)*vertical - origin); |
1493 | 1498 | }
|
1494 | 1499 |
|
1495 | 1500 | private:
|
|
1590 | 1595 |
|
1591 | 1596 | std::cout << "P3\n" << image_width << " " << image_height << "\n255\n";
|
1592 | 1597 |
|
1593 |
| - for (int j = image_height-1; j >= 0; --j) { |
1594 |
| - std::clog << "\rScanlines remaining: " << j << ' ' << std::flush; |
| 1598 | + for (int j = 0; j < image_height; ++j) { |
| 1599 | + std::clog << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush; |
| 1600 | + auto t = (j + random_double()) / (image_height-1); |
| 1601 | + |
1595 | 1602 | for (int i = 0; i < image_width; ++i) {
|
1596 | 1603 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1597 | 1604 | color pixel_color(0, 0, 0);
|
1598 | 1605 | for (int sample = 0; sample < samples_per_pixel; ++sample) {
|
1599 |
| - auto u = (i + random_double()) / (image_width-1); |
1600 |
| - auto v = (j + random_double()) / (image_height-1); |
1601 |
| - ray r = cam.get_ray(u, v); |
| 1606 | + auto s = (i + random_double()) / (image_width-1); |
| 1607 | + ray r = cam.get_ray(s, t); |
1602 | 1608 | pixel_color += ray_color(r, world);
|
1603 | 1609 | }
|
1604 | 1610 | write_color(std::cout, pixel_color, samples_per_pixel);
|
|
1769 | 1775 |
|
1770 | 1776 | std::cout << "P3\n" << image_width << " " << image_height << "\n255\n";
|
1771 | 1777 |
|
1772 |
| - for (int j = image_height-1; j >= 0; --j) { |
1773 |
| - std::clog << "\rScanlines remaining: " << j << ' ' << std::flush; |
| 1778 | + for (int j = 0; j < image_height; ++j) { |
| 1779 | + std::clog << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush; |
| 1780 | + auto t = (j + random_double()) / (image_height-1); |
| 1781 | + |
1774 | 1782 | for (int i = 0; i < image_width; ++i) {
|
1775 | 1783 | color pixel_color(0, 0, 0);
|
1776 | 1784 | for (int sample = 0; sample < samples_per_pixel; ++sample) {
|
1777 |
| - auto u = (i + random_double()) / (image_width-1); |
1778 |
| - auto v = (j + random_double()) / (image_height-1); |
1779 |
| - ray r = cam.get_ray(u, v); |
| 1785 | + auto s = (i + random_double()) / (image_width-1); |
| 1786 | + ray r = cam.get_ray(s, t); |
1780 | 1787 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1781 | 1788 | pixel_color += ray_color(r, world, max_depth);
|
1782 | 1789 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
|
2367 | 2374 |
|
2368 | 2375 | // Render
|
2369 | 2376 |
|
2370 |
| - std::cout << "P3\n" << image_width << " " << image_height << "\n255\n"; |
2371 |
| - |
2372 |
| - for (int j = image_height-1; j >= 0; --j) { |
2373 |
| - std::clog << "\rScanlines remaining: " << j << ' ' << std::flush; |
2374 |
| - for (int i = 0; i < image_width; ++i) { |
2375 |
| - color pixel_color(0, 0, 0); |
2376 |
| - for (int sample = 0; sample < samples_per_pixel; ++sample) { |
2377 |
| - auto u = (i + random_double()) / (image_width-1); |
2378 |
| - auto v = (j + random_double()) / (image_height-1); |
2379 |
| - ray r = cam.get_ray(u, v); |
2380 |
| - pixel_color += ray_color(r, world, max_depth); |
2381 |
| - } |
2382 |
| - write_color(std::cout, pixel_color, samples_per_pixel); |
2383 |
| - } |
2384 |
| - } |
| 2377 | + ... |
2385 | 2378 |
|
2386 | 2379 | std::clog << "\nDone.\n";
|
2387 | 2380 | }
|
|
2828 | 2821 | void render() {
|
2829 | 2822 | std::cout << "P3\n" << image_width << " " << image_height << "\n255\n";
|
2830 | 2823 |
|
2831 |
| - for (int j = image_height-1; j >= 0; --j) { |
2832 |
| - std::clog << "\rScanlines remaining: " << j << ' ' << std::flush; |
| 2824 | + for (int j = 0; j < image_height; ++j) { |
| 2825 | + std::clog << "\rScanlines remaining: " << (image_height - j) << ' ' << std::flush; |
| 2826 | + auto t = (j + random_double()) / (image_height-1); |
| 2827 | + |
2833 | 2828 | for (int i = 0; i < image_width; ++i) {
|
2834 | 2829 | color pixel_color(0,0,0);
|
2835 | 2830 | for (int sample = 0; sample < samples_per_pixel; ++sample) {
|
2836 |
| - auto u = (i + random_double()) / (image_width-1); |
2837 |
| - auto v = (j + random_double()) / (image_height-1); |
2838 |
| - ray r = cam.get_ray(u, v); |
| 2831 | + auto s = (i + random_double()) / (image_width-1); |
| 2832 | + ray r = cam.get_ray(s, t); |
2839 | 2833 | pixel_color += ray_color(r, max_depth);
|
2840 | 2834 | }
|
2841 | 2835 | write_color(std::cout, pixel_color, samples_per_pixel);
|
|
0 commit comments