在3D图形中,什么是相机或眼睛空间?

6

我正在尝试通过Jason L. McKesson的《学习现代3D图形编程》来学习3D图形编程。

我还没有看过其他指南,但这个指南似乎强调了3D图形背后的理论和数学知识。目前,我卡在了这一页:

http://www.arcsynthesis.org/gltut/Positioning/Tut04%20Perspective%20Projection.html

我不确定他所说的相机空间是什么,以及为什么需要将3D世界投影到2D表面上。这个问题有些模糊,因此除了完整的解释外,也希望提供一些可能会给我不同解释方式的链接。

抱歉,我应该让这更清晰:我确实知道为什么需要将3D世界投影到2D表面上。我只是不知道为什么相机空间对此有必要或有用。 - newprogrammer
4个回答

8

由于你的屏幕是二维的,因此必须将三维世界投影到二维表面上。

3D图形在不同的“坐标空间”中工作,并且这些空间之间进行转换以得到最终场景。

例如,想象一下建模一个城市。您可以将地图的左下角定义为(0,0),将右上角定义为(1000000,1000000)。您可能还会说,规则是一个点代表真实空间的一英尺。我们将这种表示称为世界空间。

要绘制城市,您需要导入一些建筑模型并将其放置在世界中。因此,您获得了建筑物的模型,但在制作此模型时,您不希望担心世界的大小或位置-您可能会说,建筑物的左下角位于(0,0),其右上角位于(1,1)。我们将这种表示称为模型空间。但是,在世界中,建筑物可能被放置在(104,136)处,并且您可能希望它的大小为1000x1000像素,因此您需要将其从模型空间转换为世界空间,即将其平移至(104,136),并将其缩放1000倍。

最后,相机空间是您在世界中移动的方式。如果您考虑一下,可以将在世界中移动视为两种方式(至少):您在世界中移动,或者世界在您周围移动。因此,为了使移动变得容易,我们将说相机始终位于点(0,0),面向某个轴线。现在,如果您想向前移动10个像素,您只需将所有内容向后移动10个像素。如果要旋转,则旋转整个世界。因此,要呈现建筑物,首先我们要将其从模型空间转换为世界空间。现在,要实际绘制它,我们需要知道它相对于观察者的位置,因此我们将其从世界空间移动到相机空间。

另外,如果您想非常好地理解这一点,一个很好的练习是编写一个3D线框渲染器,与OpenGL分开。您唯一可用的绘图函数是DrawLine(x1,y1,x2,y2),它在屏幕上从(x1,y1)到(x2,y2)绘制一条线。


那将是一个相当大的挑战。感谢您的解释! - newprogrammer
1
这并不像你想象中的那么难。我们使用变换的原因最终是为了将其投影到屏幕上并确定“这些点究竟属于哪里”。基本上,编写线框渲染器意味着你要自己完成所有矩阵乘法 - 平移、旋转,然后投影。3D图形的真正困难部分是阴影和裁剪,但如果你正在编写线框渲染器,则无需担心这些问题。这会让你更加欣赏和理解数学。 - mindvirus

6

相机空间是相对于相机的坐标系。因此,相机空间是在投影之前几何模型最终所到达的位置。

通常你从模型空间中获取坐标。你知道模型与世界之间的关系,因此可以将其从模型空间映射到世界空间。然后,你有一个位于世界中的相机,并利用该相机的信息从世界空间映射到相机空间。如果没有相对于相机的空间变换,相机就无法移动。

投影是必要的,因为你的世界是3D的,而你的屏幕是2D的。你将3D世界投影到计算机显示器的2D表面上。即使立体视觉也只是两个投影而不是一个。

我目前没有比你提供的更好的链接。


你的解释非常有帮助,谢谢。这个指南直到几章后才介绍模型空间或移动相机,但你所说的似乎很符合直觉。 - newprogrammer
另外,如果我理解你的意思正确的话,相机空间是在投影到二维平面之前吗? - newprogrammer
是的 - 相机空间是标准多边形渲染器流程中投影之前的最后一次变换的结果。 - Tommy

6
为什么需要将3D世界投影到2D表面?
所有图形都只是2D图像。因此,3D图形是一种为像素生成颜色的系统,使您相信您看到的场景是一个3D世界而不是2D图像。将3D世界转换为该世界的2D图像的过程称为渲染。
在渲染中,投影是一种将世界从一维变换为另一维的方法。我们的目标图像是二维的,而我们的初始世界是三维的。因此,我们需要一种将这个3D世界转换成2D世界的方法。
我不确定他所说的相机空间是什么意思
在这之前,顶点位置是直接用剪辑空间表示的。请记住,除以W是剪辑空间顶点位置的一部分。透视投影是一种将位置转换为剪辑空间的方式,使它们看起来像是3D世界的透视投影。
这个转换过程有明确定义的输出:剪辑空间位置。但是它的输入值到底是什么呢?
那就是相机空间。
这不是OpenGL认可的空间(与GL明确定义的剪辑空间不同);它完全是用户的任意构建。然而,基于我们对透视投影的了解,定义一个特定的相机空间可能是有用的。这可以最小化相机空间和剪辑空间透视形式之间的差异,并简化我们的透视投影逻辑。

好的,谢谢。这个问题的所有回答都很好,但是这个答案真正解释了为什么我们需要定义一个摄像机空间。我不确定我完全正确地理解了这一点,但我认为我之前对他为什么使用摄像机空间感到困惑是因为他还没有移动相机,所以我不知道他为什么要在第一时间就处理这个问题。 - newprogrammer

4

如果你想快速回答为什么需要将3D世界投影到2D表面,那么请思考使用2D媒介(例如屏幕)来表示一个3D世界(您在程序中定义的内容)。但是,要做到这一点,需要进行相当复杂的数学计算,所以这取决于你愿意深入探究的程度...

引用维基百科(http://en.wikipedia.org/wiki/Graphics_pipeline):

对象从3D世界空间坐标变换为基于虚拟摄像机的位置和方向的3D坐标系。这导致了原始3D场景从摄像机视角看到的东西,以眼空间或相机空间定义。规范化变换是查看变换的数学反演,并且从任意用户指定的坐标系统(u, v, w)映射到规范坐标系统(x, y, z)。


我只是按照这个指南的深度前进,而且看起来我已经深入到很深的地方了! - newprogrammer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接