|
137 | 137 | Opening the output file (in `ToyViewer` on my Mac, but try it in your favorite viewer and Google
|
138 | 138 | “ppm viewer” if your viewer doesn’t support it) shows this result:
|
139 | 139 |
|
140 |
| - <div class="render"> |
141 |
| - |
142 |
| -  |
143 |
| - |
144 |
| - </div> |
| 140 | +  |
145 | 141 |
|
146 | 142 | </div>
|
147 | 143 |
|
|
234 | 230 | #ifndef VEC3_H
|
235 | 231 | #define VEC3_H
|
236 | 232 |
|
| 233 | + #include <cmath> |
237 | 234 | #include <iostream>
|
238 | 235 |
|
| 236 | + using std::sqrt; |
| 237 | + |
239 | 238 | class vec3 {
|
240 | 239 | public:
|
241 | 240 | vec3() : e{0,0,0} {}
|
|
537 | 536 |
|
538 | 537 | with $t$ going from zero to one. In our case this produces:
|
539 | 538 |
|
540 |
| - <div class="render"> |
541 |
| - |
542 |
| -  |
543 |
| - |
544 |
| - </div> |
| 539 | +  |
545 | 541 |
|
546 | 542 | </div>
|
547 | 543 |
|
|
655 | 651 | <div class='together'>
|
656 | 652 | What we get is this:
|
657 | 653 |
|
658 |
| - <div class="render"> |
659 |
| - |
660 |
| -  |
661 |
| - |
662 |
| - </div> |
| 654 | +  |
663 | 655 |
|
664 | 656 | </div>
|
665 | 657 |
|
|
735 | 727 | <div class='together'>
|
736 | 728 | And that yields this picture:
|
737 | 729 |
|
738 |
| - <div class="render"> |
739 |
| - |
740 |
| -  |
741 |
| - |
742 |
| - </div> |
| 730 | +  |
743 | 731 |
|
744 | 732 | </div>
|
745 | 733 |
|
|
898 | 886 | the sphere, the normal will point outward, but if the ray is inside the sphere, the normal will
|
899 | 887 | point inward.
|
900 | 888 |
|
901 |
| - ![Figure [normal-directions]: Possible directions for sphere surface-normal geometry](../images/fig.normal-possibilities.jpg) |
| 889 | + ![Figure [normal-directions]: Possible directions for sphere surface-normal geometry |
| 890 | + ](../images/fig.normal-possibilities.jpg) |
902 | 891 |
|
903 | 892 | </div>
|
904 | 893 |
|
|
1155 | 1144 |
|
1156 | 1145 | using std::shared_ptr;
|
1157 | 1146 | using std::make_shared;
|
| 1147 | + using std::sqrt; |
1158 | 1148 |
|
1159 | 1149 | // Constants
|
1160 | 1150 |
|
|
1167 | 1157 | return degrees * pi / 180;
|
1168 | 1158 | }
|
1169 | 1159 |
|
1170 |
| - inline double ffmin(double a, double b) { return a <= b ? a : b; } |
1171 |
| - inline double ffmax(double a, double b) { return a >= b ? a : b; } |
1172 |
| - |
1173 | 1160 | // Common Headers
|
1174 | 1161 |
|
1175 | 1162 | #include "ray.h"
|
|
1252 | 1239 | This yields a picture that is really just a visualization of where the spheres are along with their
|
1253 | 1240 | surface normal. This is often a great way to look at your model for flaws and characteristics.
|
1254 | 1241 |
|
1255 |
| - <div class="render"> |
1256 |
| - |
1257 |
| -  |
1258 |
| - |
1259 |
| - </div> |
| 1242 | +  |
1260 | 1244 |
|
1261 | 1245 | </div>
|
1262 | 1246 |
|
|
1447 | 1431 | Zooming into the image that is produced, the big change is in edge pixels that are part background
|
1448 | 1432 | and part foreground:
|
1449 | 1433 |
|
1450 |
| - <div class="render"> |
1451 |
| - |
1452 |
| -  |
1453 |
| - |
1454 |
| - </div> |
| 1434 | +  |
1455 | 1435 |
|
1456 | 1436 | </div>
|
1457 | 1437 |
|
|
1626 | 1606 | <div class='together'>
|
1627 | 1607 | This gives us:
|
1628 | 1608 |
|
1629 |
| - <div class="render"> |
1630 |
| - |
1631 |
| -  |
1632 |
| - |
1633 |
| - </div> |
| 1609 | +  |
1634 | 1610 |
|
1635 | 1611 | </div>
|
1636 | 1612 |
|
|
1674 | 1650 | <div class='together'>
|
1675 | 1651 | That yields light grey, as we desire:
|
1676 | 1652 |
|
1677 |
| - <div class="render"> |
1678 |
| - |
1679 |
| -  |
1680 |
| - |
1681 |
| - </div> |
| 1653 | +  |
1682 | 1654 |
|
1683 | 1655 | </div>
|
1684 | 1656 |
|
|
1758 | 1730 | <div class='together'>
|
1759 | 1731 | After rendering we get a similar image:
|
1760 | 1732 |
|
1761 |
| - <div class="render"> |
1762 |
| - |
1763 |
| -  |
1764 |
| - |
1765 |
| - </div> |
| 1733 | +  |
1766 | 1734 |
|
1767 | 1735 | It's hard to tell the difference between these two diffuse methods, given that our scene of two
|
1768 | 1736 | spheres is so simple, but you should be able to notice two important visual differences:
|
|
1841 | 1809 |
|
1842 | 1810 | Gives us the following image:
|
1843 | 1811 |
|
1844 |
| - <div class="render"> |
1845 |
| - |
1846 |
| -  |
1847 |
| - |
1848 |
| - </div> |
| 1812 | +  |
1849 | 1814 |
|
1850 | 1815 | </div>
|
1851 | 1816 |
|
|
2168 | 2133 | <div class='together'>
|
2169 | 2134 | Which gives:
|
2170 | 2135 |
|
2171 |
| - <div class="render"> |
2172 |
| - |
2173 |
| -  |
2174 |
| - |
2175 |
| - </div> |
| 2136 | +  |
2176 | 2137 |
|
2177 | 2138 | </div>
|
2178 | 2139 |
|
|
2225 | 2186 | <div class='together'>
|
2226 | 2187 | We can try that out by adding fuzziness 0.3 and 1.0 to the metals:
|
2227 | 2188 |
|
2228 |
| - <div class="render"> |
2229 |
| - |
2230 |
| -  |
2231 |
| - |
2232 |
| - </div> |
| 2189 | +  |
2233 | 2190 |
|
2234 | 2191 | </div>
|
2235 | 2192 |
|
|
2250 | 2207 | there is a refraction ray at all. For this project, I tried to put two glass balls in our scene, and
|
2251 | 2208 | I got this (I have not told you how to do this right or wrong yet, but soon!):
|
2252 | 2209 |
|
2253 |
| - <div class="render"> |
2254 |
| - |
2255 |
| -  |
2256 |
| - |
2257 |
| - </div> |
| 2210 | +  |
2258 | 2211 |
|
2259 | 2212 | </div>
|
2260 | 2213 |
|
|
2358 | 2311 |
|
2359 | 2312 | This gives us the following result:
|
2360 | 2313 |
|
2361 |
| -<div class="render"> |
2362 |
| - |
2363 |
| -  |
2364 |
| - |
2365 |
| -</div> |
| 2314 | +  |
2366 | 2315 |
|
2367 | 2316 |
|
2368 | 2317 | Total Internal Reflection
|
|
2413 | 2362 | $$ \cos\theta = \mathbf{R} \cdot \mathbf{n} $$
|
2414 | 2363 |
|
2415 | 2364 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
2416 |
| - double cos_theta = ffmin(dot(-unit_direction, rec.normal), 1.0); |
| 2365 | + double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0); |
2417 | 2366 | double sin_theta = sqrt(1.0 - cos_theta*cos_theta);
|
2418 | 2367 | if(etai_over_etat * sin_theta > 1.0) {
|
2419 | 2368 | // Must Reflect
|
|
2444 | 2393 |
|
2445 | 2394 | vec3 unit_direction = unit_vector(r_in.direction());
|
2446 | 2395 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++ highlight
|
2447 |
| - double cos_theta = ffmin(dot(-unit_direction, rec.normal), 1.0); |
| 2396 | + double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0); |
2448 | 2397 | double sin_theta = sqrt(1.0 - cos_theta*cos_theta);
|
2449 | 2398 | if (etai_over_etat * sin_theta > 1.0 ) {
|
2450 | 2399 | vec3 reflected = reflect(unit_direction, rec.normal);
|
|
2483 | 2432 |
|
2484 | 2433 | We get:
|
2485 | 2434 |
|
2486 |
| - <div class="render"> |
2487 |
| - |
2488 |
| -  |
2489 |
| - |
2490 |
| - </div> |
| 2435 | +  |
2491 | 2436 |
|
2492 | 2437 | </div>
|
2493 | 2438 |
|
|
2523 | 2468 | double etai_over_etat = (rec.front_face) ? (1.0 / ref_idx) : (ref_idx);
|
2524 | 2469 |
|
2525 | 2470 | vec3 unit_direction = unit_vector(r_in.direction());
|
2526 |
| - double cos_theta = ffmin(dot(-unit_direction, rec.normal), 1.0); |
| 2471 | + double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0); |
2527 | 2472 | double sin_theta = sqrt(1.0 - cos_theta*cos_theta);
|
2528 | 2473 | if (etai_over_etat * sin_theta > 1.0 ) {
|
2529 | 2474 | vec3 reflected = reflect(unit_direction, rec.normal);
|
|
2572 | 2517 | <div class='together'>
|
2573 | 2518 | This gives:
|
2574 | 2519 |
|
2575 |
| - <div class="render"> |
2576 |
| - |
2577 |
| -  |
2578 |
| - |
2579 |
| - </div> |
| 2520 | +  |
2580 | 2521 |
|
2581 | 2522 | </div>
|
2582 | 2523 |
|
|
2653 | 2594 |
|
2654 | 2595 | gives:
|
2655 | 2596 |
|
2656 |
| - <div class="render"> |
2657 |
| - |
2658 |
| -  |
2659 |
| - |
2660 |
| - </div> |
| 2597 | +  |
2661 | 2598 |
|
2662 | 2599 | </div>
|
2663 | 2600 |
|
|
2741 | 2678 |
|
2742 | 2679 | to get:
|
2743 | 2680 |
|
2744 |
| - <div class="render"> |
2745 |
| - |
2746 |
| -  |
2747 |
| - |
2748 |
| - </div> |
| 2681 | +  |
2749 | 2682 |
|
2750 | 2683 | And we can change field of view:
|
2751 | 2684 |
|
|
2756 | 2689 |
|
2757 | 2690 | to get:
|
2758 | 2691 |
|
2759 |
| - <div class="render"> |
2760 |
| - |
2761 |
| -  |
2762 |
| - |
2763 |
| - </div> |
| 2692 | +  |
2764 | 2693 |
|
2765 | 2694 | </div>
|
2766 | 2695 |
|
|
2902 | 2831 |
|
2903 | 2832 | We get:
|
2904 | 2833 |
|
2905 |
| - <div class="render"> |
2906 |
| - |
2907 |
| -  |
2908 |
| - |
2909 |
| - </div> |
| 2834 | +  |
2910 | 2835 |
|
2911 | 2836 | </div>
|
2912 | 2837 |
|
|
2983 | 2908 | <div class='together'>
|
2984 | 2909 | This gives:
|
2985 | 2910 |
|
2986 |
| - <div class="render"> |
2987 |
| - |
2988 | 2911 | 
|
2989 | 2912 |
|
2990 |
| - </div> |
2991 | 2913 | </div>
|
2992 | 2914 |
|
2993 | 2915 | An interesting thing you might note is the glass balls don’t really have shadows which makes them
|
|
0 commit comments