zoukankan      html  css  js  c++  java
  • opengl 教程(12) 投影矩阵

    原帖地址:http://ogldev.atspace.co.uk/www/tutorial12/tutorial12.html

         现在我们开始学习如何把三维物体投影到二维*面上,同时保持它的深度。通常的投影包括*行投影和透视投影:*行投影比较简单,就是把顶点垂直的投向投影*面,常用在cad或者机械制图中。另外一种投影是透视投影,这种投影能较好的使二维投影显示立体感,因为人眼观看物体符合透视原理,透视原理也是学美术的人的必修课程。最常见的透视原理表现形式就是三维世界的*行线在透视几何中是相交的,它们的交点叫做灭点,比如我们观察*行的马路,在远处会发觉它们越来越靠*,直至相交在一起。

          本教程我们将产生投影变化矩阵,所谓投影矩阵,就是把视觉空间的frustum(视锥体)投影到一个长方体中,这需要我们提供四个参数:

    1. 投影区域(四边形)的宽高比。
    2. 摄像机观察垂直视角的大小。
    3. *z*面到视点的距离。
    4. 远z*面到视点距离。 

    推导投影矩阵的过程见我转贴的另外一篇文章,比本教程原文还要详细:http://www.cnblogs.com/mikewolf2002/archive/2012/11/25/2787265.html

    最终的投影矩阵为:

    其中ar为投影*面(四边形)的宽高比,alpha为垂直观察视角,NearZ,FarZ为*z和远z*面。

    12_11

          投影矩阵乘以顶点位置,这时得到的顶点坐标就为裁剪空间,再经过透视除法后,就是所谓的归一化裁剪空间。前面的教程中,我们没有做任何投影变化,直接在裁剪空间定义顶点,进行操作。

          主要变化代码,增加了一个初始化透视矩阵的函数,该函数会根据传入的参数宽高比、垂直视角、*z*面和远z*面值计算出透视矩阵。

    void Pipeline::InitPerspectiveProj(Matrix4f& m) const>
    {
    const float ar = m_persProj.Width / m_persProj.Height;
    const float zNear = m_persProj.zNear;
    const float zFar = m_persProj.zFar;
    const float zRange = zNear - zFar;
    const float tanHalfFOV = tanf(ToRadian(m_persProj.FOV / 2.0));
    m.m[0][0] = 1.0f / (tanHalfFOV * ar);
    m.m[0][1] = 0.0f;
    m.m[0][2] = 0.0f;
    m.m[0][3] = 0.0f;
    m.m[1][0] = 0.0f;
    m.m[1][1] = 1.0f / tanHalfFOV;
    m.m[1][2] = 0.0f;
    m.m[1][3] = 0.0f;
    m.m[2][0] = 0.0f;
    m.m[2][1] = 0.0f;
    m.m[2][2] = (-zNear - zFar) / zRange;
    m.m[2][3] = 2.0f * zFar * zNear / zRange;
    m.m[3][0] = 0.0f;
    m.m[3][1] = 0.0f;
    m.m[3][2] = 1.0f;
    m.m[3][3] = 0.0f;
    }

    定义了一个结构来保存透视投影参数。

    struct {
        float FOV;
        float Width;
        float Height;
        float zNear;
        float zFar;
    } m_persProj;

    最终计算变化矩阵时候,会乘上投影矩阵,注意乘的顺序,位置向量在最右边,是列向量

    m_transformation = PersProjTrans * TranslationTrans * RotateTrans * ScaleTrans;

    在渲染函数中,我们增加了设置透视矩阵函数的调用

    p.SetPerspectiveProj(30.0f, WINDOW_WIDTH, WINDOW_HEIGHT, 1.0f, 1000.0f);

    程序执行后的界面如下:

    image

  • 相关阅读:
    VC 常见问题百问
    python windows 环境变量
    Check server headers and verify HTTP Status Codes
    Where are the AES 256bit cipher suites? Please someone help
    outlook 如何预订会议和会议室
    安装Axis2的eclipse插件后,未出现界面
    windows 环境变量
    python 时间日期处理汇集
    openldap学习笔记(使用openldap2.3.32)
    set p4 environment in windows
  • 原文地址:https://www.cnblogs.com/mikewolf2002/p/2861758.html
Copyright © 2011-2022 走看看