我正在使用OpenGL制作一个游戏,在游戏世界空间中有一些物体。我想要创建一个函数,可以将物体的位置(3D)转换为屏幕上的位置(2D),并返回它。
我已经知道了这些变量:物体的3D位置、投影矩阵和视图矩阵。
Matrix projectionMatrix;
Matrix viewMatrix;
Vector3 point3D;
要进行此转换,您必须首先将模型空间位置转换为剪辑空间。这是通过矩阵乘法实现的。我将使用GLSL样式的代码使其更加明显:
vec4 clipSpacePos = projectionMatrix * (viewMatrix * vec4(point3D, 1.0));
请注意,在进行乘法运算之前,我是如何将您的三维向量转换为四维向量的。这是必要的,因为矩阵大小为4x4,而您无法将4x4矩阵与3D向量相乘,需要添加第四个分量。
下一步是将此位置从剪裁空间转换为归一化设备坐标空间(NDC空间)。NDC空间在所有三个轴上的范围为[-1, 1]。这是通过将前三个坐标除以第四个坐标来完成的:
vec3 ndcSpacePos = clipSpacePos.xyz / clipSpacePos.w;
显然,如果clipSpacePos.w
为零,就会出现问题,所以你应该事先检查一下。如果它是零,那么这意味着物体在投影平面上;它的视图空间深度为零。这样的顶点将被OpenGL自动裁剪。
接下来要做的是将[-1,1]空间转换为窗口相关坐标。这需要使用传递给glViewport
的值。前两个参数是窗口左下角的偏移量(vec2 viewOffset
),后两个参数是视口区域的宽度/高度(vec2 viewSize
)。给定这些值,窗口空间位置为:
vec2 windowSpacePos = ((ndcSpacePos.xy + 1.0) / 2.0) * viewSize + viewOffset;
这就是你能到达的极限。请记住:OpenGL的窗口空间相对于窗口的左下角而不是左上角。
windowSpacePos
应为vec2 (((ndcSpacePos.x + 1.0) / 2.0) * viewSize.x + viewOffset.x,((1.0-ndcSpacePos.y)/ 2.0)* viewSize.y + viewOffset.y)
- László Kustra