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.rhkb.cn/news/257734.html

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

相关文章

高德地图上绘制热力图的方法

百度地图和高德地图的JavaScript API都提供了热力图的绘制方法,都是将热力图作为新的图层,叠加到地图上。但是百度地图的经纬度体系与我们的经纬度存在偏差,高德的与我们相符,应当使用高德地图JavaScript API。 因为是JavaScript…

Elasticsearch:特定领域的生成式 AI - 预训练、微调和 RAG

作者:来自 Elastic Steve Dodson 有多种策略可以将特定领域的知识添加到大型语言模型 (LLM) 中,并且作为积极研究领域的一部分,正在研究更多方法。 对特定领域数据集进行预训练和微调等方法使 LLMs 能够推理并生成特定领域语言。 然而&#…

Mysql的安装、使用、优势与教程

一.安装 1.在小皮的设置界面检测3306端口,保障3306端口可用; 2、在小皮的首面界面,启动MySQL; 3、进行环境变量设置,找到MySQL的路径,进行复制; 4、在Windows的搜索栏内,输入“环境…

Linux 驱动开发基础知识——总线设备驱动模型(七)

个人名片: 🦁作者简介:学生 🐯个人主页:妄北y 🐧个人QQ:2061314755 🐻个人邮箱:2061314755qq.com 🦉个人WeChat:Vir2021GKBS 🐼本文由…

Linux——网络通信TCP通信常用的接口和tco服务demo

文章目录 TCP通信所需要的套接字socket()bind()listen()acceptconnect() 封装TCP socket TCP通信所需要的套接字 socket() socket()函数主要作用是返回一个描述符,他的作用就是打开一个网络通讯端口,返回的这个描述符其实就可以理解为一个文件描述符&a…

Vue核心基础5:数据监测、收集表单数据、过滤器

1 数据监测 【代码】 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>总结</title><scrip…

leetcode(二分查找)34.在排序数组中查找元素的第一个和最后一个位置(C++详细解释)DAY11

文章目录 1.题目示例提示 2.解答思路3.实现代码结果 4.总结 1.题目 给你一个按照非递减顺序排列的整数数组 nums&#xff0c;和一个目标值 target。请你找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 [-1, -1]。 你必须设计…

【最详解】如何进行点云的凹凸缺陷检测(opene3D)(完成度80%)

文章目录 前言实现思路想法1想法2想法3 补充实现想法1想法2代码 想法3代码 总结 前言 读前须知&#xff1a; 首先我们得确保你已经完全知晓相关的基本的数学知识&#xff0c;其中包括用最小二乘法拟合曲二次曲面&#xff0c;以及曲面的曲率详细求解。若还是没弄清楚&#xff0…

(17)Hive ——MR任务的map与reduce个数由什么决定?

一、MapTask的数量由什么决定&#xff1f; MapTask的数量由以下参数决定 文件个数文件大小blocksize 一般而言&#xff0c;对于每一个输入的文件会有一个map split&#xff0c;每一个分片会开启一个map任务&#xff0c;很容易导致小文件问题&#xff08;如果不进行小文件合并&…

Vue插槽

Vue插槽 一、插槽-默认插槽1.作用2.需求3.问题4.插槽的基本语法5.代码示例6.总结 二、插槽-后备内容&#xff08;默认值&#xff09;1.问题2.插槽的后备内容3.语法4.效果5.代码示例 三、插槽-具名插槽1.需求2.具名插槽语法3.v-slot的简写4.代码示例5.总结 四、作用域插槽1.插槽…

【AIGC】Stable Diffusion的ControlNet插件

ControlNet 介绍 ControlNet 插件是 Stable Diffusion 中的一个重要组件&#xff0c;用于提供对模型的控制和调整。以下是 ControlNet 插件的主要特点和功能&#xff1a; 模型控制&#xff1a; ControlNet 允许用户对 Stable Diffusion 中的模型进行精细的控制和调整。用户可以…

Linux_文件系统

假定外部存储设备为磁盘&#xff0c;文件如果没有被使用&#xff0c;那么它静静躺在磁盘上&#xff0c;如果它被使用&#xff0c;则文件将被加载进内存中。故此&#xff0c;可以将文件分为内存文件和磁盘文件。 内存文件 磁盘文件 软、硬链接 一.内存文件 1.1 c语言的文件接口 …

【web | CTF】BUUCTF [护网杯 2018] easy_tornado

天命&#xff1a;这题是框架性的漏洞&#xff0c;Python的web服务器框架&#xff0c;应该已经比较古老了 开局先看一下三个文件 简单阅读后会发现&#xff0c;这里存在文件包含漏洞&#xff0c;可以直接读取文件&#xff0c;但是有一个哈希值校验 一开始我以为是扫描文件后得到…

python 自我检测题--part 1

1. Which way among them is used to create an event loop ? Window.mainloop() 2. Suppose we have a set a {10,9,8,7}, and we execute a.remove(14) what will happen ? Key error is raised. The remove() method removes the specified element from the set. Th…

基于FPGA的ECG信号滤波与心率计算verilog实现,包含testbench

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 ECG信号的特点与噪声 4.2 FPGA在ECG信号处理中的应用 4.3 ECG信号滤波原理 4.4 心率计算原理 4.5 FPGA在ECG信号处理中的优势 5.算法完整程序工程 1.算法运行效果图预览 其RTL结构如…

安卓自定义画板

包含功能&#xff1a; 包含 获取当前画板的截图、设置画笔样式、获取画笔样式、设置画笔宽度、获取画笔宽度、设置画笔颜色、获取画笔颜色、加载图片、获取图片位图对象、设置图片位图对象&#xff0c;并在画布上绘制图片、撤销上一步操作、重做上一步撤销的操作、清空所有绘图…

[OPEN SQL] 修改数据

MODIFY语句用于修改数据库表中的数据 MODIFY拥有INSERT和UPDATE的操作&#xff0c;如果数据库表中不存在符合条件的数据则会添加该条新数据&#xff0c;反之数据库表中存在符合条件的数据则会更新该条数据 本次操作使用的数据库表为SCUSTOM&#xff0c;其字段内容如下所示 航…

[BIZ] - 1.金融交易系统特点

1. 典型数据汇总 数据 说明 新增数据量(条/天) Qps(条/s) 消息大小(Byte) 实时性 可丢失性 可恢复性 实时行情 1.使用场景&#xff1a;交易&#xff0c;报价&#xff0c;策略验证&#xff1b; 2.冷热分离&#xff1a;彭博行情/其他行情&#xff1b;黄金&期货行情/…

AI - 碰撞避免算法分析(ORCA)

对比VO/RVO ORCA算法检测碰撞的原理和VO/RVO基本一样的&#xff0c;只是碰撞区域的计算去掉了一定时间以外才可能发生的碰撞&#xff0c;因此碰撞区域的扇形去掉了前面的部分&#xff0c;由圆锥头变成了个圆 另一个最主要的区别是&#xff0c;求新的速度&#xff0c;是根据相…

数据可视化之维恩图 Venn diagram

文章目录 一、前言二、主要内容三、总结 &#x1f349; CSDN 叶庭云&#xff1a;https://yetingyun.blog.csdn.net/ 一、前言 维恩图&#xff08;Venn diagram&#xff09;&#xff0c;也叫文氏图或韦恩图&#xff0c;是一种关系型图表&#xff0c;用于显示元素集合之间的重叠区…