|
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