2

我正在使用 XNA 4.0 并尝试获取 Vector3 并将其转换为 Vector2,它表示其在屏幕上的坐标。我知道您可以使用 Viewport.Project,这给了我完美的结果,但我需要制定自己的方法来做到这一点。我必须在 CPU 而不是 GPU 上将每个顶点转换为每帧的 2D 坐标。使用提供的 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 坐标的比较 -使用 Project 的 FPS - 使用 ScreenCoords
的 81 FPS - 没有任何一个的 143 FPS - 152 所以我会向其他每帧进行大量投影的人推荐这样的东西。


4

1 回答 1

2

你应该意识到透视投影需要齐次坐标,你应该划分

由 homegeneus 因子 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

于 2012-05-07T13:08:08.420 回答