将3D矢量投影到2D屏幕坐标

时间:2012-05-07 01:34:53

标签: xna 3d 2d project vertex

我正在使用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
带屏幕线的FPS - 143
FPS没有任何一个 - 152
因此,对于每帧进行大量投影的其他人,我会推荐这样的东西。

1 个答案:

答案 0 :(得分: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