Let’s just set ourselves in the camera view space. In BJS left-handed convention, Z is forward in the look direction, X is right and Y is up. (On the drawing, X is toward us)
Here on the drawing, projection plane untilted is AC. Projection plane tilted by angle alpha is EF. Camera is B on the left
By definition, a perspective projection projects every point P in the scene on the projection plane (here lying at Z), along the direction BP, that’s the pinhole model. We get the projected point G by dividing P’s coordinates by P.z, the z coordinate, with a projection matrix :
(
a, 0, 0, 0,
0, b, 0, 0,
0, 0, c, 1,
0, 0, d, 0
)
The 1 in the last column allows us to get this division when we normalize homogeneous coordinates with w.
But in our case, we want to project on the tilted plane directed by EF to get H, and still along the direction BP. For that, we want to find the z-coordinate of H, written as z on the image. For this we just need a bit of geometry :
As similar triangle, we have Y / Z = y / z
, so y = Y * z / Z
With some trigonometry in the triangle HIO, we get : z = Z - y * tan(alpha)
We replace with above : z = Z - Y * z * tan(alpha) / Z
.
Grouping z
together : z = Z / (1 + Y * tan(alpha) / Z)
Now we are ready to use P’s coordinates (Px, Py, Pz)
:
As similar triangles, Py / Pz = Y / Z
, so Y = Py * Z / Pz
We replace : z = Z / (1 + Py * tan(alpha) / Pz)
.
Now, perspective projection is about multiplying every coordinate of P by the same thing to get Pz => z
, so here, we are going to multiply everything by z / Pz
, hence :
Px
Py
Pz
=>
Px * Z / (Pz + Py * tan(alpha)),
Py * Z / (Pz + Py * tan(alpha)),
Pz * Z / (Pz + Py * tan(alpha))
In matrix form, this new transformation is :
(
a, 0, 0, 0,
0, b, 0, tan(alpha),
0, 0, c, 1,
0, 0, d, 0
)