2

Opengl精湛的第4版.第164页

为了应用相机变换,我们采用相机的actor变换并翻转它,这样向后移动相机就相当于向前移动整个世界。同样,向左转,就相当于将整个世界向右旋转。

我不明白为什么?

4

2 回答 2

3

想象自己置身于一个包含所有其他事物的宇宙中。为了使您的观点看起来向前移动,您有两个选择...

  1. 你让自己前进。
  2. 你将宇宙中的其他一切都向与 1 的相反方向移动。

因为您在 OpenGL 中根据查看器定义所有内容(您最终要渲染 3D 世界特定视点的 2D 图像),所以从数学和编程的角度来看,采用第二种方法通常更有意义。

于 2013-09-25T13:58:27.160 回答
2

数学上只有一个正确答案。它被定义为在通过将位置eye-space乘以转换为之后,结果向量被解释为相对于原点(相机在概念上相对于上述点所在的空间位置)。world-spaceview-matrix

SuperBible 所说的在数学上只是对某个方向的转换的否定,这是您在使用计算view-matrix类似gluLookAt()或的函数时会自动得到的glmLookAt()(尽管 GLU 是一个分层在遗留 GL 东西上的库,但在数学上两者是相同的)。

查看gluLookAt(). 你会看到第一步是建立一个正交基,eye-space它首先产生一个 4x4 矩阵,基本上只编码上面的 3x3 旋转矩阵。第二个是将前一个矩阵乘以一个平移矩阵。就遗留功能而言,这可以表示为

glMultMatrixf(M); // where M encodes the eye-space basis
glTranslated(-eyex, -eyey, -eyez);

您可以看到,(eyex, eyey, eyez)指定相机所在位置的向量world-space只需乘以-1。现在假设我们根本不旋转相机,而是假设它位于world-space位置 (5, 5, 5)。适当的视图矩阵View将是

[1 0 0 -5
0 1 0 -5
0 0 1 -5
0 0 0 1]

现在取一个world-space由该矩阵变换的顶点位置 P = (0, 0, 0, 1):P' = View * PP'然后将只是P'=(-5, -5, -5, 1).

思考时world-space,相机在(5, 5, 5),顶点在(0, 0, 0)。思考时eye-space,相机在(0, 0, 0),顶点在(-5, -5, -5)

所以总结:从概念上讲,这是你如何看待事物的问题。您可以将其视为相对于世界变换相机,也可以将其视为相对于相机变换世界。

在数学上,就 OpenGL 转换管道而言,只有一个答案,那就是:(eye-spaceview-spacecamera-space)中的相机始终位于原点,world-space转换到的位置eye-space将始终相对于相机的坐标系。

编辑:澄清一下,虽然转换管道和所涉及的向量空间定义明确,但您仍然可以使用world-space所有东西的位置,甚至是相机,例如在片段着色器中进行照明计算。这里重要的是要知道永远不要混合来自不同空间的实体,例如不要根据一个world-space eye-space位置等计算东西。

EDIT2:如今,在我们都使用着色器*咳嗽和翻白眼*的时代,您非常灵活,理论上您可以gl_Position顶点着色器(或几何着色器曲面细分阶段)中传递您喜欢的任何位置。然而,由于后续的计算是固定的,即裁剪透视分割视口变换,如果结果位置不在和内部[-gl_Position.w, gl_Position.w],则将简单地裁剪结果位置。xyz

要真正做到这一点,有很多事情要做。我建议您阅读官方 GL wiki 中有关渲染管道的整篇文章。

于 2013-09-25T14:36:23.183 回答