光栅化渲染-8-正交投影矩阵

projection

  正交投影和透视投影的对比图,正交投影可以更好的保持原始物体的比例,透视投影则具有更好的3D真实感。

正交投影矩阵

  如图(Figure 1),正交投影的效果从空间中来看,是把相机坐标系下的边界盒压缩成了立方体

figure1

Figure 1

  与透视投影的视棱台不同,正交投影最开始的空间为长方体的边界盒。

  正交投影矩阵的构造方式与透视投影矩阵类似,同样假设成像平面坐标系的 $x$ 坐标范围为 $[l, r]$,$y$ 坐标范围为 $[b, t]$,近剪切平面和远剪切平面分别为 $n, f$。
  先考虑 $x$ ,由 $l<=x<=r$,可得 $0<=x-l<=r-l$,各项同时除以 $(r-l)$:

$$
0 <= \cfrac{x-l}{r-l} <= 1
$$

  公式各项同时乘以 $2$ 再减去 $1$:

$$
\left[
\begin{matrix}
-1 <= 2\cfrac{x-l}{r-l} - 1 <= 1 \\
-1 <= \cfrac{2x}{r-l} - \cfrac{r+l}{r-l} <= 1
\end{matrix}
\right]
$$

  于是我们就可以得到 $x$ 的转换公式:

$$
x^\prime = \cfrac{2x}{r-l} - \cfrac{r+l}{r-l}
$$

  用矩阵形式表示为:

$$
\left[
\begin{matrix}
\cfrac{2}{r-l} & 0 & 0 & -\cfrac{r+l}{r-l} \\
0 & 1 & 0 & 0 \\
0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1
\end{matrix}
\right]
$$

  $y$ 坐标的转换公式类似:

$$
y^\prime = \cfrac{2y}{t-b} - \cfrac{t+b}{t-b}
$$

  矩阵此时变为:

$$
\left[
\begin{matrix}
\cfrac{2}{r-l} & 0 & 0 & -\cfrac{r+l}{r-l} \\
0 & \cfrac{2}{t-b} & 0 & - \cfrac{t+b}{t-b} \\
0 & 0 & 1 & 0 \\
0 & 0 & 0 & 1
\end{matrix}
\right]
$$

  接下来考虑 $z$, 由 $n <= -z <= f$,可得 $0 <= -z-n <= f-n$,各项同时除以 $(f-n)$:

$$
0 <= \cfrac{-z-n}{f-n} <= 1
$$

  公式各项同时乘以 $2$ 再减去 $1$:

$$
\begin{align}
-1 <= 2\cfrac{-z-n}{f-n} - 1 <= 1 \\
-1 <= \cfrac{-2z}{f-n} - \cfrac{f+n}{f-n} <= 1
\end{align}
$$

  由此可以得到完整的正交投影矩阵:

$$
\left[
\begin{matrix}
\cfrac{2}{r-l} & 0 & 0 & -\cfrac{r+l}{r-l} \\
0 & \cfrac{2}{t-b} & 0 & - \cfrac{t+b}{t-b} \\
0 & 0 & \cfrac{-2}{f-n} & -\cfrac{f+n}{f-n} \\
0 & 0 & 0 & 1
\end{matrix}
\right]
$$

参数计算

  关于如何计算 left,right,top,bottom 这几个参数,首先要计算出边界盒的大小,统计出场景中物体的最大 $x$ 坐标maxX和 最大的 $y$ 坐标maxY
  取top = max(maxX, maxY),之后按比例 aspect ratio 来设置 left = aspectRatio * top,再根据对称可以得到 bottom = -top, right = -left

参考链接

Scratchapixel-What Are Projection Matrices and Where/Why Are They Used
Scratchapixel-The OpenGL Orthographic Projection Matrix