|
1764 | 1764 | <div class='together'> |
1765 | 1765 | And then change `ray_color()`: |
1766 | 1766 |
|
| 1767 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1768 | + color ray_color( |
| 1769 | + const ray& r, const color& background, const hittable& world, |
| 1770 | + shared_ptr<hittable>& lights, int depth |
| 1771 | + ) { |
1767 | 1772 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1768 | | - color ray_color(const ray& r, const color& background, const hittable& world, int depth) { |
1769 | | - hit_record rec; |
1770 | | - |
1771 | | - // If we've exceeded the ray bounce limit, no more light is gathered. |
1772 | | - if (depth <= 0) |
1773 | | - return color(0,0,0); |
1774 | | - |
1775 | | - // If the ray hits nothing, return the background color. |
1776 | | - if (!world.hit(r, 0.001, infinity, rec)) |
1777 | | - return background; |
| 1773 | + ... |
1778 | 1774 |
|
1779 | 1775 | ray scattered; |
1780 | 1776 | color attenuation; |
|
1786 | 1782 |
|
1787 | 1783 |
|
1788 | 1784 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1789 | | - shared_ptr<hittable> light_shape = |
1790 | | - make_shared<xz_rect>(213, 343, 227, 332, 554, shared_ptr<material>()); |
1791 | | - hittable_pdf p(light_shape, rec.p); |
| 1785 | + hittable_pdf light_pdf(lights, rec.p); |
| 1786 | + scattered = ray(rec.p, light_pdf.generate(), r.time()); |
| 1787 | + pdf_val = light_pdf.value(scattered.direction()); |
1792 | 1788 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1793 | 1789 |
|
1794 | | - scattered = ray(rec.p, p.generate(), r.time()); |
1795 | | - pdf_val = p.value(scattered.direction()); |
1796 | | - |
1797 | 1790 | return emitted |
1798 | 1791 | + albedo * rec.mat_ptr->scattering_pdf(r, rec, scattered) |
1799 | | - * ray_color(scattered, background, world, depth-1) / pdf_val; |
| 1792 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1793 | + * ray_color(scattered, background, world, lights, depth-1) / pdf_val; |
| 1794 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1800 | 1795 | } |
| 1796 | + |
| 1797 | + ... |
| 1798 | + int main() { |
| 1799 | + ... |
| 1800 | + // World |
| 1801 | + |
| 1802 | + auto world = cornell_box(); |
| 1803 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1804 | + shared_ptr<hittable> lights = |
| 1805 | + make_shared<xz_rect>(213, 343, 227, 332, 554, shared_ptr<material>()); |
| 1806 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1807 | + |
| 1808 | + ... |
| 1809 | + for (int j = image_height-1; j >= 0; --j) { |
| 1810 | + std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush; |
| 1811 | + for (int i = 0; i < image_width; ++i) { |
| 1812 | + ... |
| 1813 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 1814 | + pixel_color += ray_color(r, background, world, lights, max_depth); |
| 1815 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1816 | + ... |
| 1817 | + |
1801 | 1818 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1802 | 1819 | [Listing [ray-color-hittable-pdf]: <kbd>[main.cc]</kbd> ray_color function with hittable PDF] |
1803 | 1820 | </div> |
|
1847 | 1864 | And plugging it into `ray_color()`: |
1848 | 1865 |
|
1849 | 1866 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1850 | | - color ray_color(const ray& r, const color& background, const hittable& world, int depth) { |
1851 | | - hit_record rec; |
1852 | | - |
1853 | | - // If we've exceeded the ray bounce limit, no more light is gathered. |
1854 | | - if (depth <= 0) |
1855 | | - return color(0,0,0); |
1856 | | - |
1857 | | - // If the ray hits nothing, return the background color. |
1858 | | - if (!world.hit(r, 0.001, infinity, rec)) |
1859 | | - return background; |
| 1867 | + color ray_color( |
| 1868 | + const ray& r, const color& background, const hittable& world, |
| 1869 | + shared_ptr<hittable>& lights, int depth |
| 1870 | + ) { |
| 1871 | + ... |
1860 | 1872 |
|
1861 | 1873 | ray scattered; |
1862 | 1874 | color attenuation; |
|
1866 | 1878 | if (!rec.mat_ptr->scatter(r, rec, albedo, scattered, pdf_val)) |
1867 | 1879 | return emitted; |
1868 | 1880 |
|
1869 | | - shared_ptr<hittable> light_shape = |
1870 | | - make_shared<xz_rect>(213, 343, 227, 332, 554, make_shared<material>()); |
1871 | 1881 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
1872 | | - auto p0 = make_shared<hittable_pdf>(light_shape, rec.p); |
| 1882 | + auto p0 = make_shared<hittable_pdf>(lights, rec.p); |
1873 | 1883 | auto p1 = make_shared<cosine_pdf>(rec.normal); |
1874 | | - mixture_pdf p(p0, p1); |
1875 | | - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 1884 | + mixture_pdf mixed_pdf(p0, p1); |
1876 | 1885 |
|
1877 | | - scattered = ray(rec.p, p.generate(), r.time()); |
1878 | | - pdf_val = p.value(scattered.direction()); |
| 1886 | + scattered = ray(rec.p, mixed_pdf.generate(), r.time()); |
| 1887 | + pdf_val = mixed_pdf.value(scattered.direction()); |
| 1888 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
1879 | 1889 |
|
1880 | | - return emitted |
1881 | | - + albedo * rec.mat_ptr->scattering_pdf(r, rec, scattered) |
1882 | | - * ray_color(scattered, background, world, depth-1) / pdf_val; |
| 1890 | + ... |
1883 | 1891 | } |
1884 | 1892 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
1885 | 1893 | [Listing [ray-color-mixture]: <kbd>[main.cc]</kbd> The ray_color function, using mixture PDF] |
|
2043 | 2051 | <div class='together'> |
2044 | 2052 | And `ray_color()` changes are small: |
2045 | 2053 |
|
2046 | | - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 2054 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2047 | 2055 | color ray_color( |
2048 | 2056 | const ray& r, |
2049 | 2057 | const color& background, |
2050 | 2058 | const hittable& world, |
2051 | | - shared_ptr<hittable> lights, |
| 2059 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 2060 | + shared_ptr<hittable>& lights, |
| 2061 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2052 | 2062 | int depth |
2053 | 2063 | ) { |
2054 | | - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2055 | 2064 | hit_record rec; |
2056 | 2065 |
|
2057 | 2066 | // If we've exceeded the ray bounce limit, no more light is gathered. |
|
2086 | 2095 | ... |
2087 | 2096 | // World |
2088 | 2097 |
|
| 2098 | + auto world = cornell_box(); |
2089 | 2099 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
2090 | 2100 | auto lights = make_shared<hittable_list>(); |
2091 | 2101 | lights->add(make_shared<xz_rect>(213, 343, 227, 332, 554, shared_ptr<material>())); |
2092 | 2102 | lights->add(make_shared<sphere>(point3(190, 90, 190), 90, shared_ptr<material>())); |
2093 | 2103 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2094 | | - |
2095 | | - auto world = cornell_box(); |
2096 | | - |
2097 | | - color background(0,0,0); |
2098 | | - |
2099 | | - for (int j = image_height-1; j >= 0; --j) { |
2100 | | - std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush; |
2101 | | - for (int i = 0; i < image_width; ++i) { |
2102 | | - ... |
2103 | | - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
2104 | | - pixel_color += ray_color(r, background, world, lights, max_depth); |
| 2104 | + ... |
2105 | 2105 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2106 | 2106 | [Listing [ray-color-scatter]: <kbd>[main.cc]</kbd> Ray color with scatter] |
2107 | 2107 | </div> |
|
2173 | 2173 | const ray& r, |
2174 | 2174 | const color& background, |
2175 | 2175 | const hittable& world, |
2176 | | - shared_ptr<hittable> lights, |
| 2176 | + shared_ptr<hittable>& lights, |
2177 | 2177 | int depth |
2178 | 2178 | ) { |
2179 | | - hit_record rec; |
2180 | | - |
2181 | | - // If we've exceeded the ray bounce limit, no more light is gathered. |
2182 | | - if (depth <= 0) |
2183 | | - return color(0,0,0); |
2184 | | - |
2185 | | - // If the ray hits nothing, return the background color. |
2186 | | - if (!world.hit(r, 0.001, infinity, rec)) |
2187 | | - return background; |
| 2179 | + ... |
2188 | 2180 |
|
2189 | 2181 | scatter_record srec; |
2190 | 2182 | color emitted = rec.mat_ptr->emitted(r, rec, rec.u, rec.v, rec.p); |
2191 | 2183 | if (!rec.mat_ptr->scatter(r, rec, srec)) |
2192 | 2184 | return emitted; |
2193 | 2185 |
|
| 2186 | + |
2194 | 2187 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
2195 | 2188 | if (srec.is_specular) { |
2196 | 2189 | return srec.attenuation |
2197 | 2190 | * ray_color(srec.specular_ray, background, world, lights, depth-1); |
2198 | 2191 | } |
2199 | 2192 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2200 | 2193 |
|
2201 | | - shared_ptr<pdf> light_ptr = make_shared<hittable_pdf>(lights, rec.p); |
2202 | | - mixture_pdf p(light_ptr, srec.pdf_ptr); |
2203 | | - |
2204 | | - ray scattered = ray(rec.p, p.generate(), r.time()); |
2205 | | - auto pdf_val = p.value(scattered.direction()); |
2206 | | - delete srec.pdf_ptr; |
2207 | | - |
2208 | | - return emitted + srec.attenuation |
2209 | | - * rec.mat_ptr->scattering_pdf(r, rec, scattered) |
2210 | | - * ray_color(scattered, background, world, lights, depth-1) / pdf_val; |
| 2194 | + ... |
2211 | 2195 | } |
2212 | 2196 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2213 | 2197 | [Listing [ray-color-implicit]: <kbd>[main.cc]</kbd> |
|
2383 | 2367 | We can first try just sampling the sphere rather than the light: |
2384 | 2368 |
|
2385 | 2369 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
2386 | | - shared_ptr<hittable> light_shape = make_shared<xz_rect>(213, 343, 227, 332, 554, 0); |
2387 | | - shared_ptr<hittable> glass_sphere = make_shared<sphere>(point3(190, 90, 190), 90, 0); |
2388 | | - |
2389 | | - ... |
| 2370 | + int main() { |
| 2371 | + ... |
| 2372 | + // World |
2390 | 2373 |
|
2391 | | - for (int j = image_height-1; j >= 0; --j) { |
2392 | | - std::cerr << "\rScanlines remaining: " << j << ' ' << std::flush; |
2393 | | - for (int i = 0; i < image_width; ++i) { |
2394 | | - color pixel_color(0, 0, 0); |
2395 | | - for (int s=0; s < ns; ++s) { |
2396 | | - auto u = (i + random_double()) / image_width; |
2397 | | - auto v = (j + random_double()) / image_height; |
2398 | | - ray r = cam->get_ray(u, v); |
2399 | | - pixel_color += ray_color(r, background, world, glass_sphere, max_depth); |
2400 | | - } |
| 2374 | + auto world = cornell_box(); |
| 2375 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
| 2376 | + shared_ptr<hittable> lights = |
| 2377 | + // make_shared<xz_rect>(213, 343, 227, 332, 554, shared_ptr<material>()); |
| 2378 | + make_shared<sphere>(point3(190, 90, 190), 90, shared_ptr<material>()); |
| 2379 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
| 2380 | + ... |
2401 | 2381 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
2402 | 2382 | [Listing [sampling-sphere]: <kbd>[main.cc]</kbd> Sampling just the sphere] |
2403 | 2383 | </div> |
|
0 commit comments