我正在使用 XNA 4.0 并尝试将 Vector3 转换为代表其在屏幕上的坐标的 Vector2。 我知道你可以使用 Viewport.Project 这给了我完美的结果,但我需要制定自己的方法来做到这一点。 我必须将每个顶点转换为每帧的 2D 坐标,并在 CPU 而不是 GPU 上进行。 使用提供的 Project 方法比我想要的要慢一些。 它也返回一个“z”值,我什至不会使用它。我只想以最简单的方式返回 (x, y)。
这是我到目前为止所得出的结果,它给出了几乎正确的结果。但还没有完全实现
private Vector2 ScreenCoords(Vector3 v)
{
return new Vector2(
viewProj.M11 * v.X + viewProj.M21 * v.Y + viewProj.M31 * v.Z + viewProj.M41,
viewProj.M12 * v.X + viewProj.M22 * v.Y + viewProj.M32 * v.Z + viewProj.M42);
}
viewProj 只是 (viewMatrix * ProjectionMatrix)
屏幕中心的顶点似乎总是返回为 (0, 0),但当顶点改变屏幕坐标时(当我移动相机时),我得到的结果有点困惑 当顶点向左移动时,我的投影结果的 X 会减小,当顶点向下移动时,我的投影结果的 Y 会增加。 所以至少我有这个权利,但它们的变化速度不正确或不一致。
编辑:这是如何完成的,可能是最快的方法(请注意,这返回 [-1, 1] 范围内的坐标)
private Vector2 ScreenCoords(Vector3 v)
{
float
w = viewProj.M14 * v.X + viewProj.M24 * v.Y + viewProj.M34 * v.Z + viewProj.M44;
return new Vector2(
(viewProj.M11 * v.X + viewProj.M21 * v.Y + viewProj.M31 * v.Z + viewProj.M41) / w,
(viewProj.M12 * v.X + viewProj.M22 * v.Y + viewProj.M32 * v.Z + viewProj.M42) / w);
}
这是与使用 Viewport.Project 获取 2D 坐标的比较 -
FPS 项目 - 81
带有 ScreenCoords 的 FPS - 143
没有任何一个的 FPS - 152
因此,我会向每帧进行大量投影的其他人推荐类似的东西。
最佳答案
你应该意识到透视投影需要同质坐标,你应该除以
由同源因子 W 组成的组件。
这是数学:
Vector4 position = new Vector4(pos3, 1);
Vector4.Transform(ref position, ref worldViewProjection, out position);
position /= position.W;
您还可以在这里找到更多信息:http://en.wikipedia.org/wiki/Transformation_matrix#Perspective_projection
关于xna - 将 3D 矢量投影到 2D 屏幕坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10475735/