|
3 | 3 |
|
4 | 4 |
|
5 | 5 |
|
6 |
| - *Ray Tracing: The Rest of Your Life** |
| 6 | + **Ray Tracing: The Rest of Your Life** |
7 | 7 | Peter Shirley
|
8 | 8 | edited by Steve Hollasch and Trevor David Black
|
9 | 9 | <br>
|
|
732 | 732 | linear mixtures of them to form mixture densities that are also PDFs. For example, the simplest
|
733 | 733 | would be:
|
734 | 734 |
|
735 |
| - $$ p(direction) = \frac{1}{2}\cdotp Light(direction) + \frac{1}{2}\cdot pSurface(direction) $$ |
| 735 | + $$ p(direction) = \frac{1}{2}\cdotp \text{Light}(direction) |
| 736 | + + \frac{1}{2}\cdot \text{pSurface}(direction) $$ |
736 | 737 | </div>
|
737 | 738 |
|
738 | 739 | As long as the weights are positive and add up to one, any such mixture of PDFs is a PDF. Remember,
|
739 |
| -we can use any PDF: _all PDF eventually converge to the correct answer_. So, the game is to figure |
| 740 | +we can use any PDF: _all PDFs eventually converge to the correct answer_. So, the game is to figure |
740 | 741 | out how to make the PDF larger where the product $s(direction) \cdot color(direction)$ is large. For
|
741 | 742 | diffuse surfaces, this is mainly a matter of guessing where $color(direction)$ is high.
|
742 | 743 |
|
|
1091 | 1092 |
|
1092 | 1093 | <div class='together'>
|
1093 | 1094 | Now for integration with importance sampling. $p(direction) = \frac{1}{2\pi}$, so we average $f/p$
|
1094 |
| -which is $\cos^3(\theta) / (1/(2 \pi))$, and we can test this: |
| 1095 | +which is $\cos^3(\theta) / (1/2\pi)$, and we can test this: |
1095 | 1096 |
|
1096 | 1097 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1097 | 1098 | int main() {
|
|
1188 | 1189 | long as the camera and scene are described in the same coordinate system, all is well.
|
1189 | 1190 |
|
1190 | 1191 | <div class='together'>
|
1191 |
| -Suppose we have an origin $\mathbf{o}$ and cartesian unit vectors $\vec{\mathbf{x}}$, |
1192 |
| -$\vec{\mathbf{y}}$, and $\vec{\mathbf{z}}$. When we say a location is (3, -2, 7), we really are |
1193 |
| -saying: |
| 1192 | +Suppose we have an origin $\mathbf{O}$ and cartesian unit vectors $\mathbf{x}$, $\mathbf{y}$, and |
| 1193 | +$\mathbf{z}$. When we say a location is (3,-2,7), we really are saying: |
1194 | 1194 |
|
1195 |
| - $$ \text{Location is } \mathbf{o} + 3\vec{\mathbf{x}} - 2\vec{\mathbf{y}} + 7\vec{\mathbf{z}} $$ |
| 1195 | + $$ \text{Location is } \mathbf{O} + 3\mathbf{x} - 2\mathbf{y} + 7\mathbf{z} $$ |
1196 | 1196 | </div>
|
1197 | 1197 |
|
1198 | 1198 | <div class='together'>
|
1199 |
| -If we want to measure coordinates in another coordinate system with origin $\mathbf{o}'$ and basis |
1200 |
| -vectors $\vec{\mathbf{u}}$, $\vec{\mathbf{v}}$, and $\vec{\mathbf{w}}$, we can just find the numbers |
1201 |
| -$(u, v, w)$ such that: |
| 1199 | +If we want to measure coordinates in another coordinate system with origin $\mathbf{O}'$ and basis |
| 1200 | +vectors $\mathbf{u}$, $\mathbf{v}$, and $\mathbf{w}$, we can just find the numbers $(u,v,w)$ such |
| 1201 | +that: |
1202 | 1202 |
|
1203 |
| - $$ \text{Location is } \mathbf{o}' + u\vec{\mathbf{u}} + v\vec{\mathbf{v}} + w\vec{\mathbf{w}} $$ |
| 1203 | + $$ \text{Location is } \mathbf{O}' + u\mathbf{u} + v\mathbf{v} + w\mathbf{w} $$ |
1204 | 1204 | </div>
|
1205 | 1205 |
|
1206 | 1206 |
|
|
1209 | 1209 | If you take an intro graphics course, there will be a lot of time spent on coordinate systems and
|
1210 | 1210 | 4×4 coordinate transformation matrices. Pay attention, it’s important stuff in graphics! But we
|
1211 | 1211 | won’t need it. What we need to is generate random directions with a set distribution relative to
|
1212 |
| -$\vec{\mathbf{n}}$. We don’t need an origin because a direction is relative to no specified origin. |
1213 |
| -We do need two cotangent vectors that are mutually perpendicular to $\vec{\mathbf{n}}$ and to each |
1214 |
| -other. |
| 1212 | +$\mathbf{n}$. We don’t need an origin because a direction is relative to no specified origin. We do |
| 1213 | +need two cotangent vectors that are mutually perpendicular to $\mathbf{n}$ and to each other. |
1215 | 1214 |
|
1216 | 1215 | <div class='together'>
|
1217 | 1216 | Some models will come with one or more cotangent vectors. If our model has only one cotangent
|
1218 | 1217 | vector, then the process of making an ONB is a nontrivial one. Suppose we have any vector
|
1219 |
| -$\vec{\mathbf{a}}$ that is of nonzero length and not parallel to $\vec{\mathbf{n}}$. We can get |
1220 |
| -vectors $\vec{\mathbf{s}}$ and $\vec{\mathbf{t}}$ perpendicular to $\vec{\mathbf{n}}$ by using the |
1221 |
| -property of the cross product that $\vec{\mathbf{c}} \times \vec{\mathbf{d}}$ is perpendicular to |
1222 |
| -both $\vec{\mathbf{c}}$ and $\vec{\mathbf{d}}$: |
| 1218 | +$\mathbf{a}$ that is of nonzero length and not parallel to $\mathbf{n}$. We can get |
| 1219 | +vectors $\mathbf{s}$ and $\mathbf{t}$ perpendicular to $\mathbf{n}$ by using the |
| 1220 | +property of the cross product that $\mathbf{c} \times \mathbf{d}$ is perpendicular to |
| 1221 | +both $\mathbf{c}$ and $\mathbf{d}$: |
1223 | 1222 |
|
1224 |
| - $$ \vec{\mathbf{t}} = \text{unit_vector}(\vec{\mathbf{a}} \times \vec{\mathbf{n}}) $$ |
| 1223 | + $$ \mathbf{t} = \text{unit_vector}(\mathbf{a} \times \mathbf{n}) $$ |
1225 | 1224 |
|
1226 |
| - $$ \vec{\mathbf{s}} = \vec{\mathbf{t}} \times \vec{\mathbf{n}} $$ |
| 1225 | + $$ \mathbf{s} = \mathbf{t} \times \mathbf{n} $$ |
1227 | 1226 | </div>
|
1228 | 1227 |
|
1229 | 1228 | <div class='together'>
|
1230 |
| -This is all well and good, but the catch is that we may not be given an $\vec{\mathbf{a}}$ when we |
1231 |
| -load a model, and we don't have an $\vec{\mathbf{a}}$ with our existing program. If we went ahead |
1232 |
| -and picked an arbitrary $\vec{\mathbf{a}}$ to use as our initial vector we may get an |
1233 |
| -$\vec{\mathbf{a}}$ that is parallel to $\vec{\mathbf{n}}$. A common method is to use an |
1234 |
| -if-statement to determine whether $\vec{\mathbf{n}}$ is a particular axis, and if not, use that |
1235 |
| -axis. |
| 1229 | +This is all well and good, but the catch is that we may not be given an $\mathbf{a}$ when we load a |
| 1230 | +model, and we don't have an $\mathbf{a}$ with our existing program. If we went ahead and picked an |
| 1231 | +arbitrary $\mathbf{a}$ to use as our initial vector we may get an $\mathbf{a}$ that is parallel to |
| 1232 | +$\mathbf{n}$. A common method is to use an if-statement to determine whether $\mathbf{n}$ is a |
| 1233 | +particular axis, and if not, use that axis. |
1236 | 1234 |
|
1237 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1235 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ none |
1238 | 1236 | if absolute(n.x > 0.9)
|
1239 | 1237 | a ← (0, 1, 0)
|
1240 | 1238 | else
|
|
1243 | 1241 | </div>
|
1244 | 1242 |
|
1245 | 1243 | <div class='together'>
|
1246 |
| -Once we have an ONB of $\vec{\mathbf{s}}$, $\vec{\mathbf{t}}$, and $\vec{\mathbf{n}}$ and we have a |
1247 |
| -$random(x,y,z)$ relative to the Z-axis we can get the vector relative to $\vec{\mathbf{n}}$ as: |
| 1244 | +Once we have an ONB of $\mathbf{s}$, $\mathbf{t}$, and $\mathbf{n}$ and we have a $random(x,y,z)$ |
| 1245 | +relative to the Z-axis we can get the vector relative to $\mathbf{n}$ as: |
1248 | 1246 |
|
1249 |
| - $$ \text{Random vector} = x \vec{\mathbf{s}} + y \vec{\mathbf{t}} + z \vec{\mathbf{n}} $$ |
| 1247 | + $$ \text{Random vector} = x \mathbf{s} + y \mathbf{t} + z \mathbf{n} $$ |
1250 | 1248 | </div>
|
1251 | 1249 |
|
1252 | 1250 | <div class='together'>
|
|
1479 | 1477 | Mixture Densities
|
1480 | 1478 | ====================================================================================================
|
1481 | 1479 |
|
1482 |
| -<div class='together'> |
1483 | 1480 | We have used a PDF related to $\cos(\theta)$, and a PDF related to sampling the light. We would like
|
1484 | 1481 | a PDF that combines these.
|
1485 | 1482 |
|
|
1489 | 1486 | A common tool in probability is to mix the densities to form a mixture density. Any weighted average
|
1490 | 1487 | of PDFs is a PDF. For example, we could just average the two densities:
|
1491 | 1488 |
|
1492 |
| - $$ pdf\_mixture(direction) = \frac{1}{2} pdf\_reflection(direction) + |
1493 |
| - \frac{1}{2}pdf\_light(direction) |
| 1489 | + $$ \text{mixture}_\text{pdf}(direction) = \frac{1}{2} \text{reflection}_\text{pdf}(direction) |
| 1490 | + + \frac{1}{2} \text{light}_\text{pdf}(direction) |
1494 | 1491 | $$
|
1495 |
| -</div> |
1496 | 1492 |
|
1497 | 1493 | <div class='together'>
|
1498 | 1494 | How would we instrument our code to do that? There is a very important detail that makes this not
|
1499 | 1495 | quite as easy as one might expect. Choosing the random direction is simple:
|
1500 | 1496 |
|
1501 |
| - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 1497 | + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ none |
1502 | 1498 | if (random_double() < 0.5)
|
1503 |
| - Pick direction according to pdf_reflection |
| 1499 | + pick direction according to pdf_reflection |
1504 | 1500 | else
|
1505 |
| - Pick direction according to pdf_light |
| 1501 | + pick direction according to pdf_light |
1506 | 1502 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
1507 | 1503 | </div>
|
1508 | 1504 |
|
1509 |
| -But evaluating $pdf\_mixture$ is slightly more subtle. We need to evaluate both $pdf\_reflection$ |
1510 |
| -and $pdf\_light$ because there are some directions where either PDF could have generated the |
1511 |
| -direction. For example, we might generate a direction toward the light using $pdf\_reflection$. |
| 1505 | +But evaluating $\text{mixture}_\text{pdf}$ is slightly more subtle. We need to evaluate both |
| 1506 | +$\text{reflection}_\text{pdf}$ and $\text{light}_\text{pdf}$ because there are some directions where |
| 1507 | +either PDF could have generated the direction. For example, we might generate a direction toward the |
| 1508 | +light using $\text{reflection}_\text{pdf}$. |
1512 | 1509 |
|
1513 | 1510 | <div class='together'>
|
1514 | 1511 | If we step back a bit, we see that there are two functions a PDF needs to support:
|
|
1519 | 1516 | </div>
|
1520 | 1517 |
|
1521 | 1518 | <div class='together'>
|
1522 |
| -The details of how this is done under the hood varies for the $pdf\_reflection$ and the $pdf\_light$ |
1523 |
| -and the mixture density of the two of them, but that is exactly what class hierarchies were invented |
1524 |
| -for! It’s never obvious what goes in an abstract class, so my approach is to be greedy and hope a |
1525 |
| -minimal interface works, and for the PDF this implies: |
| 1519 | +The details of how this is done under the hood varies for the $\text{reflection}_\text{pdf}$ and the |
| 1520 | +$\text{light}_\text{pdf}$ and the mixture density of the two of them, but that is exactly what class |
| 1521 | +hierarchies were invented for! It’s never obvious what goes in an abstract class, so my approach is |
| 1522 | +to be greedy and hope a minimal interface works, and for the PDF this implies: |
1526 | 1523 |
|
1527 | 1524 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ C++
|
1528 | 1525 | class pdf {
|
|
1907 | 1904 | calculations.
|
1908 | 1905 |
|
1909 | 1906 | We also lack a real background function infrastructure in case we want to add an environment map or
|
1910 |
| -more interesting functional background. Some environment maps are HDR (the R/G/B components are |
1911 |
| -floats rather than 0–255 bytes usually interpreted as 0-1). Our output has been HDR all along and |
1912 |
| -we’ve just been truncating it. |
| 1907 | +more interesting functional background. Some environment maps are HDR (the RGB components are floats |
| 1908 | +rather than 0–255 bytes usually interpreted as 0-1). Our output has been HDR all along and we’ve |
| 1909 | +just been truncating it. |
1913 | 1910 |
|
1914 | 1911 | Finally, our renderer is RGB and a more physically based one -- like an automobile manufacturer
|
1915 | 1912 | might use -- would probably need to use spectral colors and maybe even polarization. For a movie
|
|
0 commit comments