c++ /OpenGL转换世界坐标到屏幕(2D)坐标



我正在用OpenGL制作一款游戏,在世界空间中我有一些对象。我想做一个函数,我可以在一个对象的位置(3D),并将其转换为屏幕的位置(2D),并返回它。

我知道物体的三维位置,投影矩阵和视图矩阵在以下变量中:

Matrix projectionMatrix;
Matrix viewMatrix;
Vector3 point3D;

要进行此转换,必须首先获取模型空间位置并将其转换为剪辑空间。这是用矩阵乘法完成的。我将使用glsl风格的代码使我所做的事情更明显:

vec4 clipSpacePos = projectionMatrix * (viewMatrix * vec4(point3D, 1.0));

注意我是如何在乘法之前将你的3D向量转换成4D向量的。这是必要的,因为矩阵是4x4的,而你不能将4x4矩阵与3D向量相乘。你需要第四个组件。

下一步是将该位置从clip-space转换为归一化设备坐标空间(NDC空间)。NDC空间在所有三个轴上都在[- 1,1]范围内。这是通过将前三个坐标除以第四个坐标来完成的:

vec3 ndcSpacePos = clipSpacePos.xyz / clipSpacePos.w;

显然,如果clipSpacePos.w为零,则有问题,因此您应该事先检查。如果它是零,那就意味着物体在投影平面上;它的视空间深度为0。这些顶点被OpenGL自动裁剪。

下一步是将这个[- 1,1]空间转换为窗口相对坐标。这需要使用传递给glViewport的值。前两个参数是窗口左下角的偏移量(vec2 viewOffset),后两个参数是视口区域的宽度/高度(vec2 viewSize)。给定这些,窗口空间位置为:

vec2 windowSpacePos = ((ndcSpacePos.xy + 1.0) / 2.0) * viewSize + viewOffset;

你就到这里了。记住:OpenGL的窗口空间是相对于窗口左下角的,而不是左上角。

最新更新