# Trouble transforming vectors from view space to screen space using a perspective projection matrix

I can't for the life of me figure out how to use a perspective projection matrix. My understanding is that, once objects are in view space, the the perspective transform uses the z-coordinate to scale the x and y coordinates.

Here's the code I'm using (C#, dotnet 7).

var viewToScreen = Matrix4x4.CreatePerspectiveFieldOfView((float)(Math.Tau / 4), 1.0f, 0.1f, 100f);

var square1 = new Vector3[]
{
new(+1, +1, 1),
new(-1, +1, 1),
new(+1, +1, 1),
new(+1, -1, 1),
};

var square2 = Array.ConvertAll(square1, v =>
{
v.Z += 3;
return v;
}).Dump("Square 2 (World Space)");

var screen1m1 = Array.ConvertAll(square1, v => Vector3.Transform(v, viewToScreen));

var screen2m1 = Array.ConvertAll(square2, v => Vector3.Transform(v, viewToScreen))


However, after the transform, the X and Y coordinates remain unchanged. Only the Z coordinate is changed, and then only slightly. This is consistent with an orthogonal projection, not a perspective projection.

What am I doing wrong here?

• I don't get the v.Z +=3 part... but projection matrices only work with 4D vectors. After multiplication the result vector needs to be divided by its 4th w component. so: Vector4D result = projectionMatrix * viewMatric * position4D where the 4th component of position4D should be 1. At the end you need to calculate: $result = result / result.w$ Dec 23, 2022 at 9:50
• I'm creating a second set of points, further from the screen along the z coordinate. Dec 23, 2022 at 10:23
• Please add that as an answer. It worked! And, the simple C# solution is just to use Vector4 instead of Vector3, which automatically appends the 1. Dec 23, 2022 at 10:39

The way to do the projection is the following:

Matrix4x4 projection;
Matrix4x4 modelView;
Vector4D position4D;

//fist the position's 4th value (w) need to be set to value "1"
position4D = Vector4D(position3D, 1); //the 1 in the 4th component is very important!
Vector4D result = projection * modelView * position4D;
//at the end, the result need to be divided by its 4th component (w)
result = result / result.w;


The last line is of major importance, because the projection (perspective) is not linear. the division by the 4th component can not be applied within the matrix.