标题

前面记录了3D世界如何绘制,今天讨论一下3D世界怎么呈现到屏幕?

1.(模型视图矩阵)model-view matirx

模型矩阵: 用于描述物体在3D世界中的位置,原理是:把模型上所有的顶点从模型本地坐标系变换(乘以模型矩阵)到世界坐标系.

视图矩阵: 作用是变换整个3D世界到摄像机空间.

(PS:opengl是右手左边系,所以OSG也是右手坐标系,Opengl默认摄像机位置在世界中心(0,0,0)的位置,摄像机默认朝向z轴的负方向.)

但是Opengl中没有把模型矩阵和视图矩阵分离开来,而是用统一的一个矩阵表示,三维物体从本地左边系到摄像机坐标系的变换---模型视图矩阵

//变换向量v到摄像机空间结果为Ve
Ve = V * modelViewMatirx;//OSG中矩阵是以行为主(opengl是以列为主),所以向量和矩阵的乘法规则是向量在前矩阵在后

2.(投影矩阵)projection matrix

投影矩阵:是把摄像机空间的三维模型投影显示到二维空间.今天重点介绍一下投影矩阵的原理,以为投影矩阵的理解对于三维开发者有非常重要的意义.

透视投影的原理:

在计算机图形学领域透视投影是作为一种将三维坐标投影为二维坐标的方法,最常用的是正交投影和透视投影.正交投影可以理解为简单的把三维物体沿着摄像机的方向压扁成为二维平面的过程,而透视投影是为了把三维世界更加真实的表现在二维平面的一种算法.

首先要想透视投影成立,需要三个因素:观察者\投影平面\被投影三维物体.三者关系是:假设人眼即为观察者,我们观察的是三维模型在投影平面上的投影,可以用图来表示:

假设三维世界中有一条经过X点的射线R,X和视点的连线在视平面(也是投影平面)上的交点是Xp,那么Xp即为X点在视平面上的投影.那么射线R上的所有点都可以依照上面的方法在投影平面上找到对应的一点Xp,所有的Xp点就构成了射线R的透视投影后的射线Rp.无论三维模型多复杂,投影的方法都是一样的,如下图:

透视投影在原理上对于投影平面的大小以及摄像机的位置都是没有限制的.只是在计算机图形学中,我们需要将三维世界的物体投影到各种屏幕,所以投影平面成为了矩形.并且由于计算效率问题,我们需要指定一个最远平面在三维世界中.并且摄像机的视角也是固定的.所以我们可以根据上面的一段话理解为,计算机图形学是把投影的范围退化成为了一个棱台----这就是透视投影的视截体.

关于投影矩阵的推导.

对称的视锥体:中心对称的视锥体,zz轴位于视锥体的中心;

不对称的视锥体:z轴不在视锥体的中央,就好比我们靠近窗户去观察景色,但没有正对窗户中心。

这里我们也分这两种情况来推导:

情况一:对称的视锥体

第一步:根据相似三角形的性质,有:

第二步:为使视景体内的顶点投影到近平面上,其坐标映射到[-1.0, 1.0]范围内,投影后的点要分别除以width / 2和height / 2,其中width,height分别为近投影平面的宽度与高度,根据第一步结果,有:

第三步:这一步推导深度部分变换,根据第一步和第二步,可以假设投影矩阵具有如下形式:

得到zproj=(Az+B)/z,或Az+B=zzproj 将远平面和近平面z坐标代入上式得(注意注意:在这里,视景体内的深度坐标投影之后,有zproj∈[−1,1]):

得到:

至此,对称视锥体的透视投影变换矩阵就推导完毕了,最终得到的透视投影变换矩阵为:

情况二:不对称的视锥体

这一情况看起来较上面复杂一些,其实也没复杂多少,首先,深度投影没什么变化;其次,对于不对称视锥体的xx和yy方向上的投影,只要在对称视锥体的投影基础上平移一下即可,其实只有第一步和第二步有所区别,如下:

第一步:投影,按如下方式进行平移lx和ly,

第二步:将近平面(注:z=−znear)的左、右边缘x坐标代入(1)得:

得:

同样,将近平面的上、下边缘y坐标代入(2)得:

这样,最终的投影变换矩阵为:

OpenGL中相关API就需要指定这些参数,来构建投影矩阵,如下:

void glFrustum(    GLdouble left,GLdouble right,GLdouble bottom,GLdouble top,GLdouble znear,GLdouble zfar);
//top      ——近平面上边缘离中心的距离
//bottom    ——近平面下边缘离中心的距离
//left     ——近平面左边缘离中心的距离
//right    ——近平面右边缘离中心的距离
//znear     ——近平面离视点的距离
//zfar     ——元平面离视点的距离

参数见上,另外还有一个,本质也是一样的,它应该是设置对称的视锥体的透视投影矩阵,即:

void gluPerspective(    GLdouble fovy,GLdouble aspect,GLdouble zNear,GLdouble zFar);
//fovy        —— y方向上的视角
//aspect      —— 宽高比
//zNear       —— 近平面离视点距离
//zFar        —— 远平面离视点距离

通过fov和aspect,可以求出宽度和高度,进而求出透视投影矩阵。

3.转换为屏幕坐标

透视投影后,三维模型就会投影到投影平面,投影平面的坐标系模型(x轴向右,y轴向上,原点在平面中心)如下图

而我们的屏幕的坐标系模型(原点在左上角,x轴向右,y轴向下)如下图

令视平面坐标系中的点(xp, yp)对应于屏幕坐标系中的点(xs, ys),它们的变换关系如下:

由上面可知,设视平面的宽度为Wp,高度为Hp;屏幕的宽度为Ws,高度为Hs.视平面中的(0,00, 0)点对应于屏幕坐标系中的中心点(0.5*Ws-0.5, 0.5*Hs-0.5)点对应屏幕坐标系中心点(0.5*Ws-0.5,0.5*Hs-0.5)(PS:由于屏幕坐标系是离散坐标系,所有屏幕右下点的坐标为(Ws-1, Hs-1),而不是(Ws, Hs));另外,视平面的(-0.5*Wp, -0.5*Hp)对应于屏幕的(0, 0)点。将上述两种取值代入变换方程可以得出:

这样就完成了3D世界到屏幕的整个过程.

转自:https://www.zhihu.com/column/c_187589347

osg-3D世界到屏幕相关推荐

  1. delphi 实现屏幕旋转代码_代码检查 | 如何用Processing实现3D世界

    一花一世界,一叶一菩提.每个人眼中的花是不一样的,每个人眼中的世界也是不一样的 .昔时佛祖拈花,惟迦叶微笑,既而步往极乐.在菩提树下,从一朵花中便能悟出整个世界,最终得升. 今天就来给大家介绍日本先生 ...

  2. NeHe OpenGL第十课:3D世界

    NeHe OpenGL第十课:3D世界 加载3D世界,并在其中漫游: 在这一课中,你将学会如何加载3D世界,并在3D世界中漫游.这一课使用第一课的代码,当然在课程说明中我只介绍改变了代码. 这一课是由 ...

  3. NeHe OpenGL教程 第十课:3D世界

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  4. 基于mfc的图形学实例_前端图形学(二十)——退后!!我要开始进入3D世界了...

    欢迎来到[畅哥聊技术]前端图形学相关技术文章,更多精彩内容持续更新中,敬请关注. 写在前面 先说好,今天所说的3D并不是大家惯性思维说3D就想到了WebGL,那么接下来的文章都是基于Canvas2d来 ...

  5. D3D坐标系统下3D世界坐标映射到2D屏幕坐标的平移矩阵

    D3D坐标系统下3D世界坐标映射到2D屏幕坐标的平移矩阵,有需要的朋友可以参考下. D3D中绘画3D模型基本上就是靠3个矩阵World, View, Projection来联合进行模型位置定位.视角定 ...

  6. 在3D世界中的获取鼠标的位置

    原理 电脑的鼠标是在屏幕的2D坐标上运动的,而我们要获取的是3D世界中的一个三维坐标,在游戏引擎中的实现原理如下: 先获取鼠标在屏幕上的2D坐标. 结合摄像机平面计算出这个点在3D世界中的坐标. 从这 ...

  7. Qt OpenGL 加载3D世界,并在其中漫游

    这次教程中,我将教大家如何加载一个3D世界,并在3D世界中漫游.这相较于我们只能创造一个旋转的立方体或一群星星时有很大的进步了,当然这节课代码难度不低,但也不会很难,只要你跟着我慢慢一步一步来. 一个 ...

  8. 虚拟世界由此开始 追逐3D世界的脚步zz

    十一年前,我们在争论究竟是256色画面好还是16位色彩深度画面好.十一年后的今天,我们争论的是超采样抗锯齿好还是多重采样抗锯齿好.十一年前,我们在争论是否可能实现32位渲染,十一年后,我们争论的是需不 ...

  9. 第1部分: 游戏引擎介绍, 渲染和构造3D世界

    原文作者:Jake Simpson 译者: 向海 Email:GameWorldChina@myway.com  ------------------------------------------- ...

最新文章

  1. 伍六七带你学算法 入门篇 ——最大子序和
  2. 源码阅读:AFNetworking(八)——AFAutoPurgingImageCache
  3. UA SIE545 优化理论基础4 对偶理论简介3 强对偶
  4. ACE proactor example
  5. Redis 从入门到起飞(下)
  6. 绿色运营,数据中心还得靠自动化
  7. Microsoft Dynamic CRM 2013安装
  8. java模糊查询比对方法_Java多条件和模糊查询
  9. Bellman_Ford算法(求一个点到任意一点的最短距离)
  10. QThread的用法
  11. 应届生面试自我介绍该怎么说?
  12. 【Python】24点 一行代码解决
  13. xcode 免cleanup build
  14. git 误删文件如何恢复
  15. 清华大学计算机学院张远,计算机系2019-2020学年度学生代表大会顺利召开
  16. 计算机编程情话,程序员的土味情话~(表白代码第二波)
  17. python增删改查mysql_python之mysql的增删改查
  18. KVM基于Web部署虚拟主机
  19. 互斥量、临界区、信号量、事件标志组和消息邮箱(转)
  20. Java 比较日期/时间的大小

热门文章

  1. java 生产者消费者_基于JAVA的生产者消费者问题
  2. 训练集 验证集_训练与验证、测试集数据分布不同的情况
  3. python时间序列数据分析统计服_python数据分析之:时间序列二
  4. centos7不识别固态硬盘_固态硬盘分区与不分区哪个好【详细介绍】
  5. 囧囧西游之大闹天宫java_《囧囧西游之大闹天宫》攻略(1)
  6. c语言三个数从小到大排序/输出_C语言经典100题(6)
  7. npm install 安装软件,出现 operation not permitted, mkdir 'C:\Program Files\nodejs\node_cache'...
  8. WPF中使用WindowChrome自定义窗口中遇到的最大化问题
  9. Bootstrap(导航条)
  10. python3 scarpy