A triangle is an affine combination of three points \[ \vec{X}\of{\alpha, \beta, \gamma} \;=\; \alpha\vec{A} + \beta\vec{B} + \gamma\vec{C}\]
with \(\alpha+\beta+\gamma=1\).Affine transformation preserve affine combinations
Planar projections map triangles to triangles
A point \(\vec{x} = \transpose{(x,y,z,1)}\) lies on its tangent plane, specified by \(\vec{n} = \transpose{(n_x, n_y, n_z, d)}\): \[ n_x x + n_y y + n_z z + d = 0 \quad\Leftrightarrow\quad \transpose{\vec{n}} \vec{x} = 0 \]
The same equation should be satisfied after an affine transformation \(\mat{M}\) maps \(\vec{x}\) to \(\vec{x}'\) and \(\vec{n}\) to \(\vec{n}'\) \[ 0 \;=\; \transpose{\vec{n}'} \vec{x}' \;=\; \transpose{\vec{n}'} \mat{M} \vec{x} \;=\; \transpose{\left(\transpose{\mat{M}} \vec{n}' \right)} \vec{x} \]
Comparing the two equations yields \(\vec{n}' = \mat{M}^{\mathsf{-T}} \vec{n}\)
Δx = x1-x0;
Δy = y1-y0;
d = 2*Δy - Δx;
ΔE = 2*Δy;
ΔNE = 2*(Δy - Δx);
set_pixel(x0, y0);
for (x = x0, y = y0; x < x1;)
{
if (d <= 0) { d += ΔE; ++x; }
else { d += ΔNE; ++x; ++y }
set_pixel(x, y);
}
Good: Only integer arithmetic!
So far: color/material varies per model or per vertex
Textures add visual detail without raising geometric complexity: Paste 2D images onto 3D geometry
Geometry
Texture
Textured Mesh
Images from http://www.endoxon.ch
So far: color/material varies per model or per vertex
Textures add visual detail without raising geometric complexity: Paste 2D images onto 3D geometry
Geometry
+Lighting
+Texture
Images from http://www.3drender.com/jbirn/productions.html
Images from Akenine-Möller, “Real-Time Rendering”
noperspective) or perspective (smooth) interpolation for vertex shader outputs (smooth is default)
Images from Akenine-Möller, “Real-Time Rendering”
Images from Akenine-Möller, “Real-Time Rendering”
\[ \vector{ \phi \\ \theta } \mapsto \vector{ \cos\phi \, \cos\theta \\ \sin\phi \, \cos\theta \\ \sin\theta } \]

Round to nearest integer coordinate
color = tex[6,4];
Bilinear interpolation of neighboring texture pixels
color = (1-s)*(1-t)*tex[6,3] + (1-s)*t*tex[6,4]
s*(1-t)*tex[7,3] + s*t*tex[7,4];
nearest
linear
nearest
linear
Images from Akenine-Möller, “Real-Time Rendering”

EWA filtering
bi-linear filtering
Images courtesy of Oliver Deussen

Image from Akenine-Möller, “Real-Time Rendering”


normal rendering
bump map
bump-mapped result
Coarse mesh
Diffuse map + specular map + bump map + …map
Image from TripleGangers




Many thanks to Hartmut Schirmacher for providing aligned textures and initial WebGL code!


Shadow computation is very similar to visibility determination
\[ \begin{eqnarray*} I(\vec{p},\vec{n},\vec{v}) &=& I_{\text{ambient}} \\[2mm] &+& \sum_{i} \text{shadow}(\vec{p},\vec{l}_i) \cdot \left( I_{\text{diffuse}}(\vec{p},\vec{n},\vec{l}_i) + I_{\text{specular}}(\vec{p},\vec{n},\vec{v},\vec{l}_i) \right) \\ \\ \text{with} && \text{shadow}(\vec{p},\vec{l}_i) \;=\; \left\{\begin{array}{ll} 1 & \vec{l}_i\text{ is visible from } \vec{p},\\ 0 & \vec{l}_i\text{ is blocked from } \vec{p} \end{array} \right. \end{eqnarray*} \]

\(\Rightarrow\) Apply standard visibility techniques for shadows:
z-buffer \(\rightarrow\) shadow map
Image from Akenine-Möller, “Real-Time Rendering”
Scene without shadows
z-buffer of light’s view
Scene with shadows
Seen from light’s view
Pixels in shadow
Images from Wikipedia



