|
848 | 848 | And the color function gets a minor modification:
|
849 | 849 |
|
850 | 850 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
851 |
| - vec3 ray_color(const ray& r, hittable& world, int depth) { |
| 851 | + vec3 ray_color(const ray& r, const vec3& background, hittable& world, int depth) { |
852 | 852 | hit_record rec;
|
853 | 853 |
|
854 | 854 | // If we've exceeded the ray bounce limit, no more light is gathered.
|
|
857 | 857 |
|
858 | 858 | // If the ray hits nothing, return the background color.
|
859 | 859 | if (!world.hit(r, 0.001, infinity, rec))
|
860 |
| - return vec3(0,0,0); |
| 860 | + return background; |
861 | 861 |
|
862 | 862 | ray scattered;
|
863 | 863 | vec3 attenuation;
|
|
872 | 872 |
|
873 | 873 | return emitted
|
874 | 874 | + albedo * rec.mat_ptr->scattering_pdf(r, rec, scattered)
|
875 |
| - * ray_color(scattered, world, depth-1) / pdf; |
| 875 | + * ray_color(scattered, background, world, depth-1) / pdf; |
876 | 876 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
877 | 877 | }
|
878 | 878 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
1306 | 1306 | that math and get the concept, we can add it (see the highlighted region):
|
1307 | 1307 |
|
1308 | 1308 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1309 |
| - vec3 ray_color(const ray& r, hittable& world, int depth) { |
| 1309 | + vec3 ray_color(const ray& r, const vec3& background, hittable& world, int depth) { |
1310 | 1310 | hit_record rec;
|
1311 | 1311 |
|
1312 | 1312 | // If we've exceeded the ray bounce limit, no more light is gathered.
|
|
1315 | 1315 |
|
1316 | 1316 | // If the ray hits nothing, return the background color.
|
1317 | 1317 | if (!world.hit(r, 0.001, infinity, rec))
|
1318 |
| - return vec3(0,0,0); |
| 1318 | + return background; |
1319 | 1319 |
|
1320 | 1320 | ray scattered;
|
1321 | 1321 | vec3 attenuation;
|
|
1345 | 1345 |
|
1346 | 1346 | return emitted
|
1347 | 1347 | + albedo * rec.mat_ptr->scattering_pdf(r, rec, scattered)
|
1348 |
| - * ray_color(scattered, world, depth-1) / pdf; |
| 1348 | + * ray_color(scattered, background, world, depth-1) / pdf; |
1349 | 1349 | }
|
1350 | 1350 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1351 | 1351 | [Listing [ray-color-lights]: <kbd>[main.cc]</kbd> Ray color with light sampling]
|
|
1477 | 1477 | change variable `pdf` to some other variable name to avoid a name conflict with the new `pdf` class.
|
1478 | 1478 |
|
1479 | 1479 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1480 |
| - vec3 ray_color(const ray& r, hittable& world, int depth) { |
| 1480 | + vec3 ray_color(const ray& r, const vec3& background, hittable& world, int depth) { |
1481 | 1481 | hit_record rec;
|
1482 | 1482 |
|
1483 | 1483 | // If we've exceeded the ray bounce limit, no more light is gathered.
|
|
1486 | 1486 |
|
1487 | 1487 | // If the ray hits nothing, return the background color.
|
1488 | 1488 | if (!world.hit(r, 0.001, infinity, rec))
|
1489 |
| - return vec3(0,0,0); |
| 1489 | + return background; |
1490 | 1490 |
|
1491 | 1491 | ray scattered;
|
1492 | 1492 | vec3 attenuation;
|
|
1504 | 1504 |
|
1505 | 1505 | return emitted
|
1506 | 1506 | + albedo * rec.mat_ptr->scattering_pdf(r, rec, scattered)
|
1507 |
| - * ray_color(scattered, world, depth-1) |
| 1507 | + * ray_color(scattered, background, world, depth-1) |
1508 | 1508 | / pdf_val;
|
1509 | 1509 | }
|
1510 | 1510 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
1612 | 1612 | And then change `ray_color()`:
|
1613 | 1613 |
|
1614 | 1614 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1615 |
| - vec3 ray_color(const ray& r, hittable& world, int depth) { |
| 1615 | + vec3 ray_color(const ray& r, const vec3& background, hittable& world, int depth) { |
1616 | 1616 | hit_record rec;
|
1617 | 1617 |
|
1618 | 1618 | // If we've exceeded the ray bounce limit, no more light is gathered.
|
|
1621 | 1621 |
|
1622 | 1622 | // If the ray hits nothing, return the background color.
|
1623 | 1623 | if (!world.hit(r, 0.001, infinity, rec))
|
1624 |
| - return vec3(0,0,0); |
| 1624 | + return background; |
1625 | 1625 |
|
1626 | 1626 | ray scattered;
|
1627 | 1627 | vec3 attenuation;
|
|
1642 | 1642 |
|
1643 | 1643 | return emitted
|
1644 | 1644 | + albedo * rec.mat_ptr->scattering_pdf(r, rec, scattered)
|
1645 |
| - * ray_color(scattered, world, depth-1) |
| 1645 | + * ray_color(scattered, background, world, depth-1) |
1646 | 1646 | / pdf_val;
|
1647 | 1647 | }
|
1648 | 1648 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
1690 | 1690 | And plugging it into `ray_color()`:
|
1691 | 1691 |
|
1692 | 1692 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1693 |
| - vec3 ray_color(const ray& r, hittable& world, shared_ptr<hittable> light_shape, int depth) { |
| 1693 | + vec3 ray_color( |
| 1694 | + const ray& r, |
| 1695 | + const vec3& background, |
| 1696 | + hittable& world, |
| 1697 | + shared_ptr<hittable> lights, |
| 1698 | + int depth |
| 1699 | + ) { |
1694 | 1700 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1695 | 1701 | hit_record rec;
|
1696 | 1702 |
|
|
1700 | 1706 |
|
1701 | 1707 | // If the ray hits nothing, return the background color.
|
1702 | 1708 | if (!world.hit(r, 0.001, infinity, rec))
|
1703 |
| - return vec3(0,0,0); |
| 1709 | + return background; |
1704 | 1710 |
|
1705 | 1711 | ray scattered;
|
1706 | 1712 | vec3 attenuation;
|
|
1724 | 1730 |
|
1725 | 1731 | return emitted
|
1726 | 1732 | + albedo * rec.mat_ptr->scattering_pdf(r, rec, scattered)
|
1727 |
| - * ray_color(scattered, world, depth-1) |
| 1733 | + * ray_color(scattered, background, world, lights, depth-1) |
1728 | 1734 | / pdf_val;
|
1729 | 1735 | }
|
1730 | 1736 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
1884 | 1890 | And `ray_color()` changes are small:
|
1885 | 1891 |
|
1886 | 1892 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1887 |
| - vec3 ray_color(const ray& r, hittable& world, shared_ptr<hittable> light_shape, int depth) { |
| 1893 | + vec3 ray_color( |
| 1894 | + const ray& r, |
| 1895 | + const vec3& background, |
| 1896 | + hittable& world, |
| 1897 | + shared_ptr<hittable> lights, |
| 1898 | + int depth |
| 1899 | + ) { |
1888 | 1900 | hit_record rec;
|
1889 | 1901 |
|
1890 | 1902 | // If we've exceeded the ray bounce limit, no more light is gathered.
|
|
1893 | 1905 |
|
1894 | 1906 | // If the ray hits nothing, return the background color.
|
1895 | 1907 | if (!world.hit(r, 0.001, infinity, rec))
|
1896 |
| - return vec3(0,0,0); |
| 1908 | + return background; |
1897 | 1909 |
|
1898 | 1910 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1899 | 1911 | scatter_record srec;
|
1900 | 1912 | vec3 emitted = rec.mat_ptr->emitted(r, rec, rec.u, rec.v, rec.p);
|
1901 | 1913 | if (!rec.mat_ptr->scatter(r, rec, srec))
|
1902 | 1914 | return emitted;
|
1903 | 1915 |
|
1904 |
| - auto light_ptr = make_shared<hittable_pdf>(light_shape, rec.p); |
| 1916 | + auto light_ptr = make_shared<hittable_pdf>(lights, rec.p); |
1905 | 1917 | mixture_pdf p(light_ptr, srec.pdf_ptr);
|
1906 | 1918 |
|
1907 | 1919 | ray scattered = ray(rec.p, p.generate(), r.time());
|
1908 | 1920 | auto pdf_val = p.value(scattered.direction());
|
1909 | 1921 |
|
1910 | 1922 | return emitted
|
1911 | 1923 | + srec.attenuation * rec.mat_ptr->scattering_pdf(r, rec, scattered)
|
1912 |
| - * ray_color(scattered, world, light_shape, depth-1) |
| 1924 | + * ray_color(scattered, background, world, lights, depth-1) |
1913 | 1925 | / pdf_val;
|
1914 | 1926 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1915 | 1927 | }
|
|
1954 | 1966 | `ray_color()` just needs a new case to generate an implicitly sampled ray:
|
1955 | 1967 |
|
1956 | 1968 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1957 |
| - vec3 ray_color(const ray& r, hittable& world, shared_ptr<hittable> light_shape, int depth) { |
| 1969 | + vec3 ray_color( |
| 1970 | + const ray& r, |
| 1971 | + const vec3& background, |
| 1972 | + hittable& world, |
| 1973 | + shared_ptr<hittable> lights, |
| 1974 | + int depth |
| 1975 | + ) { |
1958 | 1976 | hit_record rec;
|
1959 | 1977 |
|
1960 | 1978 | // If we've exceeded the ray bounce limit, no more light is gathered.
|
|
1963 | 1981 |
|
1964 | 1982 | // If the ray hits nothing, return the background color.
|
1965 | 1983 | if (!world.hit(r, 0.001, infinity, rec))
|
1966 |
| - return vec3(0,0,0); |
| 1984 | + return background; |
1967 | 1985 |
|
1968 | 1986 | scatter_record srec;
|
1969 | 1987 | vec3 emitted = rec.mat_ptr->emitted(r, rec, rec.u, rec.v, rec.p);
|
|
1973 | 1991 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1974 | 1992 | if (srec.is_specular) {
|
1975 | 1993 | return srec.attenuation
|
1976 |
| - * ray_color(srec.specular_ray, world, light_shape, depth-1); |
| 1994 | + * ray_color(srec.specular_ray, background, world, lights, depth-1); |
1977 | 1995 | }
|
1978 | 1996 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1979 | 1997 |
|
1980 |
| - shared_ptr<pdf> light_ptr = make_shared<hittable_pdf>(light_shape, rec.p); |
| 1998 | + shared_ptr<pdf> light_ptr = make_shared<hittable_pdf>(lights, rec.p); |
1981 | 1999 | mixture_pdf p(light_ptr, srec.pdf_ptr);
|
1982 | 2000 |
|
1983 | 2001 | ray scattered = ray(rec.p, p.generate(), r.time());
|
|
1986 | 2004 |
|
1987 | 2005 | return emitted + srec.attenuation
|
1988 | 2006 | * rec.mat_ptr->scattering_pdf(r, rec, scattered)
|
1989 |
| - * ray_color(scattered, world, light_shape, depth-1) |
| 2007 | + * ray_color(scattered, background, world, lights, depth-1) |
1990 | 2008 | / pdf_val;
|
1991 | 2009 | }
|
1992 | 2010 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
2174 | 2192 | auto u = (i + random_double()) / image_width;
|
2175 | 2193 | auto v = (j + random_double()) / image_height;
|
2176 | 2194 | ray r = cam->get_ray(u, v);
|
2177 |
| - col += ray_color(r, world, glass_sphere, max_depth); |
| 2195 | + col += ray_color(r, background, world, glass_sphere, max_depth); |
2178 | 2196 | }
|
2179 | 2197 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2180 | 2198 | [Listing [sampling-sphere]: <kbd>[main.cc]</kbd> Sampling just the sphere]
|
|
0 commit comments