(glu)lookAt的推导

时间:2013-11-03 18:28:27

标签: opengl opengl-3 glulookat viewing

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

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

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

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

    • 为什么看看=眼睛 - 中心?
    • 这是关于相机位于原点并查看z = -1?
    • 的内容

    任何解释/指示?

2 个答案:

答案 0 :(得分:1)

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

  • 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坐标转换为正深度值。

答案 1 :(得分:0)

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

  1. 将相机放在原点
  2. 相机看负z方向,+ x是右轴,+ y是向上方向(所以我们有右手坐标系)
  3. 您应该知道渲染时world space并不重要。所有重要的是对象相对于虚拟相机/眼睛的相对位置(这也是旧GL矩阵堆栈具有组合ModelView矩阵的原因,而不是Model和{的两个单独矩阵的原因{1}} transfroms)。使用放置所有对象的世界空间并在该空间中指定虚拟摄像机更加直观。这就是View应该做的事情。如果您将gluLookAt矩阵留在Identity上,就好像您的相机位于世界空间原点,朝向-z方向。因此,为了获得将相机移动到某个指定视点的效果,它与在方向上移动该世界空间中的所有对象相同。轮换也是如此。 view只会设置轮播和翻译。有关详细信息,请查看my previous answer about gluLookAt