• 投影矩阵的计算过程


      3d模型经过世界坐标变换、相机坐标变换后,下一步需要投影变换。投影变换的目的就是要把相机空间转换到标准视图空间,在这个空间的坐标都是正规化的,也就是坐标范围都在[-1,1]之间,之所以转换到这个空间是为了后续操作更方便。

      下面的讨论都是以列向量来表示,这样在变换操作时,采用的是矩阵左乘法,如果采用的是行向量的话,那就相反,矩阵右乘法即是向量在左边乘以变换矩阵。采用哪种表示并不影响结果,只需要把该种表示下得出的变换矩阵转置一下,就是采用另外一种表示模式需要的结果。

      常见的投影有两种,正交投影和透视投影,正交投影相对来说更简单,所以先来看看正交投影。

      最简单的正交变换矩阵

                                      1 0 0 0

                                       0 1 0 0

                                       0 0 0 1

      这个正交变换是不可逆变换,变换后x和y保留,z变成了0,在实际应用中,更常见的情况是限定x、y、z在一定的范围内的进行投影变换,比如x[l,r],y[b,t],z[n,f]。那么要把这段空间中的点变换到-1和1之间,只要完成两个变换,首先把坐标轴移到中心,然后进行缩放就可以了。采用列向量的话,那就是缩放矩阵乘以平移矩阵。

        2/(r-l)     0     0    0                                1   0   0    -(r+l)/2                    2/(r-l)   0       0  -(r+l)/(r-l)

        0   2/(t-b)    0    0                x              0    1   0   -(b+t)/2          =        0     2/(t-b)  0  -(t+b)/(t-b)

        0       0   2/(f-n)  0                               0     0   1   -(n+f)/2                    0        0    2/(f-n)  -(f+n)/(f-n)

        0      0         0     1                              0     0    0         1                       0        0        0           1

      透视投影类比于我们人眼系统,看一个物体,会有远小近大的效果。在转换到相机空间后,相机是这个空间的原点,和正交投影体是一个长方体或者立方体不同,透视投影体是一个锥体被近平面截取掉头部剩下的空间。假定仍然采用上面的坐标表示。在透视投影下,空间上面的任何一点P投影到近平面上某点q,通过三角几何学我们可以得到 qx=px*n/p,y点同理。假定直接投影到近平面,则该矩阵很简单,用Ma表示下面的矩阵

    1 0   0    0

    0 1   0    0

    0 0   1    0

    0  0  1/n 0

    则齐次空间某点(x,y,z ,1)被该矩阵转换后变成了 (x ,y z, z/n) ,除以z/n,则变成了(nx/z,ny/z,n ,1) 正好吻合上面的公式。

    但是我们知道投影变换需要把坐标变换到-1和1之间,假定先不考虑z轴的变换,在x轴和y轴上面经过上述变换后,已经投影在近平面了,假设近平面xy在[l,r] 和[b,t]之间了,因此只需要和上面的正交投影一样,进行平移和缩放操作就可以了,平移矩阵Mb

    1  0  0  -(l+r)/2

    0  1  0  -(t+p)/2

    0  0  1  -(f+n)/2

    0  0   0     1

    以及缩放矩阵Mc

    2/(r-l)     0     0    0                            

    0   2/(t-b)    0    0              

    0       0   2/(f-n)  0               

    0      0         0     1   

    McXMbXMa

    得到的矩阵为

    2/(r-l)       0       -(r+l)/(n*(r-l))   0

    0           2/(t-b)  -(t+b)/(n*(t-b))  0

    0             0            j               k

    0            0            1/n            0  

    j  k 为未知数,这个矩阵也可以同时乘以n,则变为

    2n/(r-l)      0      -(r+l)/(r-l)      0

    0       2n/(t-b)   -(t+b)/(t-b)     0

    0            0              j                k

    0            0              1                0

    为了求解 J  k,我们需要把z变换到-1 和1

    因此当z=n时为-1, z=f时 为1

    (j*n+k)/n= j+k/n=-1;

    同理  j+k/f=1;

    得到 k=2f*n/(n-f)

    j=-(n+f)/(n-f)

    代入上面的矩阵,就得出通用的正交变换矩阵。

    而且在一般情况下  r=-l ,b=-t

    因此上述矩阵可以简化为

    n/r  0   0   0

    0   n/t   0   0

    0   0   -(n+f)/(n-f)  2f*n/(n-f)

    0  0     1     0

    n/r 和 n/t可以进一步简化成水平半视角和垂直半视角的三角函数来表示,而水平视角和垂直视角和透视窗口的宽高比有是成正比的,最终上面两行可以用宽高比和某个半视角的余切来表示。

    这是在列向量情况下得出的投影矩阵,如果采用行向量,只需要把上面的矩阵转置一下即可。

  • 相关阅读:
    考试 题目
    引用数据类型 Scanner和 Random
    数组
    数据字典 事物 序列 索引视图
    小程序下拉刷新
    使用e.target.dataset的问题
    动态统计当前输入内容的字节、字符数
    小程序根据input输入,动态设置按钮的样式
    小程序刨坑(一)
    charles 踩坑记录
  • 原文地址:https://www.cnblogs.com/qzzlw/p/3505284.html
Copyright © 2020-2023  润新知