当我学习OpenGL时,我经常偶然发现所谓的眼睛空间坐标。
如果我是对的,你通常有三个矩阵。模型矩阵,视图矩阵和投影矩阵。虽然我不完全确定背后的数学是如何工作的,但我确实知道转换坐标到世界空间,视图空间和屏幕空间。
但是眼睛的空间在哪里,我需要将哪些矩阵转换为眼睛空间?
答案 0 :(得分:58)
以下插图显示各种空格之间的关系可能会有所帮助:
取决于您是否正在使用固定功能管道(例如,如果您调用glMatrixMode()
)或使用着色器,操作是相同的 - 这只是您是否直接编码它们的问题着色器,或OpenGL管道有助于您的工作。
虽然用固定功能管道讨论事情是令人厌恶的,但它会使对话更简单,所以我将从那里开始。
在传统OpenGL(即OpenGL 3.1之前的版本,或使用兼容性配置文件)中,定义了两个矩阵堆栈: model-view 和投影,当应用程序启动每个堆栈顶部的矩阵是一个单位矩阵(对角线为1.0,所有其他元素为0.0)。如果在该空间中绘制坐标,则可以在规范化设备坐标(NDC)中进行有效渲染,这会在X,Y和X中剪切出范围[-1,1]之外的任何顶点。 Z. 视口变换(通过调用glViewport()
设置)是将NDC映射到窗口坐标(实际上是视口坐标),但最常见的是视口和窗口大小相同和位置),以及深度范围的深度值(默认为[0,1])。
现在,在大多数应用程序中,指定的第一个转换是投影转换,它有两种类型:正交投影和透视投影。 正交投影保留角度,通常用于科学和工程应用,因为它不会扭曲线段的相对长度。在传统OpenGL中,正交投影由glOrtho
或gluOrtho2D
指定。更常用的是透视变换,它模仿眼睛的工作方式(即远离眼睛的物体小于闭眼物体),并由glFrustum
或{{1}指定}。对于透视投影,他们定义了一个观察平截头体,它是一个固定在眼睛位置的截断金字塔,在眼睛坐标中指定。在眼睛坐标中,“眼睛”位于原点,并向下看-Z轴。您的 near 和远剪裁平面沿-Z轴指定为距离。如果在眼睛坐标中渲染,则在近视和远视剪裁平面之间以及视锥体内部指定的任何几何体都不会被剔除,并且将被变换为出现在视口中。这是透视投影的图表,以及它与图像平面的关系。
眼睛位于视锥体的顶点。
要讨论的最后一个转换是模型 - 视图变换,它负责移动坐标系(而不是对象;稍后更多关于它),使得它们相对于眼睛和观察视锥体。常见的建模转换是翻译, scale , rotations 和 shears (其中OpenGL中没有本机支持)
一般而言,3D模型围绕局部坐标系建模(例如,指定球体与中心原点的坐标)。建模变换用于将“当前”坐标系移动到新位置,以便在渲染本地建模对象时,它位于正确的位置。
建模变换和观察变换之间没有数学差异。通常,建模变换用于特定模型,并由gluPerspective
和glPushMatrix()
操作控制,通常首先指定查看变换,并影响所有后续建模操作。
现在,如果您正在使用这个现代OpenGL(核心配置文件版本3.1和转发),您必须自己逻辑地执行所有这些操作(您可能只指定一个转换将模型视图和投影转换折叠成一个矩阵乘法)。矩阵通常指定为着色器glPopMatrix()
。没有矩阵堆栈,模型视图和投影转换的分离,您需要使数学正确以模拟管道。 (顺便说一句,透视分割和视口转换步骤是在你的顶点着色器完成后由OpenGL执行的 - 你不需要做数学[你可以,它不会伤害任何东西,除非你未能在uniforms
顶点着色器输出中将 w 设置为1.0。
答案 1 :(得分:37)
眼睛空间,视野空间和相机空间都是同一件事物的同义词:相对于相机的世界。
答案 2 :(得分:1)
在渲染中,场景的每个网格通常通过模型矩阵,视图矩阵和投影矩阵进行变换。最后,将投影的场景映射到视口。
投影,视图和模型矩阵共同作用,以在视口上呈现场景的对象(网格)。
坐标系:
模型坐标(对象坐标)
模型空间是坐标系统,用于定义或调制网格。顶点坐标在模型空间中定义。
世界坐标
世界空间是场景的坐标系。可以将不同的模型(对象)多次放置在世界空间中,以构成一个场景。
模型矩阵定义场景中模型(对象,网格)的位置,方向和相对大小。模型矩阵将单个网格的顶点位置转换为单个特定位置的世界空间。有不同的模型矩阵,每个模型矩阵都对应一个模型(对象)和该对象在世界空间中的位置。
视图空间(眼睛坐标)
视图空间是本地系统,由场景上的视点定义。
视图的位置,视线和视图的向上方向定义了相对于世界坐标系的坐标系。场景的对象必须相对于视图坐标系绘制,以便从查看位置“看到”。视图坐标系的逆矩阵称为视图矩阵。此矩阵从世界坐标转换为视图坐标。
通常,世界坐标和视图坐标为Cartesian coordinates
视图坐标系描述了从中查看场景的方向和位置。视图矩阵从世界空间转换为视图(眼睛)空间。
如果视图空间的坐标系是Right-handed系统,其中X轴指向右侧,Y轴指向上方,则Z轴指向视图之外(注意右手系统,Z轴是X轴和Y轴的叉积。
剪辑空间坐标为Homogeneous coordinates。在剪辑空间中,将执行场景的剪辑。
如果x
,y
和z
分量在由倒置的w
分量和w
分量定义的范围内,则该点位于剪辑空间中。点的齐次坐标:
-w <= x, y, z <= w.
投影矩阵描述从场景的3D点到视口的2D点的映射。投影矩阵从视图空间转换为剪辑空间。通过除以剪辑的w
分量,将剪辑空间中的坐标转换为范围(-1,-1,-1)至(1、1、1)的归一化设备坐标(NDC)坐标。
在正交投影上,此区域(体积)由到观看者位置的6个距离(左,右,下,上,近和远)定义。 如果左,下和近距离为负,而右,上和远距离为正(如在规范化的设备空间中),则可以想象为观察者周围的盒子。 空间(体积)中的所有对象(网格)在视口上都是“可见的”。在该空间之外(或部分在外面)的所有对象(网格)都被剪裁在该卷的边界处。 这意味着在正交投影时,观看者“后面”的对象可能是“可见的”。这看似不自然,但这就是正交投影的工作原理。
在透视投影时,观看量为frustum(截顶的金字塔),其中金字塔的顶部为观看位置。 视线的方向(视线)以及近距和远距定义了将棱锥截成平截头体的平面(视线方向是该平面的法向矢量)。 左,右,下,顶部距离定义了视线与近平面的相交点与视锥的侧面(在近平面上)之间的距离。 这会导致场景看起来像从针孔相机中看到的一样。
当在视口上看不见对象(屏幕全为“黑色”)时,最常见的错误之一是网格不在由投影和视图矩阵定义的视图空间内。
规范化的设备坐标
标准化设备空间是一个立方体,其右,下,前部为(-1,-1,-1),左,上,后部为(1、1、1)。
归一化的设备坐标是剪辑空间坐标除以剪辑坐标的w
分量。这称为Perspective divide
窗口坐标(屏幕坐标)
窗口坐标是视口矩形的坐标。窗口坐标对于rasterization过程至关重要。
标准化的设备坐标线性映射到视口矩形(“窗口坐标” /“屏幕坐标”)和深度缓冲区的深度。
视口矩形由glViewport
定义。深度范围由glDepthRange
设置,默认为[0,1]。