I am trying to figure out how XNA is actually projecting a 3d world space coordinate to screen space.

I decompiled the MonoGame framework and copied the CreateLookAt und CreatePerspectiveFieldOfView methods of Matrix and multiplied thereafter 3 vectors like XNA does:

First multiply each position with world, then multiply resultig new vector4 with view and then the new resulting vector4 finally by projection.

      public static Vector2<T> Project(Vector3<T> source, Matrix4x4<T> world, Matrix4x4<T> view, Matrix4x4<T> projection, int width, int height)
        Vector4<T> worldPosition = world * new Vector4<T>(source.X.ParseToNumeric<T>(), source.Y.ParseToNumeric<T>(), source.Z.ParseToNumeric<T>(), 1);
        Vector4<T> viewPosition = view * worldPosition;
        Vector4<T> position = projection * viewPosition;

        var X = position.X.ParseToNumeric<T>();
        var Y = position.Y.ParseToNumeric<T>();
        var Z = position.Z.ParseToNumeric<T>();

        return new Vector2<T>((X / Z) + width / 2, (Y / Z) + height / 2);


Because (0,0,0) would be the center of the screen I added to the corresponding X and Y coordinates width and height divided by 2. Just because it made sense I divided finally the xy components by z.

The result is sobering: My implementation

XNA's implementation

I used following matrices:

      basicEffect.World = Matrix.Identity;
        basicEffect.View = Matrix.CreateLookAt(new Vector3(0, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 1, 0));
        basicEffect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, GraphicsDevice.Viewport.AspectRatio, 0.1f, 1000.0f);

And these points:

            vertices[0] = new VertexPositionColor(new Vector3(0, 0, 2), Color.Red);
        vertices[1] = new VertexPositionColor(new Vector3(1, 0, 2), Color.Red);
        vertices[2] = new VertexPositionColor(new Vector3(0, 1, 2), Color.Red);

Do you know why this happens?

  • \$\begingroup\$ I'm pretty sure your triangle is too small. \$\endgroup\$
    – Bálint
    Apr 11, 2017 at 6:05
  • \$\begingroup\$ That's the point.. \$\endgroup\$ Apr 11, 2017 at 17:47
  • \$\begingroup\$ Why decompile MonoGame? It is open source. \$\endgroup\$
    – lozzajp
    Jun 13, 2017 at 12:30

1 Answer 1


MonoGame and XNA use a drawing API (such as OpenGL or DirectX), these operate on coordinates between -1 and 1, and they convert the output to device coordinates after everything is calculated (before the fragment shader basically), that's why your triangle is so big on the second image.

To make the triangle look correct, you need to multiply the 2d coordinates you get as a result with the width and height of the window.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .