Computer graphics in Game development
Ivan Belyavtsev
22.01.2021
Homogeneous coordinates - cartesian coordinates + 1 dimension
\[ (X, Y, Z) => (x, y, z, w) \]
\[ X = x/w, Y = y/w, Z = z/w \] [1]
\[T(\overrightarrow{x}) = A\overrightarrow{x}\]
where \[A = \left[\begin{array}{cccc} x1 & x2 & x3 & x4 \\ y1 & y2 & y3 & y4 \\ z1 & z2 & z3 & z4 \\ w1 & w2 & w3 & w4 \end{array}\right]\] [2]
\(\overrightarrow{tr}\) - vector of translation
\[T = \left[\begin{array}{cccc} 1 & 0 & 0 & tr.x \\ 0 & 1 & 0 & tr.y \\ 0 & 0 & 1 & tr.z \\ 0 & 0 & 0 & 1 \end{array}\right]\] [2]
\(\overrightarrow{scale}\) - vector of scaling
\[S = \left[\begin{array}{cccc} scale.x & 0 & 0 & 0 \\ 0 & scale.y & 0 & 0 \\ 0 & 0 & scale.z & 0 \\ 0 & 0 & 0 & 1 \end{array}\right]\] [2]
\(\alpha\) - angle of rotation around axis X
\[R_x = \left[\begin{array}{cccc} 1 & 0 & 0 & 0 \\ 0 & cos(\alpha) & -sin(\alpha) & 0 \\ 0 & sin(\alpha) & cos(\alpha) & 0 \\ 0 & 0 & 0 & 1 \end{array}\right]\] [2]
\(\beta\) - angle of rotation around axis Y
\[R_y = \left[\begin{array}{cccc} cos(\beta) & 0 & sin(\beta) & 0 \\ 0 & 1 & 0 & 0 \\ -sin(\beta) & 0 & cos(\beta) & 0 \\ 0 & 0 & 0 & 1 \end{array}\right]\] [2]
\(\gamma\) - angle of rotation around axis Z
\[R_z = \left[\begin{array}{cccc} cos(\gamma) & -sin(\gamma) & 0 & 0 \\ sin(\gamma) & cos(\gamma) & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{array}\right]\] [2]
\[World=TRS\]
First scale, then rotate, then translate
\[ \overrightarrow{z_{axis}} = \frac{\overrightarrow{eye} - \overrightarrow{at}}{||\overrightarrow{eye} - \overrightarrow{at}||} \] \[ \overrightarrow{x_{axis}} = \frac{\overrightarrow{up} \times \overrightarrow{z_{axis}}}{||\overrightarrow{up} \times \overrightarrow{z_{axis}}||}\] \[ \overrightarrow{y_{axis}} = \overrightarrow{z_{axis}} \times \overrightarrow{x_{axis}} \]
\[View = \left[\begin{array}{cccc} x_{axis}.x & y_{axis}.x & z_{axis}.x & 0 \\ x_{axis}.y & y_{axis}.y & z_{axis}.y & 0 \\ x_{axis}.z & y_{axis}.z & z_{axis}.z & 0 \\ -\overrightarrow{x_{axis}} \cdot \overrightarrow{eye} & -\overrightarrow{y_{axis}} \cdot \overrightarrow{eye} & -\overrightarrow{z_{axis}} \cdot \overrightarrow{eye} & 1 \end{array}\right]\]
Look-at target could be replaced as camera location vector + unit camera direction vector.
Unit direction vector could be set in spherical coordinates.
\[Proj = \left[\begin{array}{cccc} \frac{1}{tan(fov/2)\cdot ar} & 0 & 0 & 0 \\ 0 & \frac{1}{tan(fov/2)} & 0 & 0 \\ 0 & 0 & \frac{Z_f}{Z_f-Z_n} & -1 \\ 0 & 0 & \frac{Z_n\cdot Z_f}{Z_n-Z_f} & 0 \end{array}\right]\]
\[Viewport = \left[\begin{array}{cccc} width & 0 & 0 & 0 \\ 0 & -height & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 1 \end{array}\right]\]
\[\vec{X} = Viewport \cdot Proj \cdot View \cdot World \cdot \vec{x}\]
Remember about left-handed and right-handed operations!
Check correctness of each matrix, e.x. in DirecX documentation [3]