|
209 | 209 | rec.t = temp;
|
210 | 210 | rec.p = r.at(rec.t);
|
211 | 211 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
212 |
| - rec.normal = (rec.p - center(r.time())) / radius; |
| 212 | + vec3 outward_normal = (rec.p - center(r.time())) / radius; |
213 | 213 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
| 214 | + if (dot(r.direction(), outward_normal) > 0.0) { |
| 215 | + // ray is inside the sphere |
| 216 | + rec.normal = -outward_normal; |
| 217 | + rec.front_face = false; |
| 218 | + } |
| 219 | + else { |
| 220 | + // ray is outside the sphere |
| 221 | + rec.normal = outward_normal; |
| 222 | + rec.front_face = true; |
| 223 | + } |
214 | 224 | rec.mat_ptr = mat_ptr;
|
215 | 225 | return true;
|
216 | 226 | }
|
|
219 | 229 | rec.t = temp;
|
220 | 230 | rec.p = r.at(rec.t);
|
221 | 231 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
222 |
| - rec.normal = (rec.p - center(r.time())) / radius; |
| 232 | + vec3 outward_normal = (rec.p - center(r.time())) / radius; |
223 | 233 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
| 234 | + if (dot(r.direction(), outward_normal) > 0.0) { |
| 235 | + // ray is inside the sphere |
| 236 | + rec.normal = -outward_normal; |
| 237 | + rec.front_face = false; |
| 238 | + } |
| 239 | + else { |
| 240 | + // ray is outside the sphere |
| 241 | + rec.normal = outward_normal; |
| 242 | + rec.front_face = true; |
| 243 | + } |
224 | 244 | rec.mat_ptr = mat_ptr;
|
225 | 245 | return true;
|
226 | 246 | }
|
|
1691 | 1711 | rec.u = (x-x0)/(x1-x0);
|
1692 | 1712 | rec.v = (y-y0)/(y1-y0);
|
1693 | 1713 | rec.t = t;
|
| 1714 | + vec3 outward_normal = vec3(0, 0, 1); |
| 1715 | + if (dot(r.direction(), outward_normal) > 0.0) { |
| 1716 | + rec.normal = -outward_normal; |
| 1717 | + rec.front_face = false; |
| 1718 | + } |
| 1719 | + else { |
| 1720 | + rec.normal = outward_normal; |
| 1721 | + rec.front_face = true; |
| 1722 | + } |
1694 | 1723 | rec.mat_ptr = mp;
|
1695 | 1724 | rec.p = r.at(t);
|
1696 |
| - rec.normal = vec3(0, 0, 1); |
1697 | 1725 | return true;
|
1698 | 1726 | }
|
1699 | 1727 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
1795 | 1823 | rec.u = (x-x0)/(x1-x0);
|
1796 | 1824 | rec.v = (z-z0)/(z1-z0);
|
1797 | 1825 | rec.t = t;
|
| 1826 | + vec3 outward_normal = vec3(0, 1, 0); |
| 1827 | + if (dot(r.direction(), outward_normal) > 0.0) { |
| 1828 | + rec.normal = -outward_normal; |
| 1829 | + rec.front_face = false; |
| 1830 | + } |
| 1831 | + else { |
| 1832 | + rec.normal = outward_normal; |
| 1833 | + rec.front_face = true; |
| 1834 | + } |
1798 | 1835 | rec.mat_ptr = mp;
|
1799 | 1836 | rec.p = r.at(t);
|
1800 |
| - rec.normal = vec3(0, 1, 0); |
1801 | 1837 | return true;
|
1802 | 1838 | }
|
1803 | 1839 |
|
|
1812 | 1848 | rec.u = (y-y0)/(y1-y0);
|
1813 | 1849 | rec.v = (z-z0)/(z1-z0);
|
1814 | 1850 | rec.t = t;
|
| 1851 | + vec3 outward_normal = vec3(1, 0, 0); |
| 1852 | + if (dot(r.direction(), outward_normal) > 0.0) { |
| 1853 | + rec.normal = -outward_normal; |
| 1854 | + rec.front_face = false; |
| 1855 | + } |
| 1856 | + else { |
| 1857 | + rec.normal = outward_normal; |
| 1858 | + rec.front_face = true; |
| 1859 | + } |
1815 | 1860 | rec.mat_ptr = mp;
|
1816 | 1861 | rec.p = r.at(t);
|
1817 |
| - rec.normal = vec3(1, 0, 0); |
1818 | 1862 | return true;
|
1819 | 1863 | }
|
1820 | 1864 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
1864 | 1908 | <div class='together'>
|
1865 | 1909 | We get:
|
1866 | 1910 |
|
1867 |
| -  |
| 1911 | +  |
1868 | 1912 |
|
1869 | 1913 | </div>
|
1870 | 1914 |
|
1871 | 1915 | <div class='together'>
|
1872 |
| -This is very noisy because the light is small. But why are the other walls missing? They are facing |
1873 |
| -the wrong way. We need outward facing normals. Let’s make a hittable that does nothing but hold |
1874 |
| -another hittable, but reverses the normals: |
| 1916 | +This is very noisy because the light is small. But we have a problem: Some of the walls are facing |
| 1917 | +the wrong way. We haven't specified that a diffuse material should behave differently on different |
| 1918 | +faces of the object, but what if the Cornell box had a different pattern on the inside and outside |
| 1919 | +walls? The rectangle objects are described such that their front face is always in the $(1, 0, 0)$, |
| 1920 | +$(0, 1, 0)$, or $(0, 0, 1)$ directions. We need a way to switch the faces of an object. Let’s make |
| 1921 | +a hittable that does nothing but hold another hittable, but flips the face: |
1875 | 1922 |
|
1876 | 1923 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1877 |
| - class flip_normals : public hittable { |
| 1924 | + class flip_face : public hittable { |
1878 | 1925 | public:
|
1879 |
| - flip_normals(hittable *p) : ptr(p) {} |
| 1926 | + flip_face(hittable *p) : ptr(p) {} |
1880 | 1927 |
|
1881 | 1928 | virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const {
|
1882 | 1929 | if (ptr->hit(r, t_min, t_max, rec)) {
|
|
1894 | 1941 | hittable *ptr;
|
1895 | 1942 | };
|
1896 | 1943 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1897 |
| - [Listing [flip-normals]: <kbd>[hittable.h]</kbd> Flip-normals function] |
| 1944 | + [Listing [flip-face]: <kbd>[hittable.h]</kbd> Flip-Face function] |
1898 | 1945 | </div>
|
1899 | 1946 |
|
1900 | 1947 | <div class='together'>
|
|
1910 | 1957 | material *light = new diffuse_light(new constant_texture(vec3(15, 15, 15)));
|
1911 | 1958 |
|
1912 | 1959 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1913 |
| - list[i++] = new flip_normals(new yz_rect(0, 555, 0, 555, 555, green)); |
| 1960 | + list[i++] = new flip_face(new yz_rect(0, 555, 0, 555, 555, green)); |
1914 | 1961 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1915 | 1962 | list[i++] = new yz_rect(0, 555, 0, 555, 0, red);
|
1916 | 1963 | list[i++] = new xz_rect(213, 343, 227, 332, 554, light);
|
1917 | 1964 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1918 |
| - list[i++] = new flip_normals(new xz_rect(0, 555, 0, 555, 555, white)); |
| 1965 | + list[i++] = new flip_face(new xz_rect(0, 555, 0, 555, 555, white)); |
1919 | 1966 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1920 | 1967 | list[i++] = new xz_rect(0, 555, 0, 555, 0, white);
|
1921 | 1968 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
1922 |
| - list[i++] = new flip_normals(new xy_rect(0, 555, 0, 555, 555, white)); |
| 1969 | + list[i++] = new flip_face(new xy_rect(0, 555, 0, 555, 555, white)); |
1923 | 1970 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1924 | 1971 |
|
1925 | 1972 | return new hittable_list(list,i);
|
|
1965 | 2012 | pmax = p1;
|
1966 | 2013 | hittable **list = new hittable*[6];
|
1967 | 2014 | list[0] = new xy_rect(p0.x(), p1.x(), p0.y(), p1.y(), p1.z(), ptr);
|
1968 |
| - list[1] = new flip_normals(new xy_rect(p0.x(), p1.x(), p0.y(), p1.y(), p0.z(), ptr)); |
| 2015 | + list[1] = new flip_face(new xy_rect(p0.x(), p1.x(), p0.y(), p1.y(), p0.z(), ptr)); |
1969 | 2016 | list[2] = new xz_rect(p0.x(), p1.x(), p0.z(), p1.z(), p1.y(), ptr);
|
1970 |
| - list[3] = new flip_normals(new xz_rect(p0.x(), p1.x(), p0.z(), p1.z(), p0.y(), ptr)); |
| 2017 | + list[3] = new flip_face(new xz_rect(p0.x(), p1.x(), p0.z(), p1.z(), p0.y(), ptr)); |
1971 | 2018 | list[4] = new yz_rect(p0.y(), p1.y(), p0.z(), p1.z(), p1.x(), ptr);
|
1972 |
| - list[5] = new flip_normals(new yz_rect(p0.y(), p1.y(), p0.z(), p1.z(), p0.x(), ptr)); |
| 2019 | + list[5] = new flip_face(new yz_rect(p0.y(), p1.y(), p0.z(), p1.z(), p0.x(), ptr)); |
1973 | 2020 | list_ptr = new hittable_list(list,6);
|
1974 | 2021 | }
|
1975 | 2022 |
|
|
2032 | 2079 | ray moved_r(r.origin() - offset, r.direction(), r.time());
|
2033 | 2080 | if (ptr->hit(moved_r, t_min, t_max, rec)) {
|
2034 | 2081 | rec.p += offset;
|
| 2082 | + if (dot(moved_r.direction(), rec.normal) > 0.0) { |
| 2083 | + rec.normal = -rec.normal; |
| 2084 | + rec.front_face = false; |
| 2085 | + } |
| 2086 | + else { |
| 2087 | + rec.front_face = true; |
| 2088 | + } |
2035 | 2089 | return true;
|
2036 | 2090 | }
|
2037 | 2091 | else
|
|
2171 | 2225 | normal[0] = cos_theta*rec.normal[0] + sin_theta*rec.normal[2];
|
2172 | 2226 | normal[2] = -sin_theta*rec.normal[0] + cos_theta*rec.normal[2];
|
2173 | 2227 | rec.p = p;
|
2174 |
| - rec.normal = normal; |
| 2228 | + if (dot(rotated_r.direction(), normal) > 0.0) { |
| 2229 | + rec.normal = -normal; |
| 2230 | + rec.front_face = false; |
| 2231 | + } |
| 2232 | + else { |
| 2233 | + rec.normal = normal; |
| 2234 | + rec.front_face = true; |
| 2235 | + } |
2175 | 2236 | return true;
|
2176 | 2237 | }
|
2177 | 2238 | else
|
|
2323 | 2384 | }
|
2324 | 2385 |
|
2325 | 2386 | rec.normal = vec3(1,0,0); // arbitrary
|
| 2387 | + rec.front_face = true; // also arbitrary |
2326 | 2388 | rec.mat_ptr = phase_function;
|
2327 | 2389 | return true;
|
2328 | 2390 | }
|
|
2351 | 2413 | material *green = new lambertian(new constant_texture(vec3(0.12, 0.45, 0.15)));
|
2352 | 2414 | material *light = new diffuse_light(new constant_texture(vec3(7, 7, 7)));
|
2353 | 2415 |
|
2354 |
| - list[i++] = new flip_normals(new yz_rect(0, 555, 0, 555, 555, green)); |
| 2416 | + list[i++] = new flip_face(new yz_rect(0, 555, 0, 555, 555, green)); |
2355 | 2417 | list[i++] = new yz_rect(0, 555, 0, 555, 0, red);
|
2356 | 2418 | list[i++] = new xz_rect(113, 443, 127, 432, 554, light);
|
2357 |
| - list[i++] = new flip_normals(new xz_rect(0, 555, 0, 555, 555, white)); |
| 2419 | + list[i++] = new flip_face(new xz_rect(0, 555, 0, 555, 555, white)); |
2358 | 2420 | list[i++] = new xz_rect(0, 555, 0, 555, 0, white);
|
2359 |
| - list[i++] = new flip_normals(new xy_rect(0, 555, 0, 555, 555, white)); |
| 2421 | + list[i++] = new flip_face(new xy_rect(0, 555, 0, 555, 555, white)); |
2360 | 2422 |
|
2361 | 2423 | hittable *b1 = new translate(
|
2362 | 2424 | new rotate_y(new box(vec3(0, 0, 0), vec3(165, 165, 165), white), -18),
|
|
0 commit comments