lin[cam_, obj_][t_] := cam t + (1 - t) obj
s[cam_, obj_] := First@Solve[lin[cam, obj][t][[3]] == 0, t];
tr[cam_, obj_] := lin[cam, obj][t] /. s[cam, obj] // FullSimplify
And that's it: tr[ ]
is your transformation function.
Let's test it with a Rubik's cube, simulating the video you linked. The following boring part is building the cube. We will make only three faces, since the rest aren't visible.
(*The following is a face with random colors*)
d = .05; col := RandomChoice[{Red, Orange, Green, White, Yellow, Blue}];
face := Table[{col, EdgeForm[Black], Polygon[{{i + d, j + d, 0}, {i + 1 - d, j + d, 0},
{i + 1 - d, j + 1 - d, 0}, {i + d, j + 1 - d, 0}}]},
{i, 0, 2}, {j, 0, 2}]
(*Now we build a "3-faced-cube"*)
m = RotationTransform[Pi, {0, 1, 0}, 3/2 {1, 0, 1}];
cube = Table[(face /. Polygon[x_] :> Polygon[m /@ (RotateLeft[#, i] & /@ x)]), {i, 0, 2}];
Graphics3D[cube, Axes -> True, Lighting -> {{"Ambient", White}}]

And now (surprise!) we project the cube onto a sheet of paper using the function defined at the top.
Let's see two views. First, the one faking a 3D view made by selecting the appropriate ViewPoint and ViewVector (meaning the camera position and direction):
Graphics3D[cube /. Polygon[x_] :> Polygon[tr[{10, -10, 10}, #] & /@ x],
Lighting -> "Neutral", ViewVector -> {{10, -10, 10}, {0, 3, 0}}, Boxed -> True]

And now the "real" paper sheet for you to print it and make your own video :)
Framed@Graphics[cube /. (Polygon[x_] :> Polygon[tr[{10, -10, 10}, #] & /@ x]) /.
Polygon[x_] :> Polygon[Most /@ x]]

Edit:
Raising and then lowering the camera:
.