我想知道如何调整透视投影以使其看起来像正交投影。例如,假设我有一个 10x10 的点网格,每个点都有不同的 z 值,在正交投影下,它们都很好地排列。在透视投影下,它当然会调整相对于相机的位置和 z 深度。我需要对每个点进行哪些调整,看起来好像它仍然排列在一个正交投影中?(当然,直到相机移动)。
我正在考虑计算从眼睛位置穿过 z 平面的光线(如果这就是你所说的),在我希望它出现的点处,并跟随光线直到所需的深度。虽然我不确定如何实现这一点。
我想知道如何调整透视投影以使其看起来像正交投影。例如,假设我有一个 10x10 的点网格,每个点都有不同的 z 值,在正交投影下,它们都很好地排列。在透视投影下,它当然会调整相对于相机的位置和 z 深度。我需要对每个点进行哪些调整,看起来好像它仍然排列在一个正交投影中?(当然,直到相机移动)。
我正在考虑计算从眼睛位置穿过 z 平面的光线(如果这就是你所说的),在我希望它出现的点处,并跟随光线直到所需的深度。虽然我不确定如何实现这一点。
典型的 OpenGL 投影矩阵(你从 glFrustum 或 gluPerspective 得到的)将相机点放在原点。投影平面位于 (0, 0, -1):相机前面的一个单位。
因此,对于给定的顶点,您需要找到在 (0, 0, -1) 平面上投影时所获得的 X 和 Y 位置。这在技术上是“光线追踪”,但由于它是一个轴对齐的平面,并且相机位于原点,它实际上只是简单的算术:
vec3 newPosition = oldPosition * (-1.0 / oldPosition.z);
请注意,此透视投影下的插值参数在窗口空间中是线性的,而不是眼睛/相机空间。也就是说,不会有透视正确插值。
另外,请注意,上述“简单算术”并未考虑 FOV。为了解决这个问题,您需要oldPosition
通过透视矩阵的左上部分来转换 X 和 Y 。或者只是从投影矩阵中提取 0,0 和 1,1 值并将它们与 的 X 和 Y 相乘oldPosition
。这负责缩放。
还有一点需要注意,因为您没有说明总体目标。
OpenGL 不要求您使用单个投影矩阵渲染整个场景。您可以正交渲染某些场景,而其余部分则使用透视矩阵。这通常在游戏中完成,其中 HUD 和文本元素是正交渲染的,而游戏本身是 3D 透视图。
如果这是您正在做的事情,那么您需要做的就是以下内容:
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(...);
glMatrixMode(GL_MODELVIEW);
//Render my perspective stuff here.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(...);
glMatrixMode(GL_MODELVIEW);
// Render my orthographic stuff here.
如果您的正交对象与透视对象重叠,您可能希望在正交渲染期间关闭深度测试。
如果您使用的是 OpenGL,则无需实现/计算任何东西。您需要做的就是将您的相机设置为正交投影glOrtho
,然后设置您的场景(您的 3D 点网格)。
glFrustum
稍后当相机移动时,您可以捕捉此事件并使用或将相机“重置”为透视投影gluPerspective
。但一定要确保你真的想要这样做——突然改变预测看起来不太好。
如果您正在寻找相机投影的数学,我会推荐这个链接。