|
728 | 728 | our Cornell Box scene again, and let’s generate the camera in the function that generates the model:
|
729 | 729 |
|
730 | 730 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
731 |
| - void cornell_box(hittable **scene, camera **cam, double aspect) { |
732 |
| - material *red = new lambertian( new constant_texture(vec3(0.65, 0.05, 0.05)) ); |
733 |
| - material *white = new lambertian( new constant_texture(vec3(0.73, 0.73, 0.73)) ); |
734 |
| - material *green = new lambertian( new constant_texture(vec3(0.12, 0.45, 0.15)) ); |
735 |
| - material *light = new diffuse_light( new constant_texture(vec3(15, 15, 15)) ); |
736 |
| - |
737 |
| - hittable **list = new hittable*[8]; |
738 |
| - int i = 0; |
739 |
| - list[i++] = new flip_normals(new yz_rect(0, 555, 0, 555, 555, green)); |
740 |
| - list[i++] = new yz_rect(0, 555, 0, 555, 0, red); |
741 |
| - list[i++] = new xz_rect(213, 343, 227, 332, 554, light); |
742 |
| - list[i++] = new flip_normals(new xz_rect(0, 555, 0, 555, 555, white)); |
743 |
| - list[i++] = new xz_rect(0, 555, 0, 555, 0, white); |
744 |
| - list[i++] = new flip_normals(new xy_rect(0, 555, 0, 555, 555, white)); |
745 |
| - list[i++] = new translate(new rotate_y( |
746 |
| - new box(vec3(0, 0, 0), vec3(165, 165, 165), white), -18), vec3(130,0,65)); |
747 |
| - list[i++] = new translate(new rotate_y( |
748 |
| - new box(vec3(0, 0, 0), vec3(165, 330, 165), white), 15), vec3(265,0,295)); |
749 |
| - *scene = new hittable_list(list,i); |
| 731 | + hittable_list cornell_box(camera& cam, double aspect) { |
| 732 | + hittable_list world; |
| 733 | + |
| 734 | + auto *red = new lambertian(new constant_texture(vec3(0.65, 0.05, 0.05))); |
| 735 | + auto *white = new lambertian(new constant_texture(vec3(0.73, 0.73, 0.73))); |
| 736 | + auto *green = new lambertian(new constant_texture(vec3(0.12, 0.45, 0.15))); |
| 737 | + auto *light = new diffuse_light(new constant_texture(vec3(15, 15, 15))); |
| 738 | + |
| 739 | + world.add(new flip_normals(new yz_rect(0, 555, 0, 555, 555, green))); |
| 740 | + world.add(new yz_rect(0, 555, 0, 555, 0, red)); |
| 741 | + world.add(new xz_rect(213, 343, 227, 332, 554, light)); |
| 742 | + world.add(new flip_normals(new xz_rect(0, 555, 0, 555, 555, white))); |
| 743 | + world.add(new xz_rect(0, 555, 0, 555, 0, white)); |
| 744 | + world.add(new flip_normals(new xy_rect(0, 555, 0, 555, 555, white))); |
| 745 | + |
| 746 | + hittable* box1 = new box(vec3(0,0,0), vec3(165,330,165), white); |
| 747 | + box1 = new rotate_y(box1, 15); |
| 748 | + box1 = new translate(box1, vec3(265,0,295)); |
| 749 | + world.add(box1); |
| 750 | + |
| 751 | + hittable* box2 = new box(vec3(0,0,0), vec3(165,165,165), white); |
| 752 | + box2 = new rotate_y(box2, -18); |
| 753 | + box2 = new translate(box2, vec3(130,0,65); |
| 754 | + world.add(box2); |
750 | 755 |
|
751 | 756 | vec3 lookfrom(278, 278, -800);
|
752 | 757 | vec3 lookat(278, 278, 0);
|
| 758 | + vec3 up(0, 1, 0); |
753 | 759 | auto dist_to_focus = 10.0;
|
754 | 760 | auto aperture = 0.0;
|
755 | 761 | auto vfov = 40.0;
|
756 |
| - *cam = new camera( |
757 |
| - lookfrom, lookat, vec3(0,1,0), vfov, aspect, aperture, dist_to_focus, 0.0, 1.0); |
| 762 | + auto t0 = 0.0; |
| 763 | + auto t1 = 1.0; |
| 764 | + |
| 765 | + cam = camera(lookfrom, lookat, up, vfov, aspect, aperture, dist_to_focus, t0, t1); |
| 766 | + |
| 767 | + return world; |
758 | 768 | }
|
759 | 769 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
760 | 770 | [Listing [cornell-box]: <kbd>[main.cc]</kbd> Cornell box, refactored]
|
|
837 | 847 | And the color function gets a minor modification:
|
838 | 848 |
|
839 | 849 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
840 |
| - vec3 ray_color(const ray& r, hittable *world, int depth) { |
| 850 | + vec3 ray_color(const ray& r, hittable& world, int depth) { |
841 | 851 | hit_record rec;
|
842 |
| - if (depth <= 0 || !world->hit(r, 0.001, infinity, rec)) |
| 852 | + |
| 853 | + // If we've exceeded the ray bounce limit, no more light is gathered. |
| 854 | + if (depth <= 0) |
| 855 | + return vec3(0,0,0); |
| 856 | + |
| 857 | + // If the ray hits nothing, return the background color. |
| 858 | + if (!world.hit(r, 0.001, infinity, rec)) |
843 | 859 | return vec3(0,0,0);
|
844 | 860 |
|
845 | 861 | ray scattered;
|
846 | 862 | vec3 attenuation;
|
847 | 863 | vec3 emitted = rec.mat_ptr->emitted(rec.u, rec.v, rec.p);
|
| 864 | + |
| 865 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight |
848 | 866 | double pdf;
|
849 | 867 | vec3 albedo;
|
850 | 868 |
|
|
854 | 872 | return emitted
|
855 | 873 | + albedo * rec.mat_ptr->scattering_pdf(r, rec, scattered)
|
856 | 874 | * ray_color(scattered, world, depth-1) / pdf;
|
| 875 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ |
857 | 876 | }
|
858 | 877 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
859 | 878 | [Listing [ray-color-impsample]: <kbd>[main.cc]</kbd>
|
|
1284 | 1303 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1285 | 1304 | vec3 ray_color(const ray& r, hittable *world, int depth) {
|
1286 | 1305 | hit_record rec;
|
1287 |
| - if (depth <= 0 || !world->hit(r, 0,001, infinity, rec)) |
| 1306 | + |
| 1307 | + // If we've exceeded the ray bounce limit, no more light is gathered. |
| 1308 | + if (depth <= 0) |
| 1309 | + return vec3(0,0,0); |
| 1310 | + |
| 1311 | + // If the ray hits nothing, return the background color. |
| 1312 | + if (!world.hit(r, 0.001, infinity, rec)) |
1288 | 1313 | return vec3(0,0,0);
|
1289 | 1314 |
|
1290 | 1315 | ray scattered;
|
|
1445 | 1470 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1446 | 1471 | vec3 ray_color(const ray& r, hittable *world, int depth) {
|
1447 | 1472 | hit_record rec;
|
1448 |
| - if (depth <= 0 || !world->hit(r, 0.001, infinity, rec)) |
| 1473 | + |
| 1474 | + // If we've exceeded the ray bounce limit, no more light is gathered. |
| 1475 | + if (depth <= 0) |
| 1476 | + return vec3(0,0,0); |
| 1477 | + |
| 1478 | + // If the ray hits nothing, return the background color. |
| 1479 | + if (!world.hit(r, 0.001, infinity, rec)) |
1449 | 1480 | return vec3(0,0,0);
|
1450 | 1481 |
|
1451 | 1482 | ray scattered;
|
|
1564 | 1595 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1565 | 1596 | vec3 ray_color(const ray& r, hittable *world, int depth) {
|
1566 | 1597 | hit_record rec;
|
1567 |
| - if (depth <= 0 || !world->hit(r, 0.001, infinity, rec)) |
| 1598 | + |
| 1599 | + // If we've exceeded the ray bounce limit, no more light is gathered. |
| 1600 | + if (depth <= 0) |
| 1601 | + return vec3(0,0,0); |
| 1602 | + |
| 1603 | + // If the ray hits nothing, return the background color. |
| 1604 | + if (!world.hit(r, 0.001, infinity, rec)) |
1568 | 1605 | return vec3(0,0,0);
|
1569 | 1606 |
|
1570 | 1607 | ray scattered;
|
|
1630 | 1667 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1631 | 1668 | vec3 ray_color(const ray& r, hittable *world, hittable *light_shape, int depth) {
|
1632 | 1669 | hit_record rec;
|
1633 |
| - if (depth <= 0 || !world->hit(r, 0.001, infinity, rec)) |
| 1670 | + |
| 1671 | + // If we've exceeded the ray bounce limit, no more light is gathered. |
| 1672 | + if (depth <= 0) |
| 1673 | + return vec3(0,0,0); |
| 1674 | + |
| 1675 | + // If the ray hits nothing, return the background color. |
| 1676 | + if (!world.hit(r, 0.001, infinity, rec)) |
1634 | 1677 | return vec3(0,0,0);
|
1635 | 1678 |
|
1636 | 1679 | ray scattered;
|
|
1813 | 1856 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1814 | 1857 | vec3 ray_color(const ray& r, hittable *world, hittable *light_shape, int depth) {
|
1815 | 1858 | hit_record rec;
|
1816 |
| - if (depth <= 0 || !world->hit(r, 0.001, infinity, rec)) |
| 1859 | + |
| 1860 | + // If we've exceeded the ray bounce limit, no more light is gathered. |
| 1861 | + if (depth <= 0) |
1817 | 1862 | return vec3(0,0,0);
|
1818 | 1863 |
|
| 1864 | + // If the ray hits nothing, return the background color. |
| 1865 | + if (!world.hit(r, 0.001, infinity, rec)) |
| 1866 | + return vec3(0,0,0); |
1819 | 1867 |
|
1820 | 1868 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1821 | 1869 | scatter_record srec;
|
|
1876 | 1924 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1877 | 1925 | vec3 ray_color(const ray& r, hittable *world, hittable *light_shape, int depth) {
|
1878 | 1926 | hit_record rec;
|
1879 |
| - if (depth <= 0 || !world->hit(r, 0.001, infinity, rec)) |
| 1927 | + |
| 1928 | + // If we've exceeded the ray bounce limit, no more light is gathered. |
| 1929 | + if (depth <= 0) |
| 1930 | + return vec3(0,0,0); |
| 1931 | + |
| 1932 | + // If the ray hits nothing, return the background color. |
| 1933 | + if (!world.hit(r, 0.001, infinity, rec)) |
1880 | 1934 | return vec3(0,0,0);
|
1881 | 1935 |
|
1882 | 1936 | scatter_record srec;
|
|
1910 | 1964 | We also need to change the block to metal.
|
1911 | 1965 |
|
1912 | 1966 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1913 |
| - void cornell_box(hittable **scene, camera **cam, double aspect) { |
1914 |
| - int i = 0; |
1915 |
| - hittable **list = new hittable*[8]; |
1916 |
| - material *red = new lambertian( new constant_texture(vec3(0.65, 0.05, 0.05)) ); |
1917 |
| - material *white = new lambertian( new constant_texture(vec3(0.73, 0.73, 0.73)) ); |
1918 |
| - material *green = new lambertian( new constant_texture(vec3(0.12, 0.45, 0.15)) ); |
1919 |
| - material *light = new diffuse_light( new constant_texture(vec3(15, 15, 15)) ); |
1920 |
| - list[i++] = new flip_normals(new yz_rect(0, 555, 0, 555, 555, green)); |
1921 |
| - list[i++] = new yz_rect(0, 555, 0, 555, 0, red); |
1922 |
| - list[i++] = new flip_normals(new xz_rect(213, 343, 227, 332, 554, light)); |
1923 |
| - list[i++] = new flip_normals(new xz_rect(0, 555, 0, 555, 555, white)); |
1924 |
| - list[i++] = new xz_rect(0, 555, 0, 555, 0, white); |
1925 |
| - list[i++] = new flip_normals(new xy_rect(0, 555, 0, 555, 555, white)); |
1926 |
| - list[i++] = new translate( |
1927 |
| - new rotate_y(new box(vec3(0, 0, 0), vec3(165, 165, 165), white), -18), |
1928 |
| - vec3(130,0,65)); |
| 1967 | + hittable_list cornell_box(camera& cam, double aspect) { |
| 1968 | + hittable_list world; |
| 1969 | + |
| 1970 | + auto *red = new lambertian(new constant_texture(vec3(0.65, 0.05, 0.05))); |
| 1971 | + auto *white = new lambertian(new constant_texture(vec3(0.73, 0.73, 0.73))); |
| 1972 | + auto *green = new lambertian(new constant_texture(vec3(0.12, 0.45, 0.15))); |
| 1973 | + auto *light = new diffuse_light(new constant_texture(vec3(15, 15, 15))); |
| 1974 | + |
| 1975 | + world.add(new flip_normals(new yz_rect(0, 555, 0, 555, 555, green))); |
| 1976 | + world.add(new yz_rect(0, 555, 0, 555, 0, red)); |
| 1977 | + world.add(new xz_rect(213, 343, 227, 332, 554, light)); |
| 1978 | + world.add(new flip_normals(new xz_rect(0, 555, 0, 555, 555, white))); |
| 1979 | + world.add(new xz_rect(0, 555, 0, 555, 0, white)); |
| 1980 | + world.add(new flip_normals(new xy_rect(0, 555, 0, 555, 555, white))); |
| 1981 | + |
1929 | 1982 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1930 | 1983 | material *aluminum = new metal(vec3(0.8, 0.85, 0.88), 0.0);
|
1931 |
| - list[i++] = new translate( |
1932 |
| - new rotate_y(new box(vec3(0, 0, 0), vec3(165, 330, 165), aluminum), 15), |
1933 |
| - vec3(265,0,295)); |
| 1984 | + hittable* box1 = new box(vec3(0,0,0), vec3(165,330,165), aluminum); |
1934 | 1985 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1935 |
| - *scene = new hittable_list(list,i); |
| 1986 | + box1 = new rotate_y(box1, 15); |
| 1987 | + box1 = new translate(box1, vec3(265,0,295)); |
| 1988 | + world.add(box1); |
| 1989 | + |
| 1990 | + hittable* box2 = new box(vec3(0,0,0), vec3(165,165,165), white); |
| 1991 | + box2 = new rotate_y(box2, -18); |
| 1992 | + box2 = new translate(box2, vec3(130,0,65); |
| 1993 | + world.add(box2); |
1936 | 1994 |
|
1937 | 1995 | vec3 lookfrom(278, 278, -800);
|
1938 |
| - vec3 lookat(278,278,0); |
| 1996 | + vec3 lookat(278, 278, 0); |
| 1997 | + vec3 up(0, 1, 0); |
1939 | 1998 | auto dist_to_focus = 10.0;
|
1940 | 1999 | auto aperture = 0.0;
|
1941 | 2000 | auto vfov = 40.0;
|
1942 |
| - *cam = new camera( |
1943 |
| - lookfrom, lookat, vec3(0,1,0), vfov, aspect, aperture, dist_to_focus, 0.0, 1.0); |
| 2001 | + auto t0 = 0.0; |
| 2002 | + auto t1 = 1.0; |
| 2003 | + |
| 2004 | + cam = camera(lookfrom, lookat, up, vfov, aspect, aperture, dist_to_focus, t0, t1); |
| 2005 | + |
| 2006 | + return world; |
1944 | 2007 | }
|
1945 | 2008 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1946 | 2009 | [Listing [scene-cornell-al]: <kbd>[main.cc]</kbd> Cornell box scene with aluminum material]
|
|
2100 | 2163 |
|
2101 | 2164 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
2102 | 2165 | double hittable_list::pdf_value(const vec3& o, const vec3& v) const {
|
2103 |
| - auto weight = 1.0/list_size; |
| 2166 | + auto weight = 1.0/objects.size(); |
2104 | 2167 | auto sum = 0.0;
|
2105 |
| - for (int i = 0; i < list_size; i++) |
2106 |
| - sum += weight*list[i]->pdf_value(o, v); |
| 2168 | + |
| 2169 | + for (auto object : objects) |
| 2170 | + sum += weight * object->pdf_value(o, v); |
| 2171 | + |
2107 | 2172 | return sum;
|
2108 | 2173 | }
|
2109 | 2174 |
|
2110 | 2175 | vec3 hittable_list::random(const vec3& o) const {
|
2111 |
| - int index = random_int(0, list_size-1); |
2112 |
| - return list[ index ]->random(o); |
| 2176 | + auto int_size = static_cast<int>(objects.size()); |
| 2177 | + auto index = static_cast<size_t>(random_int(0, int_size-1)); |
| 2178 | + return objects[index]->random(o); |
2113 | 2179 | }
|
2114 | 2180 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2115 | 2181 | [Listing [density-mixture]: <kbd>[hittable_list.h]</kbd> Creating a mixture of densities]
|
2116 | 2182 | </div>
|
2117 | 2183 |
|
2118 | 2184 | <div class='together'>
|
2119 |
| -We assemble a list to pass in to `ray_color()`. |
| 2185 | +We assemble a list to pass to `ray_color()` `from main()`: |
2120 | 2186 |
|
2121 | 2187 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
2122 |
| - hittable *light_shape = new xz_rect(213, 343, 227, 332, 554, 0); |
2123 |
| - hittable *glass_sphere = new sphere(vec3(190, 90, 190), 90, 0); |
2124 |
| - hittable *a[2]; |
2125 |
| - a[0] = light_shape; |
2126 |
| - a[1] = glass_sphere; |
2127 |
| - hittable_list hlist(a,2); |
| 2188 | + hittable_list lights; |
| 2189 | + lights.add(new xz_rect(213, 343, 227, 332, 554, 0)); |
| 2190 | + lights.add(new sphere(vec3(190, 90, 190), 90, 0)); |
2128 | 2191 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
2129 | 2192 | [Listing [scene-density-mixture]: <kbd>[main.cc]</kbd> Updating the scene]
|
2130 | 2193 | </div>
|
|
0 commit comments