计算机图形学.李胜.05.投影(2)

OpenGL 中的投影矩阵

  • vmath:Frusutm()

[2nearrightleft0A002neartopbottomB000CD0010]

  • 其中 A,B,C,D 含义如下

A=left+rightrightleft

B=top+bottomtopbottom

C=far+nearfarnear

D=2farnearfarnear

  • 其中 far,near,top,bottom,left,right 表示6个裁剪面
    • 实际的裁剪面
      • far,near 使用的是绝对值
        • 因为一定是负数
      • far,near,top,bottom,left,right
  • 坐标变换:
    • 现实坐标系中的视见体 转化为 OpenGL中的立方体 [1,1]

  • 投影中心 (0,0,0)
  • 投影平面 z=near
  • 推导过程中裁剪面使用单词首字母代替

推导一:投影角度

  • 投影+规范化

(1) 投影

  • 将视见体中的点投影到 z=n
  • 以俯视图为例推导坐标关系(x,z

  • zp=n
  • xp=nxeze
  • 利用侧视图可以得到 yp=nyeze

(2) 规范化

  • xp[l,r]xn[1,1]

  • yp[b,t]yn[1,1]

  • x 的推导为例

    • xplrl=xn(1)1(1)
    • xn=2xplrl1=2rlxpr+lrl=2nze(rl)xer+lrl
    • xn=2nrlxe+ze(r+l)rlze
  • 同理

    • yn=2ntbye+ze(t+b)tbze
  • 写成矩阵的形式

    • 为了计算的方便,我们把分母放到最终的齐次坐标化简中去

    • wc=ze,xn=xcwc,yn=ycwc

    • [2nrl0r+lrl002ntbt+btb00010][xeyezewe]=[xcyczcwc]

(3) 记录深度信息

[2nrl0r+lrl002ntbt+btb000AB0010][xeyezewe]=[xcyczcwc]

  • 我们可以看到, zn 并没有被用上,我们可以用来记录深度信息

  • zn=zcwc=Aze+Bwewc=Aze+Bze=A+Bze

  • ze[f,n]zn[1,1]

    • 深度值越远越大
  • {1=A+Bf1=A+Bn{A=f+nfnB=2nffn

推导二:变换角度

  • 错切+缩放+规范化

(1) 错切

  • 错切至关于 z 轴中心对称

  • x 方向:tanθx=12l+rn
    • +x:tanθx=l+r2n
  • y 方向:tanθy=12t+bn
    • +y:tanθy=t+b2n

M1=[10l+r2n001t+b2n000100001]

(2) 缩放

  • 缩放的结果
    • x:[l,r][1,1]
    • y:[b,t][1,1]
    • z:[f,n][1,fn]
      • 因此,对应着投影平面 z=1 的是后裁剪面 z=f

M2=[2n(rl)f00002n(tb)f00001f00001]

  • 等价于 M2(化成标准齐次坐标是一样的)

M2=[2nrl)f00002ntb000010000f]

  • 以上形成的视见体其实是一个棱台
    • 顶点为 (0,0,0) 底面为 (1,1,0),(1,1,0),(1,1,0),(1,1,0) 的四棱锥被平面 z=nf 截成的四棱锥

(3) 透视=>平行

  • 将透视投影的规范视见体变换为平行投影的规范视见体
    • 将上述四棱锥转换为长方体
    • x:[1,1][1,1]
    • y:[1,1][1,1]
    • z:[1,fn][1,0]

M3=[100001000011nminnmin1nmin0010]

  • zmin0

M3=[1000010000ffnnfn0010]

  • 推导过程和 推导一的投影 相似
    • xpzp=xn1,ypzp=yn1
    • xn=xpzp,yn=ypzp
  • 得到矩阵如下

M3=[100001000010]

  • 将第三行用于记录深度信息

M3=[1000010000AB0010]

  • zn=Azp+Bzp=A+Bzp

    • {1=A+B10=A+Bnmin{A=11nminB=nmin1nmin

(4) 平移

  • x:[1,1][1,1]
  • y:[1,1][1,1]
  • z:[1,0][12,12]

M4=[10000100001120001]

(5) 尺缩

  • x:[1,1][1,1]
  • y:[1,1][1,1]
  • z:[12,12][1,1]

M5=[1000010000200001]

(6) 深度变换

  • 深度越大 z 越大

M6=[1000010000100001]

(7) 结果

  • 与上面一致

M6M5M4M3M2M1