我想知道如何调整透视投影以使其看起来像是正字法。例如,假设我有一个10x10的点网格,每个点都有不同的z值,在正交投影下,所有点都很好。在透视投影下,它当然会调整相对于相机的位置和z深度。我需要对每个点做出哪些调整,好像它仍然排成一行并在正投影中? (当然直到相机移动)。
我正在考虑计算从眼睛位置到z平面的光线(如果这就是你所说的那样)在我希望它出现并跟随光线直到要求的深度。虽然我不确定如何实现这一点。
答案 0 :(得分:0)
典型的OpenGL投影矩阵(从glFrustum或gluPerspective获得)将相机点置于原点。投影平面位于(0,0,-1):摄像机前面的一个单位。
因此对于给定的顶点,您需要找到的是投影到(0,0,-1)平面上的X和Y位置。这在技术上是“光线追踪”,但由于它是一个轴对齐的平面,并且相机位于原点,它实际上只是简单的算术:
vec3 newPosition = oldPosition * (-1.0 / oldPosition.z);
请注意,此透视投影下的插值参数在 window 空间中将是线性的,而不是眼睛/相机空间。也就是说,没有perspective correct interpolation。
另外,请注意上述“简单的arithemtic”没有考虑到FOV。要处理这个问题,您需要将oldPosition
的X和Y转换为透视矩阵的左上角部分。或者只是从投影矩阵中提取0,0和1,1并将它们与oldPosition
的X和Y相乘。这需要处理扩展。
还有一点需要注意,因为你没有说明这个目标。
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.
如果正交对象与透视对象重叠,您可能希望在正交渲染期间关闭深度测试。
答案 1 :(得分:-1)
如果您使用OpenGL,则无需实施/计算任何内容。您需要做的就是使用glOrtho
将相机设置为正交投影,然后设置场景(3D点的网格)。
稍后当相机移动时,您可以捕捉此事件并使用glFrustum
或gluPerspective
将相机“重置”为透视投影。但要确保你真的想要这样做 - 突然改变预测并不好看。
如果您正在寻找相机投影的数学,我建议您使用此链接。