正交到透视调整计算

发布于 2024-11-28 10:51:03 字数 240 浏览 2 评论 0原文

我想知道如何调整透视投影以使其看起来像正交的。例如,假设我有一个 10x10 的点网格,每个点都有不同的 z 值,在正交投影下所有点都排列得很好。在透视投影下,它当然会调整相对于相机的位置和 z 深度。我需要对每个点进行哪些调整,使其看起来仍然排列并处于正交投影中? (当然,直到相机移动)。

我正在思考沿着从眼睛位置通过 z 平面(如果这就是你所说的)的光线计算的思路,在我希望它出现的点上,并跟随光线直到所需的深度。虽然我不太确定如何实现这一点。

I was wondering how I might adjust a perspective projection to make it look like it was orthographic. For example, say I had a 10x10 grid of points, each with different z values, which under an orthographic projection all lines up nicely. Under a perspective projection it will of course adjust the positions relative to the camera and the z depth. What adjustments do I need to make to each point appear as though it is still lined up and in an orthographic projection? (Until the camera moves of course).

I'm thinking along the lines of calculating a ray from the eye position through the z plane (if that's what you'd call it) at the point at which I'd like it to appear and following the ray until the required depth. Although I'm not really sure how to implement this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

橘香 2024-12-05 10:51:03

典型的 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 值并将它们与 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.

如果您有与透视对象重叠的正交对象,您可能需要在正交渲染期间关闭深度测试。

The typical OpenGL projection matrix (what you get from glFrustum or gluPerspective) puts the camera point at the origin. The plane of projection is at (0, 0, -1): one unit in front of the camera.

So for a given vertex, what you need to find is the X and Y positions you would get for a projection onto the (0, 0, -1) plane. This is technically "ray tracing", but since it's an axis-aligned plane, and the camera is at the origin, it really is just simple arithmetic:

vec3 newPosition = oldPosition * (-1.0 / oldPosition.z);

Note that interpolating parameters under this perspective projection will be linear in window space, not eye/camera-space. That is, there will be no perspective correct interpolation.

Also, note that the above "simple arithemtic" does not take into account FOV. To handle that, you need to transform the X and Y of oldPosition by the upper-left part of the perspective matrix. Or just extract the 0,0 and 1,1 values from the projection matrix and multiply them with the X and Y of oldPosition. That takes care of the scaling.


One more note, since you did not state the overall goal of this.

OpenGL does not require you to render an entire scene with a single projection matrix. You can render some of a scene orthographically, while using a perspective matrix for the rest. This is often done in games, where the HUD and text elements are rendered orthographically, while the game itself is in a 3D perspective.

If this is what you're doing, all you need to do is something like the following:

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.

You may want to turn off depth tests during the orthographic rendering, if you have ortho objects that overlap the perspective ones.

瀞厅☆埖开 2024-12-05 10:51:03

如果您使用 OpenGL,则无需实现/计算任何内容。您需要做的就是使用 glOrtho 将相机设置为正交投影,然后设置场景(3D 点网格)。

稍后当相机移动时,您可以捕获此事件并使用 glFrustumgluPerspective 将相机“重置”为透视投影。但一定要确保你真的想这样做——突然改变预测看起来不太好。

如果您正在寻找相机投影的数学知识,我会推荐此链接。

http://www.songho.ca/opengl/gl_projectionmatrix.html

If you are using OpenGL you don't have to implement/calculate anything. All you will need to do is setup your camera to an orthographic projection using glOrtho and then setup your scene (your grid of 3D points).

Later when the camera moves you can catch this event and "reset" the camera to a perspective projection using glFrustum or gluPerspective. But do make sure you really want to do this - changing projections abruptly doesn't look good.

If you are looking for the mathematics of camera projections I would recommend this link.

http://www.songho.ca/opengl/gl_projectionmatrix.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文