zoukankan      html  css  js  c++  java
  • 矩阵的应用

    矩阵的应用

    OpenGL 中常见的矩阵如模型矩阵、视图矩阵、投影矩阵简单笔记。

    模型矩阵

    模型矩阵是相对于世界坐标系的,包含一系列*移、缩放、旋转的变换信息的矩阵。它与点的位置没有任何关系。基本的模型矩阵有*移矩阵、缩放矩阵、旋转矩阵,模型矩阵左乘模型矩阵,还是模型矩阵。点坐标左乘模型矩阵就能得到最终变换的坐标。因此,多个顶点能共用同一个模型矩阵,一般一个模型里的所有顶点都共用一个模型矩阵。

    *移矩阵

    \[ \left[ \begin{matrix} 1 & 0 & 0 & X_t \\\\ 0 & 1 & 0 & Y_t \\\\ 0 & 0 & 1 & Z_t \\\\ 0 & 0 & 0 & 1 \end{matrix} \right] \]

    例如:Vec(2,2,0) 沿着X轴*移3,沿着Y轴*移3,则:

    \[\left[ \begin{matrix} 1 & 0 & 0 & 3 \\\\ 0 & 1 & 0 & 3 \\\\ 0 & 0 & 1 & 0 \\\\ 0 & 0 & 0 & 1 \end{matrix} \right] \left[ \begin{matrix} 2 \\\\ 2 \\\\ 0 \\\\ 1 \end{matrix} \right] = \left[ \begin{matrix} 5 \\\\ 5 \\\\ 0 \\\\ 1 \end{matrix} \right] \]

    缩放矩阵

    \[\begin{bmatrix} S_x & 0 & 0 & 0 \\\\ 0 & S_y & 0 & 0 \\\\ 0 & 0 & S_z & 0 \\\\ 0 & 0 & 0 & 1 \end{bmatrix} \]

    旋转矩阵

    点绕z轴旋转:

    \[\begin{bmatrix} \cos\theta & -\sin\theta & 0 & 0 \\\\ \sin\theta & \cos\theta & 0 & 0 \\\\ 0 & 0 & 1 & 0 \\\\ 0 & 0 & 0 & 1 \end{bmatrix} \]

    点绕x轴旋转:

    \[\begin{bmatrix} 1 & 0 & 0 & 0 \\\\ 0 & \cos\theta & -\sin\theta & 0 \\\\ 0 & \sin\theta & \cos\theta & 0 \\\\ 0 & 0 & 0 & 1 \end{bmatrix}\]

    点绕y轴旋转:

    \[\begin{bmatrix} \cos\theta & 0 & -\sin\theta & 0\\\\ 0 & 1 & 0 & 0\\\\ \sin\theta & 0 & \cos\theta & 0 \\\\ 0 & 0 & 0 & 1 \end{bmatrix}\]


    视图矩阵

    概念:视图矩阵是本地坐标系在世界坐标系中的变换的模型矩阵的逆矩阵,因此视图矩阵也是可以分为*移、缩放、旋转的。
    好吧,说点人话,一个摄像机,在世界坐标系中,经过模型矩阵M1(模型变换),从原点沿着X轴正方向前进10单位。这时候,摄像机的视图矩阵为M2,而且M2M1的逆矩阵。M2的几何含义:假设摄像机一直原地不动,而是这个世界以M2为模型矩阵进行变换,往后移动了10个单位,也就是摄像机在世界坐标系下的*移、缩放、旋转等变换的反向过程。
    作用:获得相对坐标(本地坐标)。
    将视图矩阵左乘一个物体最终的模型矩阵,得到的矩阵就是所谓的“模型视图矩阵”。“模型视图矩阵”左乘一个世界坐标系下的坐标点,得到的是相对于本地坐标系的坐标点。
    举个例子:一个摄像机和一个物体,一起同样的速度和方向,从世界坐标系的原点沿着X轴的正方形移动了10个单位。摄像机的视图矩阵左乘物体的模型矩阵(模型视图矩阵)表示的含义可以理解为:世界往X轴的负方向移动了10个单位,然后在沿x轴正方向移动10个单位,因此任何一个坐标点乘以这个模型视图矩阵,都不会发生变化,明显,摄像机和物体相对静止的。


    投影矩阵

    投影矩阵就是把三维空间投影到二维的空间。方式有正交和透视两种。

    正交投影矩阵

    • 作用:正交投影矩阵可以把虚拟坐标转换回归一化设备坐标(正交投影矩阵乘以虚拟坐标)。
    • 归一化设备坐标:在OpenGL里,一切物体都要映射到X、Y轴和Z轴的[-1,1]范围内,这个范围内的坐标被称为归一化设备坐标,其独立于屏幕实际的尺寸。归一化设备坐标假定坐标空间是个正方形。
    • 虚拟坐标空间:为了让屏幕形状考虑进来,把宽和高中较小的一个的范围定在[-1,1]内,另外一个根据屏幕尺寸比例调整为较大的范围。

    正交投影矩阵如下:

    \[ \left[ \begin{matrix} \frac{2}{right-left} & 0 & 0 & -\frac{right+left}{right-left} \\\\ 0 & \frac{2}{top-bottom} & 0 & -\frac{top+bottom}{top-bottom} \\\\ 0 & 0 & -\frac{2}{far-near} & -\frac{far+near}{far-near} \\\\ 0 & 0 & 0 & 1 \end{matrix} \right] \]

    注意:使用的是左手坐标系还是右手坐标系,这两者的Z轴是相反的。
    其实在一个顶点着色器的顶点位置(gl_Position)变为归一化设备坐标前,还会做透视除法(xyz都除以w)。

    透视投影矩阵

    透视投影矩阵最大的作用是产生正确的w值。w值可以理解为距离,w值越大,离中心点越*。

    透视投影矩阵

    \[ \left[ \begin{matrix} \frac{α}{width/height} & 0 & 0 & 0 \\\\ 0 & α & 0 & 0 \\\\ 0 & 0 & -\frac{far+near}{far-near} & -\frac{2\*far\*near}{far-near} \\\\ 0 & 0 & -1 & 0 \end{matrix} \right] \]

    其中α是焦距:

    \[α = \frac {1} {tan(FOV/2)} \]

    FOV是相机的垂直视角,而不是水*视角
    屏幕宽度
    height:屏幕高度
    far: 到远处*面的距离(>0 && > near)
    near: 到*处*面的距离(>0)


    虚拟世界的顶点画到在屏幕上经过的变换过程

    变换后的坐标 = 视口矩阵 x 投影矩阵 x 视图矩阵 x 模型矩阵 x 模型点坐标

  • 相关阅读:
    [VC++]利用VS2005进行dump文件调试
    Release和Debug模式下成员变量初始化问题
    JDBC与C++的DB访问性能
    Log4J与LogBack的性能比较
    WinRar命令行参数
    玩弄C++:回调一个类成员函数
    如何将一个模板类A作为模板类B的模板参数
    HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTup
    HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTup
    使用jQuery发送POST,Ajax请求返回JSON格式数据
  • 原文地址:https://www.cnblogs.com/kelin/p/6104736.html
Copyright © 2011-2022 走看看