本文为L_Ares个人写作,包括图片皆为个人亲自操作,以任何形式转载请表明原文出处。
OpenGL既然要完成2D和3D的绘图,那么从绘图到显示的过程中一定需要各种坐标系的辅助才可以完成,所以本节主要介绍OpenGL中和坐标系相关的部分。
一、基础坐标系
1、2D笛卡尔坐标系
这是最常见的坐标系,所以不做过多无用描述。
2D笛卡尔坐标系的组成:原点,X轴,Y轴。
2D笛卡尔坐标系中确定点的位置是由x,y两个值来确定的。
2D笛卡尔坐标系是用来描述二维图形的坐标系,无法完成三位图形的描述。
图1.1.1 2D笛卡尔坐标系描述a点
2、3D笛卡尔坐标系
3D笛卡尔坐标系是用来完成对三维图形的描述的坐标系。
3D笛卡尔坐标系的组成:原点,X轴,Y轴,Z轴。
3D笛卡尔坐标系中的图形上的点都由x,y,z三个值来确定。
z值是深度值。
图1.2.1 3D笛卡尔坐标系描述b点二、视口和投影
1、视口
什么是视口呢?视口的解释其实很直观,视口其实就是可视窗口的一个简称。在OpenGL中还有一个窗口,窗口并不代表可视区域。在OpenGL中使用glViewPort()
函数进行设置。
举个例子,看视频的时候,视频的四周存在黑色的留白,视口是视频内容显示的部分,窗口只是外边框,也就是可以让用户看的到影像的部分。
注意:
图2.1.1 视口和窗口(1)图形超过了视口的大小是无法显示在视口中的。
(2)视口的大小可以不等于窗口大小。但是一般情况下,更倾向于设置成等比关系。
2、投影
投影是一种图形转换的方式。在OpenGL中我们常用的投影方式有两种。
- 正投影(平行投影)
- 透视投影
1、正投影(平行投影)
在中学的立体几何中曾经出现过这个概念。在数学中,正投影是平行投影的子集,但是在OpenGL中我们可以认为,平行投影就是正投影,所以在OpenGL中如果提到这两者,暂时可以认为是相同的。
特点:
(1)无论物体距离Camera的距离远近,都不会发生大小偏差,投影后的物体尺寸不会发生改变。
(2)根据上一点,正投影更适合用于平面图形
2、透视投影
透视投影更符合人类视觉习惯,远处的物体是小的,近处的物体是大的,越远越小,越近越大。
特点:
(1)远小近大。
(2)立体图形更适合使用透视投影。
三、OpenGL坐标系
1. 摄像机坐标系(Camera坐标系)
摄像机坐标系也被叫做照相机坐标系,总之是从Camera坐标系翻译过来的。
它表示的是一个观察者视角的坐标系。也就是说,当观察者的视角发生改变的时候,物体在摄像机坐标系中的位置也会发生改变。
图3.1.1 观察者视角1当观察者的视角发生了移动之后。
图3.1.2 观察者视角2这时候的摄像机坐标系是不相同的。
2. 世界坐标系、惯性坐标系、物体坐标系
这三个OpenGL的坐标系其实记住就可以,在理解上:
世界坐标系:
这是系统的绝对的坐标系,在用户自己的坐标系没有建立起之前,在系统画面上的任何一点都可以在世界坐标系中找到属于他的坐标,根据坐标来确定该点的位置。世界坐标系是始终恒定不变的。
物体坐标系:
也有叫对象坐标系,模型坐标系。物体坐标系是相对的坐标系,它专属于物体本身。当物体发生旋转,移动等行为的时候,物体坐标系也会随之发生相同的旋转,移动。
例如:“请向前走”,这就是向你的物体坐标系发出指令。“而请向东走”,这是向世界坐标系发出指令,因为物体坐标系会随物体的行为改变而改变,所以是不具备定向性方向的。
惯性坐标系:
图3.2.1 OpenGL坐标系(1)惯性坐标系是一个中间点,在物体从本身坐标系的坐标转换为世界坐标系的坐标的途中,先要将物体坐标转换为惯性坐标系的坐标,再转换为世界坐标系的坐标。
(2)惯性坐标系的x,y轴分别平行于世界坐标系的x轴,y轴。
(3)惯性坐标系的原点与物体坐标系的原点重合。
如图3.2.1所示,三个坐标系的图解。
图形从物体坐标系到惯性坐标系,实际上是坐标发生了旋转。
图形从惯性坐标系到世界坐标系,实际上是发生了平移。
为什么要引入一个惯性坐标系呢?
因为物体从物体坐标系转换到惯性坐标系只需要发生旋转,物体从惯性坐标系转换到世界坐标系只需要发生平移。
3. 规范化设备坐标(NDC)
英文全称:Normal Device Coordinate
概念:
坐标系的区间范围是[-1,1],也就是说,所有点的坐标都会被转换到-1到1这个坐标范围内。超过这个范围的顶点将是不可见的。
4. 左右手坐标系。
图3.4.1 左右手坐标系左右手坐标系的判断方法如图所示。
按照约定,OpenGL是右手坐标系,Dx是左手坐标系,NDC是左手坐标系。所以OpenGL坐标系是属于右手坐标系的。
四、坐标变换
因为图像最后是在设备屏幕上成像,而屏幕是2D的,但是很多物体是3D的,所以当碰到3D物体显示的时候,我们需要将3D的场景经过一系列的变换,最终呈现在2D的屏幕上,这也就是坐标变换的需求。
将一个物体显示到屏幕上经过的坐标变换的流程,
(1)将物体的物体坐标(对象坐标)经过模型转换,变成世界坐标。
(2)通过视变换,将世界坐标转化成观察者坐标。
(3)通过投影变换,将世界坐标转化成剪裁坐标系坐标。
(4)利用透视除法,转化成标准的NDC([-1,1])。
(5)通过视口变换,转化为屏幕坐标。
坐标变换的流程则如图4.1.1所示。
图4.1.1 坐标变换及权限OpenGL只定义了裁剪坐标系、规范化设备坐标系(NDC)和屏幕坐标系。
用户可以自定义模型坐标系、世界坐标系和摄像机坐标系。
图4.1.1中
- 虚线左侧,“用户可以自定义”的栏中,全是用户可以定义的坐标系和变换动作。
- 虚线右侧,“OpenGL定义,用户不可自定义”的栏中,则全是不可自定义的坐标系和变换动作。
- 模型变换、视变换、投影变换也就是MVP。这三者由用户自定义,最终在顶点着色器中完成。
- 透视除法和视口变换,则是OpenGL自己定义,在顶点着色器处理之后再完成。
在上述对应的每一个步骤中,我们都创建一个矩阵与之对应:
模型转换:模型矩阵。
视变换:观察矩阵。
投影变换:投影矩阵。
模型变换的意义:
通过变换将图形的顶点属性定义或者3D模型软件建立的模型可以按照需要,通过缩放、平移等操作放置到世界坐标系中,而世界坐标系是所有物体交互的坐标系,这样可以完成物体间的交互准备。
视变换的意义:
为什么不直接从世界坐标系转换到裁剪坐标系呢?因为物体在世界坐标系中的位置是绝对的,但是当观察者从不同的角度观察物体的时候,往往观察到的物体在观察者的角度是相对的。所以需要一个动作和一个坐标系来动态的描述物体在实际情况下观察者观看到的情况。这个动作就是视变换,这个解释了物体在世界坐标系中位置的坐标系就是摄像机坐标系。
至此本节OpenGL中的坐标系的理解全部结束,希望看到文章的小伙伴如果发现了文章中不适合的地方可以留言指正,谢谢。
网友评论