32

在学习 OpenGL 时,我经常偶然发现所谓的眼睛空间坐标。

如果我是对的,你通常有三个矩阵。模型矩阵、视图矩阵和投影矩阵。虽然我不完全确定其背后的数学原理是如何工作的,但我确实知道将坐标转换为世界空间、视图空间和屏幕空间。

但是眼睛空间在哪里,我需要哪些矩阵来将某些东西转换为眼睛空间?

4

3 回答 3

64

也许下图显示了各种空间之间的关系会有所帮助:OpenGL 转换管道

取决于您是使用固定功能管道(glMatrixMode()例如,如果您调用 ),还是使用着色器,操作是相同的 - 只是您是直接在着色器中编码,还是使用 OpenGL 管道辅助在你的工作中。

虽然讨论固定功能管道方面的事情令人厌恶,但它使对话变得更简单,所以我将从那里开始。

在旧版 OpenGL(即 OpenGL 3.1 之前的版本,或使用兼容性配置文件)中,定义了两个矩阵堆栈:model-viewprojection,当应用程序启动时,每个堆栈顶部的矩阵是一个单位矩阵(1.0 on对角线,所有其他元素为 0.0)。如果在该空间中绘制坐标,则实际上是在标准化设备坐标(NDC) 中进行渲染,这会在 X、Y 和 Z 中裁剪掉范围 [-1,1] 之外的任何顶点。视口变换(如通过调用设置glViewport())是将 NDC 映射到窗口坐标(实际上,视口坐标,但大多数情况下视口和窗口的大小和位置相同),以及深度值到深度范围(默认为 [0,1])。

现在,在大多数应用程序中,指定的第一个变换是投影变换,它有两种:正交投影和透视投影。正交投影保留角度,通常用于科学和工程应用,因为它不会扭曲线段的相对长度。在旧版 OpenGL 中,正交投影由glOrtho或指定gluOrtho2D。更常用的是透视变换,它模仿眼睛的工作方式(即,远离眼睛的物体比靠近眼睛的物体小),由glFrustum或指定gluPerspective。对于透视投影,他们定义了一个视锥体,这是一个截断的金字塔,锚定在眼睛的位置,在眼睛坐标中指定。在眼睛坐标中,“眼睛”位于原点,向下看 -Z 轴。您的剪裁平面和远剪裁平面被指定为沿 -Z 轴的距离。如果在眼睛坐标中渲染,则在近剪裁平面和远剪裁平面之间以及视锥体内部指定的任何几何图形都不会被剔除,而是会被转换以显示在视口中。这是透视投影的示意图,以及它与图像平面的关系查看平截头体

眼睛位于视锥体的顶点。

最后要讨论的转换是模型视图转换,它负责移动坐标系(而不是对象;稍后会详细介绍),以使它们相对于眼睛和视锥体处于良好的位置。常见的建模变换是平移缩放旋转剪切(OpenGL 中没有原生支持)。

一般而言,3D 模型是围绕局部坐标系建模的(例如,指定以原点为中心的球体坐标)。建模变换用于将“当前”坐标系移动到新位置,以便在渲染本地建模对象时,它位于正确的位置。

建模变换和视图变换之间没有数学上的区别。只是通常,建模转换用于特定模型,并由操作控制glPushMatrix()glPopMatrix()通常首先指定查看转换,并影响所有后续建模操作。

现在,如果您正在执行此现代 OpenGL(核心配置文件版本 3.1 及更高版本),您必须自己逻辑地执行所有这些操作(您可能只指定一个转换,将模型视图和投影转换折叠为单个矩阵乘法) . 矩阵通常指定为 shader uniforms。没有矩阵堆栈、模型视图和投影转换的分离,您需要正确计算才能模拟管道。(顺便说一句,透视分割和视口变换步骤由 OpenGL 在完成顶点着色器后执行 - 你不需要做数学运算 [你可以,除非你没有将w设置为 1.0你的gl_Position顶点着色器输出)。

于 2013-03-23T21:36:52.910 回答
40

眼睛空间、视图空间和相机空间都是同一事物的同义词:相对于相机的世界。

于 2013-03-23T16:05:28.180 回答
4

在一次渲染中,场景的每个网格通常由模型矩阵、视图矩阵和投影矩阵进行变换。最后将投影场景映射到视口。

投影、视图和模型矩阵相互作用,以在视口上呈现场景的对象(网格)。

  • 模型矩阵定义了场景世界空间中单个对象(网格)的位置方向和比例。
  • 视图矩阵定义了观察者(观察者)在场景中的位置和观察方向。
  • 投影矩阵定义了投影到视口上的观察者(观察者)的面积(体积)。

坐标系:

  • 模型坐标(对象坐标)

    模型空间是坐标系,用于定义或调制网格。顶点坐标在模型空间中定义。

  • 世界坐标

    世界空间是场景的坐标系。不同的模型(对象)可以在世界空间中多次放置,形成一个场景,放在一起。

    模型矩阵定义了场景中模型(对象、网格)的位置、方向和相对大小。模型矩阵将单个网格的顶点位置转换为单个特定定位的世界空间。有不同的模型矩阵,每个组合一个模型(对象)和对象在世界空间中的位置。

  • 视空间(眼坐标)

    视图空间是由场景中的视点定义的局部系统。视图的位置、视线和视图的向上方向,定义了一个相对于世界坐标系的坐标系。场景的对象必须相对于视图坐标系进行绘制,才能从观察位置“看到”。视图坐标系的逆矩阵称为视图矩阵。该矩阵从世界坐标转换为视图坐标。
    一般世界坐标和视图坐标都是笛卡尔坐标

    视图坐标系统描述了观察场景的方向和位置。视图矩阵从世界空间转换到视图(眼睛)空间。

    如果视图空间的坐标系是右手系,其中 X 轴指向右侧,Y 轴指向上方,则 Z 轴指向视图外(注意在右手系中Z 轴是 X 轴和 Y 轴的叉积)。

  • 剪辑空间坐标是齐次坐标。在剪辑空间中执行场景的剪辑。
    如果x,yz分量在由反转w分量和w点齐次坐标分量定义的范围内,则点在裁剪空间中:

    -w <= x, y, z <= w.

    投影矩阵描述了从场景的 3D 点到视口的 2D 点的映射。投影矩阵从视图空间转换到剪辑空间。通过除以w剪辑坐标的分量,剪辑空间中的坐标被转换为 (-1, -1, -1) 到 (1, 1, 1) 范围内的标准化设备坐标 (NDC)。

    在正交投影中,这个区域(体积)由到观察者位置的 6 个距离(左、右、下、上、近和远)定义。如果左、下、近距离为负,右、上、远距离为正(如在标准化设备空间中),这可以想象为观察者周围的盒子。空间(体积)中的所有对象(网格)在视口上都是“可见的”。超出(或部分超出)该空间的所有对象(网格)都在体积的边界处被剪裁。这意味着在正交投影中,观察者“后面”的对象可能是“可见的”。这可能看起来不自然,但这就是正交投影的工作原理。

    在透视投影中,观察体是一个平截头体(截棱锥),其中金字塔的顶部是观察位置。观察方向(视线)以及近距和远距定义了将金字塔截断为平截头体的平面(观察方向是该平面的法线向量)。左、右、下、上距离定义了从视线和近平面的交点到平截头体侧面(在近平面上)的距离。这导致场景看起来像从针孔相机看到的那样。

    当对象在视口上不可见(屏幕全是“黑色”)时,最常见的错误之一是网格不在由投影和视图矩阵定义的视图体积内。

  • 标准化设备坐标

    标准化的设备空间是一个立方体,右、下、前在 (-1, -1, -1) 和左、上、后在 (1, 1, 1)。标准化的设备坐标是剪辑空间坐标除以w剪辑坐标的分量。这称为透视划分

  • 窗口坐标(屏幕坐标)

    窗口坐标是视口矩形的坐标。窗口坐标对于光栅化过程是决定性的。

    标准化的设备坐标线性映射到视口矩形(窗口坐标/屏幕坐标)和深度缓冲区的深度。视口矩形由 定义glViewport。深度范围glDepthRange由默认设置为 [0, 1]。

于 2020-05-01T05:32:54.783 回答