在游戏开发中,一个物体模型从它自身的坐标系转换至我们在屏幕上所见的样子,需要进行一系列的坐标变换以及其他的操作。该过程称为渲染管线。以OpenGL为例:

该过程在以前是被封装的,不能访问。但是现在我们可以对该过程进行更改,所以该过程现在也称为OpenGL的可编程渲染管线。

而我们把顶点数据发送给我们的顶点缓冲后,在顶点着色器中,我们需要完成一个从模型本地坐标变换到投影坐标到变换。

如图所示,我们首先需要将本地空间,通过使用模型矩阵将其转换至世界空间。再通过视口矩阵,将其转换为视口空间。之后再乘上投影矩阵,就将视口空间转换为裁剪空间。最后进行裁剪等操作使裁剪空间转换为屏幕空间。

投影矩阵

改文章重点讲解使用投影矩阵的原因,以及投影矩阵的数学原理。计算机的显示屏是一个2D平面。一个3D的场景需要通过投影矩阵渲染在2D图像中。投影矩阵使用了投影变换。首先,它将所有的视口坐标转换至剪切坐标。然后这些裁剪坐标还会通过除以裁剪坐标的w分量来转换成标准设备坐标(NDC). 投影矩阵分为透视(Perspective)投影和正交(Orthographic)投影。

接下来将会阐述如何通过6个约束参数:leftrightbottomtopnear and far 来建立投影矩阵。我们要先注意平截头体的裁剪是在裁剪空间进行的,仅仅在除以Wc之前。在裁剪坐标中,Xc,Yc,Zc都要和Wc进行对比,若裁剪坐标小于-Wc或者大于Wc,则被裁减。保留:。当被裁减过后,OpenGL会自动生成被裁减的边缘。

透视投影

在透视投影中,截断的锥体平截头体(视口坐标)中的3D点被映射到立方体(NDC); 从[l,r]到[-1,1]的x坐标范围,从[b,t]到[-1,1]的y坐标和来自[-n,-f]的z坐标 到[-1,1]。

请注意,视口坐标是在右手坐标系中定义的,但NDC使用左手坐标系。 也就是说,原点处的相机沿着视口空间中的-Z轴看,但它在NDC中沿着+ Z轴看。

在OpenGL中,视口空间中的3D点被投影到近平面(投影平面)上。 下图显示了视口空间中的点(Xe,Ye,Ze)如何投射到近平面上的(Xp,Yp,Zp)。

从平截头体的顶视图,视口空间的X坐标,Xe被映射到Xp,其通过使用相似三角形的比率来计算;

然后通过相似的方法计算平截头体的左视图中的Yp;

注意Xp和Yp都取决于Ze; 它们与-Ze相反。 换句话说,它们都被-Ze除。 这是构建投影矩阵的第一个线索。 在通过乘以投影矩阵变换适口坐标空间(view space)之后,裁减坐标仍然是齐次坐标。 它最终通过除以剪辑坐标的W分量变为标准设备坐标(NDC)。

因此,我们可以将裁减坐标的w分量设置为-Ze。 并且,投影矩阵的第4行变为(0, 0,-1, 0)。

接下来,我们将Xp和Yp映射到具有线性关系的NDC的Xn和Yn; [l,r]⇒[-1,1]和[b,t]⇒[-1,1]。

然后,我们将Xp和Yp替换为上述等式。

请注意,我们使每个方程的两个项都被-Ze整除为透视除法(Xc / Wc,Yc / Wc)。 我们将Wc设置为-Ze,括号内的术语变为剪辑坐标的Xc和Yc。

从这些方程式中,我们可以找到投影矩阵的第1行和第2行。

现在,我们只有第3行的投影矩阵需要解决。 寻找Zn与其他的略有不同,因为视口空间中的Ze总是被投射到近平面上的-n。 但是我们需要用于裁减和深度测试的唯一Z值。 另外,我们应该能够取消投影(即逆变换)它。 因为我们知道Z不依赖于X或Y值,所以我们借用W分量来找到Zn和Ze之间的关系。 因此,我们可以像这样指定投影矩阵的第3行。

在视口空间中,We等于1。因此,等式变为:

为了找到系数A和B,我们使用(Ze,Zn)关系; 如(-n,-1)和(-f,1),并将它们放入上面的等式中。

为了求解A和B的等式,重写B的等式(1);

将方程(1')代入方程(2)中的B,然后求解A;

将A代入方程(1)中以算出B;

我们得到了A和B。因此Ze和Zn之间的关系变成了:

最后,我们找到了投影矩阵的所有信息。 完整的投影矩阵是:

该投影矩阵用于一般的截头体。 如果观察体积是对称的,那么它就是,,并且可以简化为:

在我们继续之前,请再次看一下Ze和Zn,eq.(3)之间的关系。 您注意到它是一个有理函数,并且是Ze和Zn之间的非线性关系。 这意味着近平面的精度非常高,但远平面的精度非常低。 如果范围[-n,-f]越来越大,则会导致深度精度问题(z-fighting); 远处平面周围的小的Ze变化不会影响Zn值。可以使 n和f之间的距离应尽可能短,以最小化深度缓冲精度问题。

这个非线性的特点在游戏中会有非常大的优点,因为我们在进行深度测试的时候,距离摄像机近的点在深度测试具有非常高的精度,而远处的点在深度测试的时候会有较低的精度。而这正是我们需要的。

正交投影

构造用于正投影的投影矩阵比透视模式简单得多。

视口空间中的所有Xe,Ye和Ze分量线性映射到NDC。 我们只需要将矩形体积缩放到立方体,然后将其移动到原点。 让我们使用线性关系找出投影矩阵的元素。

由于正交投影不需要W分量,因此投影矩阵的第4行保持为(0,0,0,1)。 因此,正交投影的完整投影矩阵是:

如果观察体积是对称的,,则可以进一步简化。

OpenGL中投影矩阵(Projection Matrix)详解相关推荐

  1. ModelMatrix、ModelViewMatrix、ProjectionMatrix、NormalMatrix模型矩阵、模型视图矩阵、投影矩阵、正规矩阵详解

    ModelMatrix.ModelViewMatrix.ProjectionMatrix.ModelMatrix模型矩阵.模型视图矩阵.投影矩阵.正规矩阵详解 1. 前言 在openGL经常用到Mod ...

  2. 【CG】针孔相机矩阵(Camera Matrix)详解

    0. 相机矩阵 Camera Matrix 小孔成像模型 成像过程 1. 相机矩阵的分解 齐次坐标下,物体的物理坐标是 [x,y,z,1]′ [ x , y , z , 1 ] ′ [x,y,z,1] ...

  3. 深入理解OpenGL之投影矩阵推导

    深入理解OpenGL之投影矩阵推导 OpenGL流水线中的投影矩阵以及坐标变换 OpenGL中,投影矩阵在Vertex shader中使用,用于变换顶点.一般和Model, View矩阵结合成MVP矩 ...

  4. android 图片浏览器旋转,OpenGL纹理旋转及翻转问题详解

    大家好,我是程序员kenney,今天给大家讲解一下Android上OpenGL开发可能会遇到的一些纹理旋转及翻转的问题,其中有些原理在其它平台上如ios,osx上也是类似的.纹理旋转的问题一定要搞清楚 ...

  5. python创建列向量_关于Numpy中的行向量和列向量详解

    关于Numpy中的行向量和列向量详解 行向量 方式1 import numpy as np b=np.array([1,2,3]).reshape((1,-1)) print(b,b.shape) 结 ...

  6. 【5年Android从零复盘系列之二十】Android自定义View(15):Matrix详解(图文)【转载】

    [转载]本文转载自麻花儿wt 的文章<android matrix 最全方法详解与进阶(完整篇)> [5年Android从零复盘系列之二十]Android自定义View(15):Matri ...

  7. Unity Shader中各部分定义内容详解

    Unity Shader中各部分定义内容详解 样板 Shader "Practice/Unlit/SimpleUnlit" {Properties{_MainTex (" ...

  8. Eigen Matrix 详解

    Eigen Matrix 详解 在Eigen中,所有的matrices 和vectors 都是模板类Matrix 的对象,Vectors 只是一种特殊的矩阵,行或者列为1. Matrix的前三个模板参 ...

  9. 【转】OpenGL随笔(1)—— mipmap 详解

    [转]OpenGL随笔(1)-- mipmap 详解 注:本文使用的所有 OpenGL 函数来自 OpenGL 4.5,优先使用 DSA. 使用 mipmap 时,OpenGL 根据被映射对象的大小( ...

最新文章

  1. 聊一聊工作中如何优雅的通过TDD方式来维护一个高质量的NPM包
  2. mysql为什么使用b 树作为索引_为什么Mysql用B+树作为索引
  3. java调用lingo_使用Lingo增强JMS
  4. linu - 系统延时与定时任务
  5. 编译 Apache Karaf 2.2.9遇到找不到jar包问题的解决方案
  6. java吧 博客系统_【Java】SpringMVC + Mybatis 实现的个人博客系统
  7. Notification使用详解之四:由后台服务向Activity发送进度信息
  8. shell中Connection closed by foreign host问题解决
  9. html把毫秒转换成年月日,JS实现获取毫秒值及转换成年月日时分秒的方法
  10. linux下各种player不显示mkv字幕的解决
  11. 愿你我,能被这世界温柔以待
  12. 数据处理的基本方法--简要介绍
  13. Nginx介绍及原理简单分析
  14. 计算机日常故障DIY维修有哪些,计算机维护 DIY 完全手册
  15. 我用python分析买房数据
  16. java加载tensorflow训练的PB模型记录
  17. sublime安装和使用
  18. https://camo.githubusercontent.com/a25916ccc96abf4f949ae55a3fc8b0108ac578a8/687474703a2f2f3764396f30
  19. iOS分辨率的那些事儿
  20. Haar Wavelet Transformation

热门文章

  1. vuejs对象更新渲染_vue 数组和对象渲染问题
  2. python 字节码 优化_字节码优化
  3. Spring-Data-JPA入门--增删改查1
  4. Java摇骰子比大小_还在摇骰子比大小?这几款火热的KTV喝酒游戏你值得收藏
  5. java解析excel文件处理数字成像_Java处理Excel工具,POI解析,使用InputStream读取文件...
  6. Sphinx——自动生成Python文档
  7. java执行完main就结束了吗_为什么main方法中执行完第一个方法完之后,后面的代码都不执行了?...
  8. python脚本 游戏赚金币_python捡金币游戏(上)
  9. java 分词词频_利用word分词来对文本进行词频统计
  10. springrain java_springrain