• 【计算机图形学基础】投影矩阵


      最近在重温计算机图形学的基础知识,期望能做到温故知新,加深对其的理解,以便能从容应对工作中各种情况。
      小弟水平有限,若有不正确之处,欢迎大家批评指正。

    1 投影矩阵的作用

      投影分为正交投影透视投影
      正交投影会保留场景原始的画面,平行的线仍然平行;
      透视投影会产生近大远小的效果,平行的线不再平行。
      投影矩阵将相机空间的顶点全部转换到裁剪空间。裁剪空间的点x、y和z的坐标都被映射在[-1, 1]。
      注意,裁剪空间中的点还是齐次坐标。齐次坐标转换到笛卡尔坐标,需要进行如下的转换:

       ( x y z w )

    (xyzw)" role="presentation" style="position: relative;">(xyzw)
    xyzw ----> ( x w y w z w 1 )
    (xwywzw1)" role="presentation" style="position: relative;">(xwywzw1)
    wxwywz1
    ----> ( x w y w z w )
    (xwywzw)" role="presentation" style="position: relative;">(xwywzw)
    wxwywz

    2 正交投影

    2.1 视景体

      正交投影的视景体如下图所示:
    视景体
      该视景体是一个立方体,在 x y z xyz xyz 组成的的相机空间中;
      l 代表视景体左截面x坐标,r 代表视景体右截面x坐标;
      b 代表视景体底截面y坐标,t 代表视景体上截面y坐标;
      n 代表视景体近截面z坐标,f 代表视景体远截面z坐标;
      视景体中,l 一定小于 r,b 一定小于 t。相机空间中,可视点的 z 值一定小于0,所以 n 一定大于 f。

    2.2 正交投影变换

      正交投影变换包含两个步骤:
      ① 将视景体中心平移到原点;
      ② 执行缩放,使 xyz的范围为[-1, 1]。
    正交投影变换
      上述变换要分别使用平移矩阵 M T M_{T} MT 和缩放矩阵 M S M_{S} MS
      平移矩阵如下:

    M T M_{T} MT = ( 1 0 0 − ( l + r ) 2 0 1 0 − ( b + t ) 2 0 0 1 − ( n + f ) 2 0 0 0 1 )

    (100(l+r)2010(b+t)2001(n+f)20001)" role="presentation" style="position: relative;">(100(l+r)2010(b+t)2001(n+f)20001)
    1000010000102(l+r)2(b+t)2(n+f)1

      缩放矩阵如下:

    M S M_{S} MS = ( 2 r − l 0 0 0 0 2 t − b 0 0 0 0 2 n − f 0 0 0 0 1 )

    (2rl00002tb00002nf00001)" role="presentation" style="position: relative;">(2rl00002tb00002nf00001)
    rl20000tb20000nf200001

      现以 x 为例来推导缩放因子。
      平移视景体中心到原点后,由于视景体是对称的立方体,所以 − n < x < n -n < x < n n<x<n,其中n > 0,且 n = r − l + r 2 r - \frac{l+r}{2} r2l+r = r − l 2 \frac{r-l}{2} 2rl
      为了让 − 1 < x < 1 -1 < x < 1 1<x<1,因此需要乘以系数 1 n \frac{1}{n} n1,即 2 r − l \frac{2}{r-l} rl2
      其他两个维度的推导也是如此。
      综上,正交投影矩阵 M O r t h o M_{Ortho} MOrtho = M S M_{S} MS M T M_{T} MT
      注意,如果视景体的aspect ratio != 1,经过正交变换后,图像会被拉伸。最后,会通过视口变换进行纠正。

    3 透视投影

      透视投影是应用最广泛的投影,它能产生近大远小的效果,平行线经过透视投影后不再平行。

    3.1 视椎体

    视椎体
      同正交投影一样,透视投影也有自己的l、r、b、t、n、f。不同的是,各个截面会相交于相机空间的原点
      视椎体中的顶点被投影到近平面上,从而被渲染到屏幕。

    3.2 决定视椎体的因素

      视椎体由如下因素决定:① field of view;② aspect ration;③ near 和 far。
    fovy和aspect ratio
      视椎体是个对称的平截头体,现以侧面YZ平面来分析:
    在这里插入图片描述
      现在已知fovY、apsect ratio = w i d t h h e i g h t \frac{width}{height} heightwidth、near和far,视椎体是一个对称平截头体,且规则地放在 − Z -Z Z轴上。
      根据正切定理,有 t = t a n ( f o v Y 2 ) tan(\frac{fovY}{2}) tan(2fovY) * ∣ n ∣ |n| n;又根据对称性,得到 -t = b;
      又根据 aspect ratio = r t \frac{r}{t} tr = w i d t h h e i g h t \frac{width}{height} heightwidth,因此 r = aspect ratio * t;又因为对称性,所以有 -r = l。
      综上,可根据fovY、aspect ration、near 和 far可求得 l、r、b 和 t。

    3.3 透视投影矩阵

    3.3.1 相似变换

      以侧面 YZ 面来进行分析:
    在这里插入图片描述
      由相似三角形,点投影到近平面后,其 y ′ y' y = ∣ n ∣ ∣ z ∣ \frac{|n|}{|z|} zn * y y y
      同理,该点的x轴坐标为 x ′ x' x = ∣ n ∣ ∣ z ∣ \frac{|n|}{|z|} zn * x x x
      在OpenGL中,通常near和far必须指定为大于0,因此,由于 z < 0 z < 0 z<0,有:
       x ′ x' x = − n z -\frac{n}{z} zn * x x x y ′ y' y = − n z -\frac{n}{z} zn * y y y

    3.3.2 推导影响x、y分量的元素

       x x x 经过投影后成为 x ′ x' x x ′ x' x在近平面上,因此有: l < x ′ < r l < x' < r l<x<r

      减去 l,有: 0 < x ′ − l < r − l 0 < x' - l < r - l 0<xl<rl

      除以 r − l r - l rl,有: 0 < x ′ − l r − l < 1 0 < \frac{x' - l}{r - l} < 1 0<rlxl<1

      乘以2,有: 0 < 2 x ′ − l r − l < 2 0 < 2\frac{x' - l}{r - l} < 2 0<2rlxl<2

      减去1,有: − 1 < 2 x ′ − l r − l − 1 < 1 -1 < 2\frac{x' - l}{r - l} - 1< 1 1<2rlxl1<1

      将上述等式优化,有: − 1 < 2 x ′ − 2 l r − l − r − l r − l < 1 -1 < \frac{2x' - 2l}{r - l} - \frac{r-l}{r-l}< 1 1<rl2x2lrlrl<1

      有: − 1 < 2 x ′ − l − r r − l < 1 -1 < \frac{2x' - l - r}{r - l}< 1 1<rl2xlr<1

      有: − 1 < 2 x ′ r − l − r + l r − l < 1 -1 < \frac{2x'}{r - l} - \frac{r+l}{r-l}< 1 1<rl2xrlr+l<1

      将上述 x ′ x' x 替换为 x x x(相机空间坐标点),有: − 1 < − 2 n x z ( r − l ) − r + l r − l < 1 -1 < \frac{-2nx}{z(r - l)} - \frac{r+l}{r-l}< 1 1<z(rl)2nxrlr+l<1; (等式①)

      因此,若将下述矩阵作为透视变换矩阵,有:

       M P e r s p e c t M_{Perspect} MPerspect = ( 2 n r − l 0 r + l r − l 0 . . . . . . . . . . . . . . . . . . . . . . . . 0 0 − 1 0 )

    (2nrl0r+lrl0........................0010)" role="presentation" style="position: relative;">(2nrl0r+lrl0........................0010)
    rl2n......00......0rlr+l......10......0

      现求取 x x x分量进行验证, M P e r s p e c t M_{Perspect} MPerspect x ( x y z w )

    (xyzw)" role="presentation" style="position: relative;">(xyzw)
    xyzw ,该结果的 x x x 分量为: 2 n r − l x \frac{2n}{r-l}x rl2nx + r + l r − l z \frac{r+l}{r-l}z rlr+lz

      该结果的 w w w 分量(齐次坐标)为: 0 ∗ x 0 * x 0x + 0 ∗ y 0 * y 0y + ( − 1 ∗ z ) (-1 * z) (1z) + 0 ∗ w 0 * w 0w = − z -z z

      齐次坐标转换为笛卡尔坐标需要除以 w w w,故上述 x x x 分量转换到笛卡尔坐标后为: 2 n x − z ( r − l ) \frac{2nx}{-z(r-l)} z(rl)2nx - r + l r − l \frac{r+l}{r-l} rlr+l。该值和前述推导等式①一致。

      综上,透视投影矩阵的第一行元素就确定下来了。
      同理,可以确定透视投影的第二行元素,其推导方法和前述一致,只是把 r r r l l l 分别替换为 t t t b b b

       M P e r s p e c t M_{Perspect} MPerspect = ( 2 n r − l 0 r + l r − l 0 0 2 n t − b t + b t − b 0 . . . . . . . . . . . . 0 0 − 1 0 )

    (2nrl0r+lrl002ntbt+btb0............0010)" role="presentation" style="position: relative;">(2nrl0r+lrl002ntbt+btb0............0010)
    rl2n0...00tb2n...0rlr+ltbt+b...100...0

    3.3.3 推导影响z分量的元素

      投影后的点在近平面上, x x x y y y 不会对 z z z 有影响,那么设透视投影矩阵为:

       M P e r s p e c t M_{Perspect} MPerspect = ( 2 n r − l 0 r + l r − l 0 0 2 n t − b t + b t − b 0 0 0 A B 0 0 − 1 0 )

    (2nrl0r+lrl002ntbt+btb000AB0010)" role="presentation" style="position: relative;">(2nrl0r+lrl002ntbt+btb000AB0010)
    rl2n0000tb2n00rlr+ltbt+bA100B0

      其中 A 和 B 是待求解的未知数。

      有: z ′ z' z = ( A z + B w Az + Bw Az+Bw) / ( − z -z z)

      当相机空间的点在近平面时, z ′ z' z 需要被投影为-1,且此时 z z z = -near;
      当相机空间的点在远平面时, z ′ z' z 需要被投影为1,且此时 z z z = -far;

      因此,可以列出两个方程:

      ① − 1 -1 1 = − n A + B n \frac{-nA + B}{n} nnA+B

      ② 1 1 1 = − f A + B f \frac{-fA + B}{f} ffA+B

      两个方程,两个未知数,解得 A A A = − f + n f − n -\frac{f+n}{f-n} fnf+n B B B = − 2 f n f − n -\frac{2fn}{f-n} fn2fn

      综上,透视投影的方程如下:

       M P e r s p e c t M_{Perspect} MPerspect = ( 2 n r − l 0 r + l r − l 0 0 2 n t − b t + b t − b 0 0 0 − f + n f − n − 2 f n f − n 0 0 − 1 0 )

    (2nrl0r+lrl002ntbt+btb000f+nfn2fnfn0010)" role="presentation" style="position: relative;">(2nrl0r+lrl002ntbt+btb000f+nfn2fnfn0010)
    rl2n0000tb2n00rlr+ltbt+bfnf+n100fn2fn0

    4 参考

    1. mathematics-physics-for-computer-graphics/lookat-function
    2. 推导相机矩阵
    3. GAMES101-现代计算机图形学入门-闫令琪
  • 相关阅读:
    Java毕业论文设计(农业综合性服务平台)
    SPASS-图表的创建&编辑
    sql主从复制搭建
    全球十大优质炒黄金交易APP平台排名(信息汇总)
    03【Controller方法返回值详解】
    【前端面试必知】Vue组件间的通信方式
    leetcode2022年度刷题分类型总结(十二)并查集
    P02014258 苏英秦 信息论作业
    c#入参使用引用类型为啥要加ref?
    DC电源模块在电容滤波器上的设计
  • 原文地址:https://blog.csdn.net/lyzirving/article/details/125860578