0

Brief overview, you can image I'm drawing points of a 3D schematic onto a Canvas, think CAD.

I have points in 3D XYZ Vector3 coordinates, and I've got a model, view, projection matrix all setup. I've done this and produced OpenGL and Metal (Mac/iOS) views and they all work great.

I now just wanted to plot points on a 2D canvas (SkiaSharp) as another view representation but I've run into an issue I just can't wrap my head around.

First I did a plain Orthographic view of it and this worked fine.

I used Matrix4x4 CreateOrthographic to do the Projection matrix (https://learn.microsoft.com/en-us/dotnet/api/system.numerics.matrix4x4.createorthographic?view=net-8.0)

And I used CreateLookAt for the View matrix (https://learn.microsoft.com/en-us/dotnet/api/system.numerics.matrix4x4.createlookat?view=net-8.0)

The Camera is placed vertically above the single model center and looks down (position is Center.X, Center.Y, 10 for example and target Center.X, Center.Y, 0 with the camera Up as the unit Y vector.

This all looks fine in Orthographic.

So then I tried a Perspective projection matrix.

I used the CreatePerspectiveFieldOfView (https://learn.microsoft.com/en-us/dotnet/api/system.numerics.matrix4x4.createperspectivefieldofview?view=net-8.0) - which I used with the data for OpenGL/Metal (and that looks exactly as expected), but the more manually created on in a Skia canvas just doesn't look right.

It still looks Orthographic???

Here's what I've tried and found....

1 - The view looks orthographic. When I rotate the model, I have a large flat grid in it, and the far edge of the grid is the same size on screen as the near edge of the grid .... so seemingly orthographic but its a 'perspective FOV matrix'.

2 - When I try and move the camera in the Z axis (either in the CreateLookAt position or after the fact with a translation)....the view doesn't change at all. Again, something I could understand with an Orthographic view but not perspective FOV?

3 - The Aspect Ratio I input into the perspective stretches the view vertically or horizontally. I'm having to put in 1 (square) to get a non-stretched view (Red flag!)

4 - FOV doesn't appear to do much except scale the whole view (as you'd expect, it gets smaller/larger) - but still appearing orthographic?

Does anyone have any ideas as to why/what/how you might see this sort of affect? What could I have set up wrong or interpreted wrong to result in such an output? Is there a step I've missed that a GPU would do in OpenGL/Metal as to why these matrices appear fine when transforming vertices into a shader, but not when manually processing Vector3's and drawing onto Skia?

1 Answer 1

1

For anyone else finding similar outputs, there is a reason why a perspective matrix in an MVP setup could appear Orthographic, the issue is there's a stage OpenGl/Directx/metal all do automatically that I missed.

You need to do a Perspective Divide which I forgot to do.

So, taking the Vector3 world position, take a Vector4 with the w value set to 1 - and transform this with your MVP matrix.

Then, with the resulting Vector4, you can create a new Vector3 where each component is the Vector4 component divided by the Vector4 W value.

So,

X = vec.X / vec.W
Y = vec.Y / vec.W
Z = vec.Z / vec.W

For screen space you only need X and Y.

So why does it appear as Orthographic if you don't do this?

Well the W value is the depth of the projected point between your near and far clip plane. So if you don't do the division, it's like dividing each point by 1 - which puts everything visual at the same depth (the far plane) - making it look Orthographic!

So the full steps roughly needed...

Vector3 wordPos;
Matrix4x4 MVP;
Vector4 input = new Vector4(worldPos, 1f);
Vector4 trans = Vector4.Transform(input, MVP);
Vector2 screen = new Vector2(trans.X / trans.W, trans.Y / trans.W);

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