Opengl精湛的第4版.第164页
为了应用相机变换,我们采用相机的actor变换并翻转它,这样向后移动相机就相当于向前移动整个世界。同样,向左转,就相当于将整个世界向右旋转。
我不明白为什么?
Opengl精湛的第4版.第164页
为了应用相机变换,我们采用相机的actor变换并翻转它,这样向后移动相机就相当于向前移动整个世界。同样,向左转,就相当于将整个世界向右旋转。
我不明白为什么?
想象自己置身于一个包含所有其他事物的宇宙中。为了使您的观点看起来向前移动,您有两个选择...
因为您在 OpenGL 中根据查看器定义所有内容(您最终要渲染 3D 世界特定视点的 2D 图像),所以从数学和编程的角度来看,采用第二种方法通常更有意义。
数学上只有一个正确答案。它被定义为在通过将位置eye-space
乘以转换为之后,结果向量被解释为相对于原点(相机在概念上相对于上述点所在的空间位置)。world-space
view-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 * P
。P'
然后将只是P'=(-5, -5, -5, 1)
.
思考时world-space
,相机在(5, 5, 5)
,顶点在(0, 0, 0)
。思考时eye-space
,相机在(0, 0, 0)
,顶点在(-5, -5, -5)
。
所以总结:从概念上讲,这是你如何看待事物的问题。您可以将其视为相对于世界变换相机,也可以将其视为相对于相机变换世界。
在数学上,就 OpenGL 转换管道而言,只有一个答案,那就是:(eye-space
或view-space
或camera-space
)中的相机始终位于原点,world-space
转换到的位置eye-space
将始终相对于相机的坐标系。
编辑:澄清一下,虽然转换管道和所涉及的向量空间定义明确,但您仍然可以使用world-space
所有东西的位置,甚至是相机,例如在片段着色器中进行照明计算。这里重要的是要知道永远不要混合来自不同空间的实体,例如不要根据一个world-space
和和eye-space
位置等计算东西。
EDIT2:如今,在我们都使用着色器*咳嗽和翻白眼*的时代,您非常灵活,理论上您可以gl_Position
在顶点着色器(或几何着色器或曲面细分阶段)中传递您喜欢的任何位置。然而,由于后续的计算是固定的,即裁剪、透视分割和视口变换,如果结果位置不在和内部[-gl_Position.w, gl_Position.w]
,则将简单地裁剪结果位置。x
y
z
要真正做到这一点,有很多事情要做。我建议您阅读官方 GL wiki 中有关渲染管道的整篇文章。