7.5 KiB
title | date | author | tags | categories | ||
---|---|---|---|---|---|---|
OpenGL中的坐标系 | 2021-04-16 | ac |
|
|
转载:
OpenGL 图形库的使用(七)—— 坐标系统之五种不同的坐标系统(一)
OpenGL 坐标系解析
1. 基本概念
视口
视口(viewPort
)是浏览器上显示网页的一块区域,大小并不局限于浏览器可视区域范围,但在OpenGL
中表示的是浏览器窗口内部用于绘制裁剪区域的部分区域。
3D笛卡尔坐标系
简单的将就是三条两两垂直的轴线构成的空间直角坐标系。(右手系)
投影(3D->2D)
OpenGL从笛卡尔坐标系映射到屏幕上的二维坐标,需要用到投影,指定投影空间,指定在窗口显示的视景体(Viewing Volume),并指定如何对它进行转换。
两种常用的投影方式:Orthographic 正射投影(平行投影)、Perspective 透视投影(中心投影)。
正射投影的投影光线是平行的且垂直与投影面,使用的时候需要指定一个正方体/长方体的视景体,在视景体以外的任何物体都不会被绘制。特点:
- 无变形,物体在屏幕上的大小与实际大小相同;
- 不存在远近问题;
透视投影同样需要指定视景体,但不是正方体,而是平截头体(Frustum)。透视投影的视线(投影线)是从视点(观察点)出发,视线是不平行的,任何一束不平行于投影平面的透视投影将汇聚成一点,称之为灭点。特点:
- 具有消失感、距离感、相同大小的形体呈现出有规律的变化等透视特性,能逼真地反映形体的空间形象。
- 适用于3D地形模拟、飞行穿越仿真、步行穿越仿真等模拟人眼视觉效果的研究领。
Frustum表示view中由六个平面组成的平截头体( left, right, bottom, top, near ,far)
左手坐标系和右手坐标系
标准化设备坐标
标准化设备坐标(Normalized Device Coordinate,NDC
)是一个x、y和z值在-1.0到1.0的一小段空间。任何落在范围外的坐标都会被丢弃/裁剪,不会显示在你的屏幕上。
2. 坐标系
OpenGL
中的物体、世界、照相机坐标系都属于右手坐标系,而规范化设备坐标系使用左手坐标系。
先来了解一下OpenGL中的五个Space:
- 局部空间
Local Space
,或称为对象空间Object Space
- 世界空间
World Space
- 观察空间
View Space
,也称为 视觉空间eye Space
- 裁剪空间
Clip Space
- 屏幕空间
Screen Space
OpenGL 希望在每次定点着色器运行后,我们可见的所有顶点都为标准化设备坐标(NDC),即每个顶点的x/y/z坐标都应该在-1.0到1.0之间,超过这个坐标范围的顶点都将不可见。
通常会设定一个坐标范围(如平椎体),之后在顶点着色器中将这些坐标转换为标准化设备坐标,然后将这些标准化设备坐标传入光栅器(Rasterizer
)中,将它们变换为屏幕的二维坐标或像素。
看到坐标系统的负责的计算过程,你可能会问为什么要设定这么多坐标系统?
虽然物体的顶点坐标在最终转化为屏幕坐标之前会被转换到几个过渡坐标系统(Intermedinate Coordinate System
)中,增加了计算量,但优点在于,在这些特定的坐标系中,一些操作或运算会更加方便。
局部空间 Object Space
局部空间是指物体所在的坐标空间,即对象最开始所在的地方。想象你在一个建模软件(比如说Blender)中创建了一个立方体。你创建的立方体的原点有可能位于(0, 0, 0),即便它有可能最后在程序中处于完全不同的位置。甚至有可能你创建的所有模型都以(0, 0, 0)为初始位置(译注:然而它们会最终出现在世界的不同位置)。所以,你的模型的所有顶点都是在局部空间中:它们相对于你的物体来说都是局部的。
每个物体都有他们独立的坐标系。
世界空间 World Space
如果我们将我们所有的物体导入到程序当中,它们有可能会全挤在世界的原点(0, 0, 0)上,这并不是我们想要的结果。我们想为每一个物体定义一个位置,从而能在更大的世界当中放置它们。世界空间中的坐标正如其名:是指顶点相对于(游戏)世界的坐标。如果你希望将物体分散在世界上摆放(特别是非常真实的那样),这就是你希望物体变换到的空间。物体的坐标将会从局部变换到世界空间;该变换是由模型矩阵(Model Matrix)
实现的。
模型矩阵是一种变换矩阵,它能通过对物体进行位移、缩放、旋转来将它置于它本应该在的位置或朝向。
观察空间 View Space
观察空间经常被人们称之OpenGL的摄像机(Camera)(也称为摄像机空间(Camera Space)或视觉空间(Eye Space))。
观察空间是将世界空间坐标转化为用户视野前方的坐标而产生的结果。因此观察空间就是从摄像机的视角所观察到的空间。
而这通常是由一系列的位移和旋转的组合来完成,平移/旋转场景从而使得特定的对象被变换到摄像机的前方。这些组合在一起的变换通常存储在一个观察矩阵(View Matrix)
里,它被用来将世界坐标变换到观察空间。
裁剪空间 Clip Space
在一个顶点着色器运行的最后,OpenGL期望所有的坐标都能落在一个特定的范围内,且任何在这个范围之外的点都应该被裁剪掉(Clipped)。被裁剪掉的坐标就会被忽略,所以剩下的坐标就将变为屏幕上可见的片段。这也就是裁剪空间(Clip Space)
名字的由来。
因为将所有可见的坐标都指定在-1.0到1.0的范围内不是很直观,所以我们会指定自己的坐标集(Coordinate Set)
并将它变换回标准化设备坐标系,就像OpenGL期望的那样。
3. 坐标转化流程
OpenGL最终的渲染设备是2D的,我们需要将3D表示的场景转换为最终的2D形式,前面使用【模型变换】和【视变换】将物体坐标转换到照相机坐标系后,需要进行【投影变换】,将坐标从相机—>裁剪坐标系,经过【透视除法】后,变换到规范化设备坐标系(NDC),最后进行【视口变换】后,3D坐标才变换到屏幕上的2D坐标。
- 图中左边的过程包括模型变换、视变换,投影变换,这些变换可以由用户根据需要自行指定,这些内容在顶点着色器中完成;
- 图中右边的两个步骤,包括透视除法、视口变换,这两个步骤是OpenGL自动执行的,在顶点着色器处理后的阶段完成。
将坐标系统组合在一起
OpenGL 会使用 glViewPort
内部的参数来将标准化设备坐标映射到屏幕坐标,每个坐标都关联了一个屏幕上的点。这个过程称为视口变换。
参考文章
[1] OpenGL 坐标系解析 https://www.jianshu.com/p/3448f546eac4
[2] OpenGL 图形库的使用(七) https://www.jianshu.com/p/fe30d207dc5e