Skip to content
Model-View-Projection (MVP) Transform
step 1/5

Reading — step 1 of 5

Read

~1 min read3D Math

Model-View-Projection (MVP) Transform

Every vertex in a 3D pipeline gets multiplied by MVP to land on the screen:

clipPos = P * V * M * vertex
  • M (Model): object's local coords → world coords (where it is in the scene).
  • V (View): world coords → camera coords (camera at origin, looking down -Z).
  • P (Projection): camera coords → clip coords (the canonical -1..1 frustum after perspective divide).

Read right-to-left: vertex is first lifted to world by M, then dragged into camera space by V, then warped by P.

LookAt: build V from camera position eye, target at, and up vector up:

f = normalize(at - eye)
r = normalize(cross(f, up))
u = cross(r, f)
View = [[ r.x,  r.y,  r.z, -dot(r, eye) ],
        [ u.x,  u.y,  u.z, -dot(u, eye) ],
        [-f.x, -f.y, -f.z,  dot(f, eye) ],
        [   0,    0,    0,            1 ]]

Perspective projection (OpenGL convention):

f = 1 / tan(fov / 2)
P = [[ f/aspect, 0,                      0,                          0 ],
     [        0, f,                      0,                          0 ],
     [        0, 0, (near+far)/(near-far),  (2*near*far)/(near-far) ],
     [        0, 0,                     -1,                          0 ]]

After P * V * M * v, divide by w to get NDC (normalized device coords), then map (-1..1) → pixels with the viewport transform.

This is the entire vertex-shader job for 99% of triangle work. Cache MVP per draw call; recompute only when the camera or object moves.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…