WVP and vertex position relationship

Started by
9 comments, last by DividedByZero 8 years, 2 months ago
Hi guys,

I believe I have manually built a WVP column-major matrix by playing around with matrix math from scratch.

Camera position is 0,0,-10
Near plane is 1.0
Far plane = 1000.0;
Aspect ratio = 768.0 / 1024.0;

The output result is


P * V * W

1.66292 0       0       0
0       2.21723 0       0
5       5       16.002  1
0       0       -2.002  0
Firstly, does this look correct given the parameters above?

If so, say a single vertex was positioned at 5,5,5 (as used in the above calculation) what would be the correct way to extract the new vertex postision?

From my understanding it should be elements 12 & 13. But these are zero for some reason.

Thanks in advance. I'm actually having fun learning this side of things more deeply smile.png


[edit]
Using an online matrix calculator, it shows the same result as my calculation (assuming I am going about it the right way).
Advertisement
First of, it is most often called MVP (model->view->projection), which is, tranform your model into world space, then into camera space and then into projection space (btw. a cube, not a flat 2d panel ;-) ).

But back to the issue you have. The basic idea of hom. matricies in game dev is, to move/rotate your object or single vertices in the world. The benefit of using matricies is, that you can chain actions by multiplying it with matrices, eg:
1. move object to enemy position
2. rotate object, so that it face enemy
=>
create translation matrix T
create rotation matrix R
=>
transform = T * R

So, the latter is the transformation matrix most often associated with a single object. It contains rotation and position (and scaling) information.

To transform a matrix, you just need to multiply the matrix with this transform:
output_matrix = transform * input_matrix

Well, if you want to transform a vertex, you only need the position, a vertex does not have a rotation or scaling, therefor you just need a vector (in other words a 1x4/4x1 matrix). So, you need to do this to transform a vector
v'=transform * v

But it is important to expand a 3d position to a 4 component vector, your vector should look like:
v = (x,y,z,1)

Sometimes it is only necessary to consider the rotation of a transformation, e.g. a normal, in this case your vector should look like this:
vn = (nx,ny,nz,0)
the 0 results in ignoring the translation part of the transformation.
Thanks for the reply Ashaman73 smile.png

From your explanation I feel I am doing this correctly.

I'll expand on exactly what I have. Maybe I am transposing something.


// World matrix (actual vertex pos is 5,5,5 and no transforms applied)
1	0	0	0
0	1	0	0
0	0	1	0
5	5	5	1

// View matrix
1	0	0	0
0	1	0	0
0	0	1	0
0	0	10	1

// Projection matrix
1.66292	0	0	0
0	2.21723	0	0
0	0	1.002	1
0	0	-2.002	0
When I multiply these together I get the output of


P * V * W

1.66292 0       0       0
0       2.21723 0       0
5       5       16.002  1
0       0       -2.002  0
I would have though the new x & y co-ords (discarding z as we are now in normalised screen space) should have been elements 12 and 13, but they are left as zero.

Are my calculations off here?

World matrix (actual vertex pos is 5,5,5

The world matrix is not a vertex...

I would have though the new x & y co-ords

You haven't transformed any vertices yet. You can't have new x & y coords if you don't even have original/input x & y coords.

After creating a WVP matrix, you can multiply the vertex position [x,y,z,1] against the WVP matrix to get [x',y',z',w']. The screen (NDC) pos is then: XNDC = x'/w', YNDC = y'/w'

World matrix (actual vertex pos is 5,5,5

The world matrix is not a vertex...

I would have though the new x & y co-ords

You haven't transformed any vertices yet. You can't have new x & y coords if you don't even have original/input x & y coords.


Wouldn't the original vertex pos be the same as the elements 12, 13, 14 of the world matrix assuming you don't want to perform any actual transformations?

I'll reshuffle the calculations as you have suggested and see what results we get then.

Also, assuming there are no transforms, rotations, & scaling required. Couldn't you just multiply VP with the vertex vector?

Thanks again for your patience, it will 'click' soon smile.png



[edit]
Hmmmm. Even when I post multiply the vertex vector (5,5,5,1) with the WVP matrix I get the exact same answer (as I suspected earlier).


1.66292 0       0       0
0       2.21723 0       0
5       5       16.002  1
0       0       -2.002  0

Hmmmm. Even when I post multiply the vertex vector (5,5,5,1) with the WVP matrix I get the exact same answer (as I suspected earlier).


1.66292 0       0       0
0       2.21723 0       0
5       5       16.002  1
0       0       -2.002  0

This doesn't make sense -- a vector4 (AKA 1x4 matrix, or 4x1 matrix, depending on conventions) multiplied by a matrix4x4 produces a vector4 result -- it does not produce a matrix4x4 result.

You want to be doing this, where P/V/W are Mat4x4's, and Vertex is a Mat4x1 (aka Vector4 - and Vertex.w should be 1.0):
ProjectedVertex = Projection * View * World * Vertex

Note that you can do it this way, which is three "Mat4x4 * Mat4x1" operations:
ProjectedVertex = Projection * (View * (World * Vertex))
Or you can do it this way, which is two "Mat4x4 * Mat4x4" operations, and one "Mat4x4 * Mat4x1" operation:
ProjectedVertex = ((Projection * View) * World) * Vertex
Both should produce the same result.

So... as well as your Mat4x4 Multiply(Mat4x4 a, Mat4x4 b) function, you also need a Vec4 Multiply(Mat4x4 a, Vec4 b) function.

Also, assuming there are no transforms, rotations, & scaling required. Couldn't you just multiply VP with the vertex vector?

Yes. The "world" matrix is actually the "model space to world space transform". If the vertices are already in world-space, then this matrix would be identity, which does nothing (so could be optimized out).

You ninja'd me with you post. I was in the process of replying.

What you have said above seems to confirm my thoughts.

I was soon aware that I needed to multiply Mat4x4 by vec4 as you have just said.

So I did this (to save re-writing another function).

I multiplied the WVP matrix with the following (hopefully it is the same as multiplying by a vec4).


0       0       0       5
0       0       0       5
0       0       0       5
0       0       0       1
and then performed XNDC = x'/w', YNDC = y'/w' as per your advice.

I now have a vertex pos of -0.830629, -1.10751 which seems to be a bit more reasonable.

Does this now seem right (or getting closer)?

Thanks again smile.png


[edit]
The results are still 'off', so I am writing a proper vec4 mat4 multiplier function.

[edit2]
Did that. Results are still off from what I can see.

Sorry guys, I'm embarrassed to ask any more. I feel I must have reached that annoying level now.
I think the problem now lies within how I have set up the view matrix.

I can changes the values of camx, y, and z. But it doesn't affect the VP matrix at all.
I think I am done with trying to learn this. My brain just exploded all over the screen, making it hard to read...

In my opinion, you're trying to combine and apply too many concepts at once. Have you understood how to work with matrices and vectors?

You should try and ignore the projection and view matrix and just focus on world transformation matrices first. Just treat projection*view as a black box that transforms stuff in such a way that you can see it on screen and try to figure out what rotation, scale and translation matrices do with individual vectors and subsequently with simple objects (e.g. a box). Projection is an advanced concept that's hard to grasp if you don't know the basic stuff.

If there's still interest I can write up another part on 3d transformations and why you work in 4 dimensions. Maybe I should write a series of articles...

This topic is closed to new replies.

Advertisement