
Use Whitted-style ray tracing algorithm to generate image
for each pixel {
determine viewing direction
intersect ray with scene
compute illumination
store result in pixel
}
for each pixel {
determine viewing direction <==
intersect ray with scene
compute illumination
store result in pixel
}
a painter tracing objects on a canvas in front

![]() |
![]() |
![]() |
struct Camera {
frame Frame
size Size2
distance f64
// ...
}
|
Note
NOTE: \(\hat\z\) points backwards; \(-\hat\z\) points forwards

Note
All visible points within a truncated pyramid
for each pixel, create ray from camera center to the pixel center
|
|
struct Camera {
// ...
resolution Size2i
// ...
}
|
convert pixel coordinates \((x,y)\) to image plane coordinates \((u,v)\)
|
\[ u = \frac{x + 0.5}{w} \] \[ v = 1 - \frac{y + 0.5}{h} \] |
|
compute point \(\point{q}\) at center of current pixel \((x,y)\)

computer ray that starts at camera focal point \(\point{o}\) and passes through pixel center \(\point{q}\)

\[\begin{array}{rcl} \tilde\q(u,v) & = & \tilde\o + (u-0.5) w \hat\x + (v-0.5) h \hat\y - d \hat\z \\ & = & 0 + w (u-0.5) (1,0,0)\, + \\ & & +\, h (v-0.5) (0,1,0) - d (0,0,1) \\ & = & (w \cdot (u-0.5), h \cdot (v-0.5), -d) \\ \tilde\p(t) & = & \tilde\e + t \hat\d \\ & = & \tilde\o + t (\tilde\q - \tilde\o) / || \tilde\q - \tilde\o || = t \hat\q \end{array} \]
Note
Last line (\(t\hat\q\)) abuses notation
for each pixel {
determine viewing direction
intersect ray with scene <==
compute illumination
store result in pixel
}
compute intersection of ray and shapes in scene
struct Surface {
frame Frame // position and orientation of surface
shape Shape // enum: sphere, plane, triangle, etc.
size f64 // radius of sphere
}
| point on a ray: | \(\tilde\p(t) = \tilde\e + t\hat\d\) |
| point on a sphere: | \(\vlen{\tilde\p(t)-\tilde\c} = r\) |
| by substitution: | \(\vlen{\tilde\e + t\hat\d - \tilde\c} = r\) |

| algebraic equation: | \(a t^2 + b t + c = 0\) |
| with: | \(a = \vlen{\hat\d}^2\) |
| \(b=2 \hat\d \* (\tilde\e-\tilde\c)\) | |
| \(c = \vlen{\tilde\e-\tilde\c}^2 - r^2\) | |
| solve for \(t\): | \(t_{\pm} = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}\) |

\[t_{\pm} = \frac{-b \pm \sqrt{d}}{2a}\,,\quad d=b^2-4ac\]
discriminant \(d\): \(d < 0\) ⇒ no hit; \(d = 0\) ⇒ one hit, \(d > 0\) ⇒ two hits
pick smallest \(t\) such that \(t \in ( t_{min}, t_{max} )\)


shading frame \(\frame{f} = \{ \point{o}, \direction{x}, \direction{y}, \direction{z} \}\)
where
attributes (ex: color or uv) can be interpolated at \(\point{p}(t)\) using \(\theta\), \(\phi\)
\[ u = \frac{\phi}{2\pi} + 0.5 \qquad v = \frac{\theta}{\pi} \]
| point on a ray: | \(\tilde\p(t) = \tilde\e + t\hat\d\) |
| point on a plane: | \((\tilde\p(t)-\tilde\c) \* \hat\n = 0\) |
| by substitution: | \( (\tilde\e + t\hat\d -\tilde\c) \* \hat\n = 0 \) |

one solution for \(\hat\d \* \hat\n \neq 0\), no/infinite solutions otherwise
\[t = \frac{(\tilde\c - \tilde\e) \* \hat\n}{\hat\d \* \hat\n}\]
check that \(t \in ( t_{min}, t_{max} )\)


shading frame \(\frame{f} = \{ \point{o}, \direction{x}, \direction{y}, \direction{z} \}\)
Ray-Disk intersection uses Ray-Plane intersection with additional condition

Ray-Quad intersection uses Ray-Plane intersection with additional condition

to handle rotated quad, compute distance of \(\point{p}(t)\) from origin in the local frame (i.e., transform \(\point{p}(t)\) to local frame, \(\point{p}'(t)\))
attributes (ex: color or uv) can be interpolated at \(\point{p}(t)\) using \(\point{p}'(t)\)
\[ u = 0.5 + \frac{p_x'}{2r} \qquad v = 0.5 + \frac{p_y'}{2 r} \]
| point on ray: | \(\tilde\p(t) = \tilde\e + t\hat\d\) |
| point on triangle: | \(\tilde\p(\alpha,\beta) = \alpha(\tilde\a-\tilde\c) + \beta(\tilde\b-\tilde\c) + \tilde\c\) |
| by substitution: | \(\tilde\e + t\hat\d = \alpha(\tilde\a-\tilde\c) + \beta(\tilde\b-\tilde\c) + \tilde\c\) |

\[ \tilde\e + t\hat\d = \alpha(\tilde\a-\tilde\c) + \beta(\tilde\b-\tilde\c) + \tilde\c \rightarrow \]
\[ \alpha(\tilde\a-\tilde\c) + \beta(\tilde\b-\tilde\c) - t\hat\d = \tilde\e - \tilde\c \rightarrow \]
\[ \alpha\a' + \beta\b' - t\hat\d = \e' \rightarrow \]
\[ \mat{{-\hat\d} & \a' & \b'} \mat{ t \\ \alpha \\ \beta } = \e' \]
use Cramer's rule
\[ t = \dfrac{\matdet{\e' & \a' & \b'}}{\matdet{{-\hat\d} & \a' & \b'}} = \dfrac{(\e' \xx \a') \* \b'}{(\hat\d \xx \b') \* \a'} \]
\[ \alpha = \dfrac{\matdet{{-\hat\d} & \e' & \b'}}{\matdet{{-\hat\d} & \a' & \b'}} = \dfrac{(\hat\d \xx \b') \* \e'}{(\hat\d \xx \b') \* \a'} \]
\[ \beta = \dfrac{\matdet{{-\hat\d} & \a' & \e'}}{\matdet{{-\hat\d} & \a' & \b'}} = \dfrac{(\e' \xx \a') \* \hat\d}{(\hat\d \xx \b') \* \a'} \]
test for
\[ t \in (t_{min},t_{max}), \,\,\,\, \alpha \ge 0, \,\,\,\, \beta \ge 0, \,\,\,\, \alpha + \beta \le 1 \]

shading frame \(\frame{f} = \{ \point{o}, \direction{x}, \direction{y}, \direction{z} \}\)
vertex attributes (ex: color or uv) can be interpolated at \(\point{p}(t)\) using \(\alpha\), \(\beta\), \(\gamma\) as linear weights
\[ c_p = \alpha c_a + \beta c_b + \gamma c_c \]


maxDistance = infinity
hit = null
foreach surface s {
intersection = s.intersect(ray)
if(intersection.hit) {
if(intersection.distance < maxDistance) {
hit = s
maxDistance = intersection.distance
}
}
}
