Computer Graphics note(2):视图变换&投影变换

2020-08-02 17:49:17 浏览数 (1)

文章目录

  • 一.前提
  • 二.视图变换
    • 1.推导过程
  • 三.投影变换
    • 1.正交投影(右手系)
    • 2.透视投影
      • (1)视锥定义
      • (2)怎么做透视投影Mpersp=MorthoMpersp−>orthoM_{persp}=M_{ortho}M_{persp->ortho}Mpersp​=Mortho​Mpersp−>ortho​
      • (3)前提规定
      • (4)推导过程
      • (5)Question:frustum中间的点的变化
        • 推导过程

一.前提

Games101 lecture4-lecture5 考虑将三位物体转换二维图像需要的步骤,我们需要以下变换来达成目的, model transformation(模型(基础)变换–Object就位) view/camera transformation(视图变换–调整相机) projection transformation(投影变换–变换到[−1,1]3[-1,1]^3[−1,1]3,忽略深度信息zzz,变成[−1,1]2[-1,1]^2[−1,1]2) viewport transformation(视口变换–投影到屏幕空间) 如下图所示(Fundamentals of Computer Graphics (3rd Edition) 7.1 Viewing Transformations Figure 7.2):

二.视图变换

​ 首先需要定义一个相机,一个相机有三个属性,位置(Positon)epmb{e}eee,观测方向(Look-at/ gaze direction)gpmb{g}g​g​​g和向上方向(Up direction)tpmb{t}ttt。 ​ 同时只要相机和物体之间没有相对运动,观测结果就不会改变,则可以让相机固定在原点,向上方向为YYY方向,看向−Z-Z−Z方向,而这就需要通过变换矩阵MviewM_{view}Mview​来自达成(需要注意的是物体也会随着相机移动而移动,因为要保证两者之间没有相对运动),该矩阵需要完成如下操作:

  1. 将原来在任意点epmb{e}eee的相机平移到原点
  2. 将观测方向gpmb{g}g​g​​g旋转到−Z-Z−Z方向
  3. 将向上方向tpmb{t}ttt旋转到YYY方向
  4. 将{gpmb{g}g​g​​gXtpmb{t}ttt}方向旋转到XXX方向(当前两个方向旋转完成之后,XXX方向自然对齐) 如下图所示:

MviewM_{view}Mview​先平移在旋转(和仿射变换不同),即Mview=RviewTviewM_{view}=R_{view}T_{view}Mview​=Rview​Tview​。 最后结果如下: Mview=RviewTview=[xgXtygXtzgXt0xtytzt0x−gy−gz−g00001][100−xe010−ye001−ze0001] M_{view}=R_{view}T_{view}=begin{bmatrix} x_{gXt} &y_{gXt}&z_{gXt}&0\ x_t&y_t&z_t&0\ x_{-g}&y_{-g}&z_{-g}&0\ 0&0&0&1 end{bmatrix} begin{bmatrix} 1&0&0& -x_e\ 0&1&0& -y_e\ 0&0&1& -z_e\ 0&0&0& 1end{bmatrix} Mview​=Rview​Tview​=⎣⎢⎢⎡​xgXt​xt​x−g​0​ygXt​yt​y−g​0​zgXt​zt​z−g​0​0001​⎦⎥⎥⎤​⎣⎢⎢⎡​1000​0100​0010​−xe​−ye​−ze​1​⎦⎥⎥⎤​

1.推导过程

首先是平移到原点,可以很自然的写出其平移矩阵TviewT_{view}Tview​如下: Tview=[100−xe010−ye001−ze0001] T_{view}=begin{bmatrix} 1&0&0& -x_e\ 0&1&0& -y_e\ 0&0&1& -z_e\ 0&0&0& 1end{bmatrix} Tview​=⎣⎢⎢⎡​1000​0100​0010​−xe​−ye​−ze​1​⎦⎥⎥⎤​ 接着考虑旋转,将任意方向旋转到X,Y,−ZX,Y,-ZX,Y,−Z方向上不容易写出,但是可以考虑其逆变换,写出将X(1,0,0),Y(0,1,0),Z(0,0,1)X(1,0,0),Y(0,1,0),Z(0,0,1)X(1,0,0),Y(0,1,0),Z(0,0,1)旋转到{gpmb{g}g​g​​gXtpmb{t}ttt},tpmb{t}ttt,−gpmb{-g}−g​−g​​−g的旋转矩阵Rview−1R_{view}^{-1}Rview−1​,并且由于旋转矩阵是正交矩阵,所以只要写出Rview−1R_{view}^{-1}Rview−1​,其转置矩阵即为所求,如下所示: Rview−1=[xgXtxtx−g0ygXtyty−g0zgXtztz−g00001] R_{view}^{-1}=begin{bmatrix} x_{gXt} &x_t&x_{-g}&0\ y_{gXt} &y_t&y_{-g}&0\ z_{gXt} &z_t&z_{-g}&0\ 0&0&0&1 end{bmatrix} Rview−1​=⎣⎢⎢⎡​xgXt​ygXt​zgXt​0​xt​yt​zt​0​x−g​y−g​z−g​0​0001​⎦⎥⎥⎤​ 可以通过将上述矩阵应用与三轴来检验其正确性。RviewR_{view}Rview​如下所示: Rview=Rview(−1)(−1)=RviewT=[xgXtygXtzgXt0xtytzt0x−gy−gz−g00001] R_{view} = R_{view}^{(-1)(-1)}=R_{view}^T= begin{bmatrix} x_{gXt} &y_{gXt}&z_{gXt}&0\ x_t&y_t&z_t&0\ x_{-g}&y_{-g}&z_{-g}&0\ 0&0&0&1 end{bmatrix} Rview​=Rview(−1)(−1)​=RviewT​=⎣⎢⎢⎡​xgXt​xt​x−g​0​ygXt​yt​y−g​0​zgXt​zt​z−g​0​0001​⎦⎥⎥⎤​ 所以最终的MviewM_{view}Mview​如开头所示。

三.投影变换

投影变换目的就是将物体变换到[−1,1]3[-1,1]^3[−1,1]3。想要得到二维图像,可以去掉zzz,变成[−1,1]2[-1,1]^2[−1,1]2。变换分为两种,正交(orthographic)投影和透视(prespective)投影。透视投影存在近大远小的现象,而正交投影则不会,这是两者的本质区别,两者分别如下图所示: 图片来源:https://stackoverflow.com/questions/36573283/from-perspective-picture-to-orthographic-picture

上图中透视投影围成一个视锥(四棱锥),而视锥中从某一个深度到另一个深度之间的区域叫做frustumfrustumfrustum,而透视投影就是将frustumfrustumfrustum中的东西显示到近平面(NearNearNear clipclipclip planeplaneplane)上。

1.正交投影(右手系)

首先定义一个空间中的立方体(只需定义6个面,左右上下前后),[l,r][l,r][l,r]x[b,t][b,t][b,t]x[f,n][f,n][f,n],需要注意的是远平面(fff)和近平面(nnn),有n>fpmb{n}>pmb{f}nnn>f​f​​f因为看向−Z-Z−Z(右手系),所以物体越远则其对应的ZZZ的值越小,反之越大。如果是左手系则越远ZZZ越大,因为看向的 Z Z Z方向。然后将立方体中心平移到原点,并将其缩放成canonicalcanonicalcanonical(正则规范标准立方体) cube[−1,1]3cube [-1,1]^3cube[−1,1]3,忽略zzz,则变为[−1,1]2[-1,1]^2[−1,1]2。 如下图所示:

先将立方体中心(r l2,t b2,n f2)(frac{r l}{2},frac{t b}{2},frac{n f}{2})(2r l​,2t b​,2n f​)平移到原点,然后缩放到[−1,1]3[-1,1]^3[−1,1]3(长宽高为222),这里的缩放其实就是将立方体的长宽高缩放为222,其变换矩阵MorthoM_{ortho}Mortho​如下: Mortho=[2r−l00002t−b00002n−f00001][100−r l2010−t b2001−n f20001]=[2r−l00−r lr−l02t−b0−t bt−b002n−f−n fn−f0001] M_{ortho}=begin{bmatrix} frac{2}{r-l} &0&0&0\ 0& frac{2}{t-b} &0&0\ 0&0& frac{2}{n-f} &0\ 0&0&0 &1 end{bmatrix} begin{bmatrix} 1&0&0& -frac{r l}{2}\ 0&1&0& -frac{t b}{2}\ 0&0&1& -frac{n f}{2}\ 0&0&0& 1 end{bmatrix}=begin{bmatrix} frac{2}{r-l}&0&0&-frac{r l}{r-l}\ 0&frac{2}{t-b}&0&-frac{t b}{t-b}\ 0&0&frac{2}{n-f}&-frac{n f}{n-f}\ 0&0&0&1 end{bmatrix} Mortho​=⎣⎢⎢⎡​r−l2​000​0t−b2​00​00n−f2​0​0001​⎦⎥⎥⎤​⎣⎢⎢⎡​1000​0100​0010​−2r l​−2t b​−2n f​1​⎦⎥⎥⎤​=⎣⎢⎢⎡​r−l2​000​0t−b2​00​00n−f2​0​−r−lr l​−t−bt b​−n−fn f​1​⎦⎥⎥⎤​

2.透视投影

(1)视锥定义

透视投影的视锥定义只要定义两个东西1.垂直可视角度YYY 2.宽高比aspectaspectaspect,如下图所示:

从侧面观察,则近平面距离相机距离为∣n∣|n|∣n∣,如下图所示:

(2)怎么做透视投影Mpersp=MorthoMpersp−>orthoM_{persp}=M_{ortho}M_{persp->ortho}Mpersp​=Mortho​Mpersp−>ortho​

  1. 首先将frustumfrustumfrustum挤压成一个长方体(Mpersp−>orthoM_{persp->ortho}Mpersp−>ortho​)([l,r][l,r][l,r]x[b,t][b,t][b,t]x[f,n][f,n][f,n],);
  2. 然后再做一次正交投影(MorthoM_{ortho}Mortho​,已知)。即可完成投影到近平面的任务。

如下图所示:

(3)前提规定

  1. 在挤压过程(第一步)中frustumfrustumfrustum的近平面nnn上点不变;
  2. fff平面的ZZZ值不变,因为只是在收缩;
  3. fff平面的中心点是不会改变的(挤压完还是中心点)。

(4)推导过程

先单独考虑挤压过程,我们需要找到一个矩阵来完成变换。 考虑下图,从视锥的侧面看,我们需要将(x,y,z)(x,y,z)(x,y,z)挤压到和近平面上点(x′,y′,z′)(x',y',z')(x′,y′,z′)一样的高度,考虑相似三角形,则有y′=nzyy'=frac{n}{z}yy′=zn​y;同理(从上面看),对于xxx而言有x′=nzxx'=frac{n}{z}xx′=zn​x。

需要注意的是,这里n,zpmb{n},pmb{z}nnn,zzz在图上表示的是距离原点的距离(负ZZZ方向),所以是个负数。

至此,已知挤压过程x,yx,yx,y的变换,zzz未知,将上述变换用齐次坐标,同时在基础变换中我们提到过对于齐次坐标而言,(x,y,z,w)T(w!=0)(x,y,z,w)^T(w!=0)(x,y,z,w)T(w!=0)表示的点即为(xw,yw,zw,1)T(frac{x}{w},frac{y}{w},frac{z}{w},1)^T(wx​,wy​,wz​,1)T。 所以有如下关系: Mpersp−>ortho[xyz1]=[nzxnzy?1]=同乘z[nxny?z] M_{persp->ortho}begin{bmatrix} x\y\z\1 end{bmatrix}=begin{bmatrix} frac{n}{z}x \ frac{n}{z}y \ ? \1 end{bmatrix}stackrel{同乘z}{=}begin{bmatrix} nx\ny\?\z end{bmatrix} Mpersp−>ortho​⎣⎢⎢⎡​xyz1​⎦⎥⎥⎤​=⎣⎢⎢⎡​zn​xzn​y?1​⎦⎥⎥⎤​=同乘z⎣⎢⎢⎡​nxny?z​⎦⎥⎥⎤​ 从中可以反推出Mpersp−>orthoM_{persp->ortho}Mpersp−>ortho​如下: Mpersp−>ortho=[n0000n00????0010] M_{persp->ortho}=begin{bmatrix} n&0&0&0 \ 0&n&0&0 \ ?&?&?&? \ 0&0&1&0 end{bmatrix} Mpersp−>ortho​=⎣⎢⎢⎡​n0?0​0n?0​00?1​00?0​⎦⎥⎥⎤​ 同时因为挤压过程中近平面点不变,远平面点ZZZ值不变。则对于一个近平面上点(x,y,n,1)T(x,y,n,1)^T(x,y,n,1)T(假设近平面上的zzz的值为nnn)。考虑齐次坐标中一个点可以有很多不同的表示,同理则有(x,y,n,1)T=同乘n(nx,ny,n2,n)T(x,y,n,1)^Tstackrel{同乘n}{=}(nx,ny,n^2,n)^T(x,y,n,1)T=同乘n(nx,ny,n2,n)T变换后是不变的。所以有如下关系: Mpersp−>ortho[xyn1]=[nxny?z]=[nxnyn2n] M_{persp->ortho}begin{bmatrix} x\y\n\1 end{bmatrix}=begin{bmatrix} nx\ny\?\z end{bmatrix}=begin{bmatrix} nx\ny\n^2\n end{bmatrix} Mpersp−>ortho​⎣⎢⎢⎡​xyn1​⎦⎥⎥⎤​=⎣⎢⎢⎡​nxny?z​⎦⎥⎥⎤​=⎣⎢⎢⎡​nxnyn2n​⎦⎥⎥⎤​

则可以推出变换矩阵的第三行为(0,0,A,B)(0,0,A,B)(0,0,A,B),即有式子(1)(1)(1)如下: [00AB][xyn1]=n2(1) begin{bmatrix} 0&0&A&B end{bmatrix}begin{bmatrix} x\y\n\1 end{bmatrix}=n^2tag{1} [0​0​A​B​]⎣⎢⎢⎡​xyn1​⎦⎥⎥⎤​=n2(1)

再考虑fff平面中zzz不变,且中心点不变,则对于其中心点(0,0,f,1)(0,0,f,1)(0,0,f,1)(假设远平面上zzz值为fff)。则有如下关系式子(2)(2)(2): [00f1]=同乘f[00f2f]⇒[00AB][00f1]=[00f2f](2) begin{bmatrix} 0\0\f\1 end{bmatrix}stackrel{同乘f}{=}begin{bmatrix} 0\0\f^2\f end{bmatrix}Rightarrowbegin{bmatrix} 0&0&A&B end{bmatrix}begin{bmatrix} 0\0\f\1 end{bmatrix}=begin{bmatrix} 0\0\f^2\f end{bmatrix}tag{2} ⎣⎢⎢⎡​00f1​⎦⎥⎥⎤​=同乘f⎣⎢⎢⎡​00f2f​⎦⎥⎥⎤​⇒[0​0​A​B​]⎣⎢⎢⎡​00f1​⎦⎥⎥⎤​=⎣⎢⎢⎡​00f2f​⎦⎥⎥⎤​(2) 由(1)(2)(1)(2)(1)(2)可得,如下结果 {An B=n2Af B=f2⇒{A=n fB=−nf begin{cases} An B=n^2\ Af B=f^2 end{cases}Rightarrowbegin{cases} A=n f\ B=-nf end{cases} {An B=n2Af B=f2​⇒{A=n fB=−nf​ 则有 Mpersp−>ortho=[n0000n0000n f−nf0010] M_{persp->ortho}=begin{bmatrix} n&0&0&0 \ 0&n&0&0 \ 0&0&n f&-nf \ 0&0&1&0 end{bmatrix} Mpersp−>ortho​=⎣⎢⎢⎡​n000​0n00​00n f1​00−nf0​⎦⎥⎥⎤​ 所以透视投影变换矩阵计算如下: Mpersp=MorthoMpersp−>ortho=[2nr−l0−r lr−l002nt−b−t bt−b000n fn−f−2nfn−f0010] M_{persp}=M_{ortho}M_{persp->ortho}=begin{bmatrix} frac{2n}{r-l}&0&-frac{r l}{r-l}&0\ 0&frac{2n}{t-b}&-frac{t b}{t-b}&0\ 0&0&frac{n f}{n-f}&-frac{2nf}{n-f}\ 0&0&1&0 end{bmatrix} Mpersp​=Mortho​Mpersp−>ortho​=⎣⎢⎢⎡​r−l2n​000​0t−b2n​00​−r−lr l​−t−bt b​n−fn f​1​00−n−f2nf​0​⎦⎥⎥⎤​

(5)Question:frustum中间的点的变化

在frustumfrustumfrustum中间任何一个位置,比如点(x,y,n f2,1)T(x,y,frac{n f}{2},1)^T(x,y,2n f​,1)T,经过挤压之后(不做第二步正交)更加靠近远平面还是近平面?(远平面)

推导过程

先将Mpersp−>orthoM_{persp->ortho}Mpersp−>ortho​应用到该点上,如下: Mpersp−>ortho[xyn f21]=[nxny(n f)22−nfn f2]=规范化,同除以n f2[2nxn f2nyn fn f−2nfn f1] M_{persp->ortho}begin{bmatrix} x\y\frac{n f}{2}\1 end{bmatrix}=begin{bmatrix} nx\ny\ frac{(n f)^2}{2}-nf\ frac{n f}{2} end{bmatrix}stackrel{规范化,同除以frac{n f}{2}}{=}begin{bmatrix} frac{2nx}{n f}\ frac{2ny}{n f} \ n f-frac{2nf}{n f}\1 end{bmatrix} Mpersp−>ortho​⎣⎢⎢⎡​xy2n f​1​⎦⎥⎥⎤​=⎣⎢⎢⎡​nxny2(n f)2​−nf2n f​​⎦⎥⎥⎤​=规范化,同除以2n f​⎣⎢⎢⎢⎡​n f2nx​n f2ny​n f−n f2nf​1​⎦⎥⎥⎥⎤​

比较变换前后两点的ZZZ值大小,如下: n f−2nfn f−n f2=n f2−2nfn f=(n f)2−4nf2(n f)=(n−f)22(n f) begin{aligned} n f-frac{2nf}{n f}-frac{n f}{2} &= frac{n f}{2}-frac{2nf}{n f} \ &= frac{(n f)^2-4nf}{2(n f)}\ &= frac{(n-f)^2}{2(n f)} end{aligned} n f−n f2nf​−2n f​​=2n f​−n f2nf​=2(n f)(n f)2−4nf​=2(n f)(n−f)2​​

前面提到此时的n,fn,fn,f是个负数,所以有(n−f)2>0(n-f)^2>0(n−f)2>0,(n f)<0(n f)<0(n f)<0,即更加靠近远平面

0 人点赞