OpenGL-ES 学习(4)---- OpenGL-ES 坐标体系

坐标体系

我们知道 OpenGL -ES 坐标系中每个顶点的 x,y,z 坐标都应该在 -1.0 到 1.0 之间,超出这个坐标范围的顶点都将不可见。
将一个物体(图像)渲染到屏幕上,通常经过将物体坐标转换为标准化设备坐标,然后再将标准化设备坐标转化为屏幕坐标的过程。
(将物体坐标转换为标准化设备坐标,再将标准化设备坐标转换为屏幕坐标的过程)

该过程通常涉及多个坐标系统的变换,将所有顶点转换为片段之前,顶点需要处于不同的坐标系统进行计算,对我们来说比较重要的有 5 个坐标系统:

  • 局部空间(Local Space)
  • 世界空间(World Space)
  • 观察空间(View Space)
  • 裁剪空间(Clip Space)
  • 屏幕空间(Screen Space)

five_space

局部空间

局部空间 (Local Space) 是指对象所在的坐标空间,坐标原点由你自己指定,模型的所有顶点相对于你的对象来说都是局部的

局部坐标系空间是指物体所在的坐标系空间,即对象最开始所在的地方。例如在一个建模软件中创建了一个立方体。创建的立方体的原点有可能位于(0, 0, 0),即便它有可能最后在程序中处于完全不同的位置。甚至有可能创建的所有模型都以(0, 0, 0)为初始位置,然而它们会最终出现在世界的不同位置。所以,模型的所有顶点都是在局部系空间中,它们相对于物体来说都是局部的。

对象相对于局部顶点的坐标,每个顶点都相对于自己的参考系。

世界空间

在世界空间(World Space)主要实现对象的平移、缩放、旋转变换,将它们放在我们指定的位置这些变换是通过模型矩阵(Model Matrix)实现的。

如果将局部空间的建模所有的物体导入到程序当中,它们有可能会全挤在世界的原点(0, 0, 0)上,这并不是想要的结果,理想状态下是为每一个物体定义一个位置,从而能在更大的世界当中放置它们。

世界空间中的坐标系正如其名:是指顶点相对于世界的坐标。物体的坐标将会从局部变换到世界空间;
该变换一般是由模型矩阵(Model Matrix)实现。模型矩阵是一种变换矩阵,
它能通过对物体进行位移、缩放、旋转来将它置于它本应该在的位置或朝向。
对物体的旋转,平移,缩放都是在世界空间内进行的。
在 C/C++ 中可以利用 GLM 构建模型矩阵:

glm::mat4 Model = glm::mat4(1.0f); //单位矩阵
Model = glm::scale(Model, glm::vec3(2.0f, 2.0f, 2.0f)); //缩放
Model = glm::rotate(Model, MATH_PI/2, glm::vec3(1.0f, 0.0f, 0.0f)); //沿 x 轴旋转 90 度
Model = glm::translate(Model, glm::vec3(0.0f, 1.0f, 0.0f)); //沿 y 轴正方向平移一个单位

GLM 是 OpenGL Mathematics 的缩写,它是一个只有头文件的库,也就是说我们只需包含对应的头文件就行了,不用链接和编译

观察空间

观察空间(View Space)也被称为 OpenGL-ES 相机空间(定义了相机所在的位置),即从摄像机的角度观察到的空间,它将对象的世界空间的坐标转换为观察者视野前面的坐标。

这通常是由一系列的平移和旋转的组合来平移和旋转场景从而使得特定的对象被转换到摄像机前面,这些组合在一起的转换通常存储在一个观察矩阵(View Matrix)里。
GLM 的实现方式:

glm::mat4 View = glm::lookAt(glm::vec3(0, 0, 3), // Camera is at (0,0,1), in World Space 相机位置glm::vec3(0, 0, 0), // and looks at the origin 观察点坐标glm::vec3(0, 1, 0)  // Head is up (set to 0,-1,0 to look upside-down) 相机 up 方向,即相机头部朝向
);

观察坐标系空间经常被称之OpenGL ES的摄像机视角,所以有时也称为摄像机坐标系空间(Camera Space)或视觉坐标系空间(Eye Space)。
观察坐标系空间是将世界空间坐标转化为用户视野前方的坐标而产生的结果。因此观察坐标系空间就是从摄像机的视角所观察到的空间。
而这通常是由一系列的位移和旋转的组合来完成,平移/旋转场景从而使得特定的对象被变换到摄像机的前方。
这些组合在一起的变换通常存储在一个观察矩阵(View Matrix)里,它被用来将世界坐标变换到观察空间。

裁剪空间

在OpenGL-ES中,裁剪空间(Clip Space)是一个用于表示 3D 场景在 2D 屏幕上投影的坐标系。
它的 x 和 y 轴都是从左到右,从上到下的,而不是从 0 到 1。裁剪空间中的点是用四个坐标值(x, y, z, w)来表示的
,其中 x 和 y 表示点在 x 轴和 y 轴上的坐标,z 表示点到屏幕的距离,w 表示点的齐次坐标。
裁剪空间中的点在经过透视除法之后,就可以得到屏幕上的真实坐标。透视除法是一种将 3D 坐标变换到 2D 屏幕上的方法,它可以将3D空间中的任意点投影到一个正方体的六个面上,然后去掉那些不在正方体内部的点,得到最终可以显示在屏幕上的点。


由投影矩阵创建的观察箱(Viewing Box)被称为平截头体,每个出现在平截头体范围内的坐标都会最终出现在用户的屏幕上。将特定范围内的坐标转化到标准化设备坐标系的过程(而且它很容易被映射到2D观察空间坐标)被称之为 投影 ,因为使用投影矩阵能将3D坐标投影到很容易映射到2D的标准化设备坐标系中。

将世界空间内的坐标转化为标准设备坐标(2D 观察空间坐标)的过程称为投影

透视除法

一旦所有顶点被变换到裁剪空间,最终的操作——透视除法将会执行,在这个过程中将位置向量的x,y,z分量分别除以向量的齐次w分量;
透视除法是将 4D裁剪空间坐标变换为3D标准化设备坐标的过程。这一步会在每一个顶点着色器运行的最后被自动执行。
在这一阶段之后,最终的坐标将会被映射到屏幕空间中(使用 glViewport 中的设定),并被变换成片段。

将观察坐标变换为裁剪坐标的投影矩阵可以为两种不同的形式,每种形式都定义了不同的平截头体(View Box)。可以选择创建一个正射投影矩阵(Orthographic Projection Matrix)或一个透视投影矩阵(Perspective Projection Matrix)。

所以投影矩阵是用于观察空间到裁剪空间的转换

正交投影

正交投影是一种平行投影,投影点与原顶点的连线相互平行,且物体不产生 “近大远小” 的视觉效果。

正交投影矩阵

在 C/CPP 中可以使用 GLM 构建正交投影矩阵

glm::mat4 Projection = glm::ortho(-ratio, ratio, -1.0f, 1.0f, 0.0f, 100.0f); //ratio 一般表示视口的宽高比,width/height// 生成单位矩阵
esMatrixLoadIdentity(&orthographic);// 参数分别表示 left right bottom top nearz farz 实现缩小的效果
esOrtho(&orthographic, -5.0f, 5.0f, -2.0f, 2.0f, -1.0f, 1.0f);// 不做处理和变化
esOrtho(&orthographic, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, 1.0f);// 实现放大中心部分的效果
esOrtho(&orthographic, -0.5f, 0.5f, -0.5f, 0.5f, -1.0f, 1.0f);

根据上面所说,在OpenGL ES中,裁剪空间通常是一个 [-1,1] 的矩形,其中左下角的坐标为 [-1, -1],右上角的坐标为 [1, 1]。这个矩形被称为视口(Viewport),它的大小可以在OpenGL-ES 的初始化函数中设置。

如果设置 ViewSpace Orthographic 投影方式,将 left,top,bottom,up 坐标都设置为之前的一半,则 平行投影后,2D 图片 Z 保持不变,
视口内的图像是被源图像中心区域放大的效果,相反的,设置为之前的 5 倍,则实现的是缩小的效果。
正交投影原理

透视投影

透视投影的投影线相交于一点,可以用来模拟真实世界 近大远小 的视觉效果。
透视投影

对于肉眼直观的感受是,近大远小的,这种视觉效果称之为透视;透视投影要模仿肉眼的这种效果,是使用透视投影矩阵来完成的。这个透视投影矩阵将给定的平截头体范围映射到裁剪空间,除此之外还修改了每个顶点坐标的 w 值,从而使得离观察者越远的顶点坐标 w 分量越大。被变换到裁剪空间的坐标都会在 -w 到 w 的范围之间(任何大于这个范围的坐标都会被裁剪掉)。OpenGL-ES要求所有可见的坐标都落在-1.0到1.0范围内,作为顶点着色器最后的输出,因此,一旦坐标在裁剪空间内之后,透视除法就会被应用到裁剪空间坐标上:

顶点坐标的每个分量都会除以它的 w 分量,距离观察者越远顶点坐标就会越小。这是也是w 分量非常重要的另一个原因,它能够帮助开发者进行透视投影。最后的结果坐标就是处于标准化设备空间中的。

在 C/C++ 中可以利用 GLM 构建透视投影矩阵:

glm::mat4 Projection = glm::perspective(45.0f, ratio, 0.1f, 100.f); //ratio 一般表示视口的宽高比,width/height,

第一个参数定义了 fov(filed of view) 的值,它表示的是视野(Field of View),并且设置了观察空间的大小。

对于一个真实的观察效果,它的值经常设置为 45.0,但想要看到更多结果你可以设置一个更大的值。第二个参数设置了宽高比,由视口的高除以宽。第三和第四个参数设置了平截头体的近和远平面。我们经常设置近距离为 0.1 而远距离设为 100.0 。所有在近平面和远平面的顶点且处于平截头体内的顶点都会被渲染。

最后整个坐标系统的变换矩阵可以用一个矩阵表示
MVPMatrix = Projection * View * Model

在透视投影中,截断的金字塔平截头体(观察坐标)中的3D点被映射到立方体(NDC);从 [l,r] 到 [-1, 1] 的x坐标范围,从 [b,t] 到 [-1,1 ]的y坐标范围和 [-n,-f] 到[-1, 1] 的 z 的坐标范围。这边需要注意的是在OpenGL ES观察坐标是在右手坐标系中定义的,但NDC使用左手坐标系。
观察空间到裁剪空间

组合矩阵

上述的每一个步骤都创建了一个变换矩阵:模型矩阵、观察矩阵和投影矩阵。一个顶点坐标将会根据以下过程被变换到裁剪坐标:
组合矩阵
注意矩阵运算的顺序是相反的即需要从右往左阅读矩阵的乘法。最后的顶点应该被赋值到顶点着色器中的 gl_Position,OpenGL-ES将会自动进行透视除法和裁剪。顶点着色器的输出要求所有的顶点都在裁剪空间内,这正是刚才使用变换矩阵所做的。
OpenGL-ES然后对裁剪坐标执行透视除法从而将它们变换到标准化设备坐标。
OpenGL-ES会使用 glViewPort 内部的参数来将标准化设备坐标映射到屏幕坐标,每个坐标都关联了一个屏幕上的点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/469801.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

牛客JZ 36二叉搜索树与双向链表

描述 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。如下图所示 数据范围:输入二叉树的节点数 0≤n≤10000≤n≤1000,二叉树中每个节点的值 0≤val≤10000≤val≤1000 要求:空间复杂度O(1)(即在原树上…

音视频/流媒体协议和编码汇总

一、流媒体协议 1. RTMP/RTMPT/RTMPS/RTMPE 等多变种 是应用层协议,使用TCP作为底层传输协议,并提供了低延迟、高带宽利用率和实时性的特点。 (1)RTMP协议是Adobe的私有协议,未完全公开 (2)一般传输的是 flv,f4v 格式流 2. RTP/RTCP/SRTP …

Java 集合

一、集合的框架体系(重要,背!!!) 1.Collection(单列集合,只存放value) 2.Map(双列集合,存放key-value) 二、Collection接口 1.特点 …

wordpress好的网站主题

有什么好的网站主题,都分享在这里了。 蓝色风格的wordpress模板,好的wordpress网站主题,需要既好看,又好用。 https://www.zhanyes.com/qiye/6305.html 血红色的好看的wordpress主题,布局经典,设计好的&am…

Python一些可能用的到的函数系列124 GlobalFunc

说明 GlobalFunc是算网的下一代核心数据处理基础。 算网是一个分布式网络,为了能够实现真的分布式计算(加快大规模任务执行效率),以及能够在很长的时间内维护不同版本的计算方法,需要这样一个对象/服务来支撑。Globa…

第一篇【传奇开心果系列】Python的pyttsx3库技术点案例示例:文本转换语言

传奇开心果短博文系列 系列短博文目录Python的pyttsx3库技术点案例示例系列 短博文目录前言一、pyttsx3主要特点和功能介绍二、pyttsx3文字转语音操作步骤介绍三、多平台支持介绍和示例代码四、多语言支持介绍和示例代码五、自定义语言引擎介绍和示例代码六、调整语速和音量介绍…

2024年2月最新易支付系统全开源

2024.02 更新日志: 1.新增微信公众号消息提醒功能 2.重构转账付款功能,支持通过插件扩展 3.商户后台新增代付功能 4.后台新增付款记录列表 5.支付宝插件新增预授权支付 6.优化支付通道列表,支持翻页与快速复制通道 7.新增创建订单人机验…

express 定时删除 oss 垃圾图片

一: 删除垃圾图片 思路: 获取 oss 中存储的所有图片文件;获取数据库中存储的图片文件数据;对比差异,不在数据库中的 oss 图片文件即为要删除的垃圾图片。 实现: 1、获取所有 oss 文件 import OSS from…

前端秘法基础式(HTML)(第二卷)

目录 一.表单标签 1.表单域 2.表单控件 2.1input标签 2.2label/select/textarea标签 2.3无语义标签 三.特殊字符 一.表单标签 用来完成与用户的交互,例如登录系统 1.表单域 <form>通过action属性,将用户填写的数据转交给服务器 2.表单控件 2.1input标签 type…

【Python网络编程之Ping命令的实现】

&#x1f680; 作者 &#xff1a;“码上有前” &#x1f680; 文章简介 &#xff1a;Python开发技术 &#x1f680; 欢迎小伙伴们 点赞&#x1f44d;、收藏⭐、留言&#x1f4ac; Python网络编程之Ping命令的实现 代码见资源&#xff0c;效果图如下一、实验要求二、协议原理2…

Linux之多线程

目录 一、进程与线程 1.1 进程的概念 1.2 线程的概念 1.3 线程的优点 1.4 线程的缺点 1.5 线程异常 1.6 线程用途 二、线程控制 2.1 POSIX线程库 2.2 创建一个新的线程 2.3 线程ID及进程地址空间布局 2.4 线程终止 2.5 线程等待 2.6 线程分离 一、进程与线程 在…

数模.传染病模型plus

一、SIS模型 二、SIR模型 三、SIRS模型 四、SEIR模型