2

我正在尝试学习(现代)OpenGL,但我对各种转换感到非常困惑......

查看矩阵让我感到困惑,所以我需要澄清一下。

这是我对(传统)管道的理解。

  1. 顶点在世界空间中指定,使用建模矩阵将其缩放、平移、旋转等到所需位置
  2. (这就是我开始感到困惑的地方)我们可以(可选地)使用“lookAt”函数(gluLookAt)将虚拟相机定位在所需的位置。我在这里遵循了矩阵的推导:http ://www.youtube.com/watch?v=s9FhcvjM7Hk 。直到教授计算“查看”向量为止,我都明白了。他说观察向量=眼睛-中心。现在这里是我开始迷路的地方。我的第一直觉是向量应该是中心 - 眼睛。假设中心向量为 (0,0,0),眼睛向量为 (0,0,5)。要查看对象,相机应指向中心 - eye = (0,0,-5)。但是,教授说我们想将 center - eye 移动到 -z 方向(这是什么意思?)。因此,眼睛中心将给出观察方向。我对此感到困惑。他进一步补充说,在 OpenGL 中,在原点处有一个摄像头在看 (0,0,-1)。现在,这是我完全不明白的。我确实了解查看转换只不过是对对象应用逆变换。我做了一点实验,发现当我绘制一个 z 值为 1 的三角形(并且绝对没有模型视图/投影变换)时,它仍然绘制在屏幕上。但是,我不希望会这样,因为相机位于原点。

现在,总结...

  • 为什么看=眼睛-中心?
  • 相机在原点并看着 z=-1 是怎么回事?

任何解释/指针?

4

2 回答 2

2

渲染三角形时,顶点坐标解释如下:

  • x 坐标将影响视口上的水平位置。-1 是左边缘,+1 是右边缘。
  • y 坐标将影响视口上的垂直位置。-1 是底边,+1 是顶边。
  • z 坐标将影响深度信息。-1 是相机平面(近)的位置,+1 是远平面。该值通常用于写入深度缓冲区。

这就是为什么您的简单示例在远平面呈现可见三角形的原因。

现在让我们来看看视图转换。转换将由四个向量构成。(1, 0, 0) 的图像,(0, 1, 0) 的图像,(0, 0, 1) 的图像和一个平移向量。但是,由于视图变换是逆变换,因此必须反转生成的矩阵。

你是对的,视图方向是center - eye。然而,这不是我们需要的矩阵。我们需要 (0, 0, 1) 的图像。通常,OpenGL 程序使用右手坐标系。在该系统中,相机朝向负 z 方向。center - eye实际上 (0, 0, -1) 的图像也是如此。那么 (0, 0, 1) 的图像就是eye - center。这就是你需要的。

使用此定义,您还需要适当的投影转换。否则,您只会看到相机后面的东西(因为那是 z 坐标为正的位置,因此具有正的深度值)。投影变换负责将负 z 坐标转换为正深度值。

于 2013-11-03T18:51:10.217 回答
-1

使用虚拟相机时,通常会定义一个眼睛空间。这个定义可以是任意的,但是有一些广泛的约定(以及 GL 的旧矩阵堆栈定义或首选一些约定)。gluLookAt为以下约定指定:

  1. 相机放置在原点
  2. 相机看z轴负方向,+x是右轴,+y是向上方向(所以我们有一个右手坐标系)

您应该知道world space渲染时这并不重要。重要的是对象相对于虚拟相机/眼睛的相对位置(这也是为什么旧的 GL 矩阵堆栈有一个组合ModelView矩阵,而不是两个单独的矩阵 forModelViewtransfroms)。使用放置所有对象的世界空间并在该空间中指定虚拟相机更加直观。这gluLookAt就是应该做的。如果您将view矩阵留在 Identity 中,就好像您的相机位于世界空间原点,向 -z 方向看。因此,要获得将相机移动到某个指定的眼点的效果,就相当于将那个世界空间中的所有对象都向相反的方向移动。旋转也是如此。和gluLookAt只会设置旋转和平移。看看我之前的回答,了解gluLookAt一些细节。

于 2013-11-03T18:48:01.523 回答