详细的世界坐标转屏幕坐标及投影矩阵的推导

投影矩阵网上推导一大堆,怎么构建矩阵,怎么运用透视除法等都有说,但说清楚为什么这样做的貌似不多。我现在尝试用矩阵乘法的本质去说明投影矩阵是怎么推导的。

以下向量统一用列向量表示法。

1.坐标转换 

坐标的表达形式(Fundamentals of Computer Graphics, 4th page 135)

详细的世界坐标转屏幕坐标及投影矩阵的推导_第1张图片

看上图,p在世界坐标系下的坐标值有两种表示法:

p=o+x_{p}x+y_{p}y           

 p=e+u_{p}u+v_{p}v  

其中:

(x_{p},y_{p})=(2.5,0.9)

(u_{p},v_{p})=(0.5,-0.7)

u,v是e坐标系下的标准正交基。

从图中可以看到,p在o坐标系下的坐标是(2.5,0.9),在e坐标系下是(0.5,-0.7)。

但按上面两个公式,算出来的值都是(2.5,0.9)。

我们把e下的方程化为矩阵:

从矩阵可以看出(x,y)->(u,v)的转换关系。如下式:

那么,e坐标系下的坐标可由下式求的:

\begin{bmatrix} u_{p}\\ v_{p}\\ 1 \end{bmatrix}= {\begin{bmatrix} u &v &e \\ 0 & 0& 1 \end{bmatrix}}^{-1}p_{xy}

由于[u v]是正交矩阵,所以有:

\begin{bmatrix} u &v \end{bmatrix}^{-1} =\begin{bmatrix} u &v \end{bmatrix}^{t} =\begin{bmatrix} u^{t}\\ v^{t} \end{bmatrix}

\begin{bmatrix} u_{p}\\ v_{p}\\ 1 \end{bmatrix}= \begin{bmatrix} x_{u} &y_{u} &0 \\ x_{v} & y_{v} & 0\\ 0 &0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 &-x_{e} \\ 0 & 1 &-y_{e} \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x_{p}\\ y_{p}\\ 1 \end{bmatrix}

说了这么多,目的是为了引出下面的推导,世界坐标转到摄像机空间坐标

上式可写为:

\begin{bmatrix} u_{p}\\ v_{p}\\ 1 \end{bmatrix}= \begin{bmatrix} u^t &0 \\ v^t & 0\\ 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 &-x_{e} \\ 0 & 1 &-y_{e} \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} x_{p}\\ y_{p}\\ 1 \end{bmatrix}

2.摄像机矩阵推导

先明确一点:这里说的摄像机矩阵是指世界空间到摄像机的矩阵

摄像机空间的三个基分别是向量right,up,look,世界空间中的位置是P。以R表示摄像机right向量,U表示up向量,V表示look向量,我们的目的是把R,U,V三个向量分别转换到x,y,z向量。

由于这个向量比较难转换,我们换种思路,把x,y,z轴转到RUV的矩阵是:

R_{view}^{-1} = \begin{bmatrix} R_{x} & U_{x} & V_{x} & 0\\R_{y} & U_{y} & V_{y} & 0\\ R_{z} & U_{z} & V_{z} & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}

由于该矩阵是正交矩阵,那么有

$$R_{view} = (R_{view}^{-1})^{t} = \begin{bmatrix} R^t & 0\\ U^t & 0\\ V^t & 0\\ 0 & 1 \end{bmatrix} =\begin{bmatrix} R_{x} & R_{y} & R_{z} & 0\\U_{x} & U_{y} & U_{z} & 0\\ V_{x} & V_{y} & V_{z} & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \tag{1} $$

回想一下,在空间中绕一点P旋转,是不是,可以看成先把P移到原点,然后旋转,再移动回P点上。

而摄像机空间,是把摄像机的坐标移动到原点,再把各个轴旋转到xyz轴上。

假设摄像机世界坐标是P,矩阵如下:

$$T_{view} = \begin{bmatrix} 1 & 0 & 0 & -P_{x}\\ 0 & 1 & 0 & -P_{y}\\ 0 & 0 & 1 &-P_{z} \\0 &0 &0 & 1 \end{bmatrix} \tag{1} $$

把两个矩阵相乘得到最后的lookup矩阵C:

C= R_{view}\times T_{view} = $$ $$ $$ \begin{bmatrix} R_{x} & R_{y} & R_{z} & 0\\U_{x} & U_{y} & U_{z} & 0\\ V_{x} & V_{y} & V_{z} & 0\\ 0 & 0 & 0 & 1 \end{bmatrix} \tag{1} \quad \times \quad \begin{bmatrix} 1 & 0 & 0 & -P_{x}\\ 0 & 1 & 0 & -P_{y}\\ 0 & 0 & 1 &-P_{z} \\0 &0 &0 & 1 \end{bmatrix} \tag{1} \tag{1} $$\quad=\quad $$ \begin{bmatrix} R_{x} & R_{y} & R_{z} & -P\cdot R\\U_{x} & U_{y} & U_{z} & -P\cdot U\\ V_{x} & V_{y} & V_{z} & -P\cdot V\\ 0 & 0 & 0 & 1 \end{bmatrix} \tag{1}

这里解释了为何LookUp矩阵的平移项是-P·R而不是-P,因为是矩阵相乘的结果。

摄像机空间转换矩阵推导完毕后,下一步是从摄像机空间转到投影空间。

3.正交投影矩阵的推导

我一直在想一个问题,能否用线性代数的投影矩阵来推导出正交投投影矩阵?

根据线性代数的投影矩阵推导公式,假设向量v在平面A[a1 a2]上的投影向量是p,则p可表示为下式:

p=x_{1}a_{1}+x_{2}a_{2}=$$ \begin{bmatrix} a_{1} & a_{2} \end{bmatrix} \tag{1} $$\times $$ \begin{bmatrix} x_{1} & x_{2} \end{bmatrix} \tag{1} $$ = Ax

其中a1,a2是平面的线性组合向量。这里有个限制:A必须是列空间,即A所在的空间一定包含零点

假设向量v投影到A空间后得到p,我们要求的矩阵是:Pv = p中的P

再有向量r = v - p,则向量r垂直平面A,即向量r与a1和a2都垂直。得到如下式子:

{a_{1}}^{T}\cdot r = 0

{a_{2}}^{T}\cdot r = 0

以上两式组合得:

$$ \begin{bmatrix} a_{1}^{T} \\ a_{2}^{T} \end{bmatrix} \tag{1} $$\times $$ \begin{bmatrix} r \end{bmatrix} \tag{1} $$ = $$ \begin{bmatrix} 0 \end{bmatrix}

把r = v - p,p=Ax代入上式得

\\ \begin{bmatrix} a_{1}^{T} \\ a_{2}^{T} \end{bmatrix} \times \begin{bmatrix} v - Ax \end{bmatrix} = \begin{bmatrix} 0 \end{bmatrix} \\A^{T} \times [v-Ax] = [0]

简写成

\\ A^{T}v - A^{T}Ax=0 \\ A^{T}Ax =A^{T}v \\ x=\left( A^{T}A \right)^{-1}A^{T}v

Ax=p,两边乘以A得

\\ A^{T}v - A^{T}Ax=0 \\ A^{T}Ax =A^{T}v \\ x=\left( A^{T}A \right)^{-1}A^{T}v \\ Ax=A\left( A^{T}A \right)^{-1}A^{T}v \quad \Rightarrow \quad p = A\left( A^{T}A \right)^{-1}A^{T}v

即得投影矩阵 

P=A\left( A^{T}A \right)^{-1}A^{T}

更详细的性质与推导可以看线性代数投影矩阵的相关参考。

下面详细说出相机正交投影推导:

A是XOY平面,v是空间中一点。

A= $$ \begin{bmatrix} 1 & 0 \\ 0 & 1 \\ 0 & 0 \\ 0 & 0 \end{bmatrix} \tag{1} $$

P=A\left( A^{T}A \right)^{-1}A^{T} =$$ \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0\\ 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 \end{bmatrix} \tag{1} $$

 

然后要把投影坐标映射到NDC空间。NDC是一个归一化的盒子,z范围0-1,x,y都是-1到1,我手动画图来说明。

详细的世界坐标转屏幕坐标及投影矩阵的推导_第2张图片

屏幕x轴的映射关系是

y=\frac{2}{w}x -1  其中w是屏幕映射区域的宽

同理屏幕y轴的映射关系是

y=\frac{2}{h}x -1  其中h是屏幕映射区域的高

现在我们把w换成r-l,把h换成t-b,r是投影区域的右X坐标,l是左X坐标,t和b同理。

详细的世界坐标转屏幕坐标及投影矩阵的推导_第3张图片

\\ y=\frac{2}{r-l}x+(-\frac{r+l}{r-l}) \\ y=\frac{2}{t-b}x+(-\frac{t+b}{t-b})

z轴的映射关系如下:

详细的世界坐标转屏幕坐标及投影矩阵的推导_第4张图片

求得映射方程如下:

y=\frac{1}{far-near}x+\frac{near}{near-far}

最后得到投影矩阵O:

O= $$ \begin{bmatrix} 2/(r-l) & 0 & 0 & -(r+l)/(r-l) \\ 0 & 2/(t-b) & 0 & -(t+b)/(t-b)\\ 0 & 0 & 1/(far-near) & near/(near-far) \\ 0 & 0 & 0 & 1 \end{bmatrix} \tag{1} $$

我们看到,P怎么变换也不能变换到O,这是为什么呢?

个人理解:P的行列式是0,没有逆矩阵,意味着你无法知道原来的Z的位置。因为线性代数中的投影矩阵是降维操作,而图形学中的投影是一个线性方程变换。

===============================

看了闫令琪的图形学中的推导,是我看过最好最直观的。

简单来说,正交投影就是把长方体的盒子,转换到中心为0的标准正方体[-1, 1]³。

这里是把z的n和f变换到-1到1中,和上面的[0,1]不一样

详细的世界坐标转屏幕坐标及投影矩阵的推导_第5张图片

上图来源于闫令琪的教程,注意,我这里是左手坐标系,把图修正了。

长方体的平移距离是\left ( -(l+r)/2, -(t+l)/2,-(n+l)/2 \right ),矩阵表示为:

O_{t} = \begin{bmatrix} 1 & 0 & 0 & -(l+r)/2 \\ 0 & 1 & 0 & -(t+b)/2\\ 0 & 0 & 1 & -(n+f)/2\\ 0 & 0 & 0 & 1 \end{bmatrix}

Scale就更简单了,l到r缩放到-1到1,缩放因子就是2 / (r - l),其他同理。

O_s= \begin{bmatrix} 2/(r-l) & 0 & 0 & 0\\ 0 & 2/(t-b) & 0 & 0\\ 0 & 0 & 2/(f-n) & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}

正交投影矩阵是:

O = O_s\times O_t = \begin{bmatrix} 2/(r-l) & 0 & 0 & -(l+r)/(r-l)\\ 0 & 2/(t-b) & 0 & -(t+b)/(t-b)\\ 0 & 0 & 2/(f-n) & (n+f)/(n-f)\\ 0 & 0 & 0 & 1 \end{bmatrix}

4.透视投影的推导

参考闫令琪的教程,透视投影就是先把Frustum变换到一个box,然后再进行正交投影的过程。

先看这个连接,https://sites.cs.ucsb.edu/~lingqi/teaching/resources/GAMES101_Lecture_04.pdf

后面我再在这里写过程,并把闫令琪留给我们的问题写出来。

首先,齐次坐标的表示:

(x, y, z, 1),(wx, wy, wz, w != 0),(xz, yz, z², z != 0)均表示同一个点。

下一步,如何把frustum变换到正交投影的box?

详细的世界坐标转屏幕坐标及投影矩阵的推导_第6张图片

侧视图:

详细的世界坐标转屏幕坐标及投影矩阵的推导_第7张图片

y和y'的转换可写成:y' = \frac{y}{z}nx'=\frac{x}{z}n

那么我们要找到一个矩阵,可以把(x, y, z, 1)变换到坐标(x', y', ?, 1) = (yn/z, xn/z, ? 1) = (yn, xn, ? z)

一矩阵乘法的形式表示:

M_{persp\rightarrow ortho} \times \begin{pmatrix} x\\ y\\ z\\ 1 \end{pmatrix} = \begin{pmatrix} nx\\ ny\\ ?\\ z \end{pmatrix}

根据矩阵乘法,row_1 \cdot (x, y, z, 1) = nx,row1 = (n, 0, 0, 0),row2和row4也是如此

M_{persp\rightarrow ortho} = \begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ ? & ? & ? & ?\\ 0 & 0 & 1 & 0 \end{bmatrix}

关键第三行如何求?

但z = n时,经过该矩阵M_{persp\rightarrow ortho}的转换后仍然是n

\begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ ? & ? & ? & ?\\ 0 & 0 & 1 & 0 \end{bmatrix} \times \begin{bmatrix} x\\ y\\ n\\ 1 \end{bmatrix} = \begin{bmatrix} nx/z\\ ny/z\\ n\\ 1 \end{bmatrix} = \begin{bmatrix} nx\\ ny\\ n^2\\ n \end{bmatrix}

点乘法则:

\begin{bmatrix} 0 & 0 & A & B \end{bmatrix} \cdot \begin{bmatrix} x\\ y\\ n\\ 1 \end{bmatrix} = n^2 \quad \Rightarrow An + B = n^2

当z = f时,仍然按上面的法则推导

\begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ ? & ? & ? & ?\\ 0 & 0 & 1 & 0 \end{bmatrix} \times \begin{bmatrix} x\\ y\\ f\\ 1 \end{bmatrix} = \begin{bmatrix} nx/z\\ ny/z\\ f\\ 1 \end{bmatrix} =\begin{bmatrix} nx\\ ny\\ f^2\\ f \end{bmatrix}

\begin{bmatrix} 0 & 0 & A & B \end{bmatrix} \cdot \begin{bmatrix} x\\ y\\ f\\ 1 \end{bmatrix} = f^2 \quad \Rightarrow Af + B = f^2

解方程组求A,B得:

A = n + f

B = -nf

M_{persp\rightarrow ortho} = \begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ 0 & 0 & n+f & -nf\\ 0 & 0 & 1 & 0 \end{bmatrix}

最后投影矩阵:

M_{persp} = M_{ortho} \times M_{persp\rightarrow ortho} \\ = \begin{bmatrix} 2/(r-l) & 0 & 0 & -(l+r)/(r-l)\\ 0 & 2/(t-b) & 0 & -(t+b)/(t-b)\\ 0 & 0 & 2/(f-n) & (n+f)/(n-f)\\ 0 & 0 & 0 & 1 \end{bmatrix} \times \begin{bmatrix} n & 0 & 0 & 0\\ 0 & n & 0 & 0\\ 0 & 0 & n+f & -nf\\ 0 & 0 & 1 & 0 \end{bmatrix} \\ = \begin{bmatrix} 2n/(r-l) & 0 & -(l+r)/(r-l) & 0\\ 0 & 2n/(t-b) & -(t+b)/(t-b) & 0\\ 0 & 0 & 2(n+f)/(f-n) & -2nf/(f-n)\\ 0 & 0 & 1 & 0 \end{bmatrix}

另一种方式的投影矩阵

假设摄像机坐标本来就已经在原点,l + r = 0,t + b=0。

并且r - l = width,t - b = height

投影矩阵可以写成:

M_{persp} = \begin{bmatrix} 2n/width & 0 & 0 & 0\\ 0 & 2n/height & 0 & 0\\ 0 & 0 & 2(n+f)/(f-n) & -2nf/(f-n)\\ 0 & 0 & 1 & 0 \end{bmatrix}

摄像机垂直方向的视角是fov,如下图:

详细的世界坐标转屏幕坐标及投影矩阵的推导_第8张图片

再看下面的式子:

详细的世界坐标转屏幕坐标及投影矩阵的推导_第9张图片

投影矩阵可以最后写成:

M_{persp} = \begin{bmatrix} \frac{1}{tan(fov/2)aspect} & 0 & 0 & 0\\ 0 & \frac{1}{tan(fov/2)} & 0 & 0\\ 0 & 0 & 2(n+f)/(f-n) & -2nf/(f-n)\\ 0 & 0 & 1 & 0 \end{bmatrix}

如果正交投影中,变换到一个在z是0-1的box,只需要修改Ot和Os矩阵:

O_{t} = \begin{bmatrix} 1 & 0 & 0 & -(l+r)/2 \\ 0 & 1 & 0 & -(t+b)/2\\ 0 & 0 & 1 & -n\\ 0 & 0 & 0 & 1 \end{bmatrix}

O_s= \begin{bmatrix} 2/(r-l) & 0 & 0 & 0\\ 0 & 2/(t-b) & 0 & 0\\ 0 & 0 & 1/(f-n) & 0\\ 0 & 0 & 0 & 1 \end{bmatrix}

O = O_s\times O_t = \begin{bmatrix} 2/(r-l) & 0 & 0 & -(l+r)/(r-l)\\ 0 & 2/(t-b) & 0 & -(t+b)/(t-b)\\ 0 & 0 & 1/(f-n) & n/(n-f)\\ 0 & 0 & 0 & 1 \end{bmatrix}

这种情况下的投影矩阵可写成:

M_{persp} = \begin{bmatrix} \frac{1}{tan(fov/2)aspect} & 0 & 0 & 0\\ 0 & \frac{1}{tan(fov/2)} & 0 & 0\\ 0 & 0 & f/(f-n) & -nf/(f-n)\\ 0 & 0 & 1 & 0 \end{bmatrix}

5.NDC坐标到屏幕坐标的转换

NDC中x是-1到1,y也是-1到1,而窗口大小分别是width和height。

下面是NDC的坐标与屏幕坐标的映射关系:

详细的世界坐标转屏幕坐标及投影矩阵的推导_第10张图片        详细的世界坐标转屏幕坐标及投影矩阵的推导_第11张图片

对应方程分别是:

x_{screen}=\frac{width}{2}x+\frac{width}{2}

y_{screen}=-\frac{height}{2}y+\frac{height}{2}

屏幕空间的z是0-1之间,我假设这里的NDC的z也是0-1,(opengl是-1,1),z对应的变换如下:

z_{screen}=z

z_{screen}=\frac{1}{2}z+\frac{1}{2} \qquad (opengl)

因此得到NDC到屏幕坐标的矩阵S。

S= \begin{bmatrix} width/2 & 0 & 0 & width/2 \\ -height/2 & 0 & 0 & height/2 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & 0\end{bmatrix}

S_{opengl}= \begin{bmatrix} width/2 & 0 & 0 & width/2 \\ -height/2 & 0 & 0 & height/2 \\ 0 & 0 & 0.5 & 0.5 \\ 0 & 0 & 0 & 0\end{bmatrix}

做后屏幕坐标就是:

P_{screen} = S \times P_{NDC}

所以,世界坐标到屏幕坐标的最后映射关系是:

P_{screen} = S \times O \times C\times P_{world}

 

你可能感兴趣的:(图形学,数学)