• opengl视图变换 投影变换推导


    视图变换
    在opengl中,视图变换的输入是:
    (1)眼睛位置(或者说相机位置)eys;
    (2)眼睛朝向的中心center,(就是眼睛朝哪里看);
    (3)头的方向up。
    任何一点经过视图变换后都会转化到眼睛坐标系下。具体地说,眼睛坐标系的三个轴分别是:
    (1)z轴: F=center-eye;(要归一化)
    (2)x轴: S=cross(F,up);(这里是叉乘,也要归一化)
    (3)y轴: U=cross(S,F)。
    此时,eye的位置就是原点了。那么对于任意一点P(px,py,pz),在新坐标下的三个点分别是:
    px=dot(p-eye,S);(这里是点乘)
    py=dot(p-eye,U);
    pz=dot(p-eye,F)

    所以可得变换矩阵为:

    不过在opengl的坐标系下。z轴的方向其实是垂直屏幕向外的,所以与我们上面的F是相反的。因此实际的变换矩阵是下面这样子:

    这样的变换矩阵,其实对于真正能看到的点,变换后它的z坐标应该是一个负的值。

    透视投影

    透视投影的输入为
    (1)宽度width
    (2)高度height
    (3)近裁面near
    (4)远裁面far。
    经过透视投影变换后的点的坐标,xyz都在[-1,1]。(不在这个范围内的将被opengl裁剪掉)。而且这里输入的点一般是经过视图变换的点,因此点的z坐标是个负值。



    如上图所示,设一个点的坐标是(x,y,z),变换之后的坐标为$(x_{proj},y_{proj},z_{near})$。那么由三角形相似可得:

    $frac{z_{near}}{-z}=frac{y_{proj}}{y}=frac{x_{proj}}{x}$

    所以

    $y_{proj}=frac{z_{near}cdot y}{-z}$

    $x_{proj}=frac{z_{near}cdot x}{-z}$
    然后将$y_{proj},x_{proj}$变换到[-1,1]之间,即$y_{proj}=frac{z_{near}cdot y}{-zcdot width/2}$,$x_{proj}=frac{z_{near}cdot x}{-zcdot height/2}$。

    下面我们来讨论变换后的z坐标。由于在远裁面将被映射到1,近裁面将被映射到-1,设z的变换公式为$f(z)=frac{Az+B}{-z}$,$-z$的意思是最后的齐次坐标是$-z$,归一化的时候用的是$-z$。那么有:$left{egin{matrix}frac{A(-cdot z_{near})+B}{-(-z_{near})}=-1\ frac{A(-cdot z_{far})+B}{-(-z_{far})}=1end{matrix} ight.$
    解得:$left{egin{matrix}A=-frac{z_{near}+z_{far}}{z_{far}-z_{far}}\ B=-frac{2z_{near}z_{far}}{z_{far}-z_{near}}end{matrix} ight.$
    令$X=frac{z_{near}}{width/2} $,$Y=frac{z_{near}}{height/2} $最后得到变换矩阵为:
    $egin{bmatrix}X & 0 & 0 & 0 \ 0 & Y & 0 & 0 \ 0 & 0 & A & -1\ 0 & 0 & B & 0end{bmatrix}$


    另外,有时候计算透视投影时输入是长宽比aspect和视野的角度Fov(y轴的角度)。这里可以想办法计算出width和height的表达式,带入上面的变换矩阵。过程略去了。最后计算的$X=frac{1}{aspectcdot tan(frac{Fov}{2})}$,$Y=frac{1}{tan(frac{Fov}{2})}$


    正交投影



    正交投影的输入为left,right,top,bottom,far,near。
    对于x方向来说,设插值方程为$fx(x)=Ax+B$,那么有:$left{egin{matrix}A cdot left +B=-1\ A cdot right +B=1end{matrix} ight.$,解得:$left{egin{matrix}A=frac{2}{right-left}\ B=-frac{right+left}{right-left}end{matrix} ight.$

    y方向同理。

    对于z方向来说,$fz(-near)=-1,fz(-far)=1$。

    最后得到变换矩阵为:
    $egin{bmatrix}Ax & 0 & 0 &0 \ 0 & Ay & 0 &0 \ 0 & 0 & Az & 0\ Bx & By& Bz &1 end{bmatrix}$

    其中

    $Ax=frac{2}{right-left}$

    $Bx=-frac{right+left}{right-left}$

    $Ay=frac{2}{top-bottom}$

    $By=-frac{top+bottom}{top-bottom}$

    $Az=-frac{2}{far-near}$

    $Bz=-frac{far+near}{far-near}$

  • 相关阅读:
    NPM 重新回炉
    构建工具
    工作的环境部署
    Proxy 代理
    Promise 的 用法及实现
    JS 的 继承
    动态规划——LCS
    矩阵连乘——动态规划
    线段树&树状数组
    SpringAOP
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/6035737.html
Copyright © 2020-2023  润新知