1
\$\begingroup\$

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?

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

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.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.