Sunday, August 17, 2014

Homemade 3D rendering engine (VI)

After the detour to mathematics, it’s time to complete the projection. We note firstly that, the projection we wanted is a function, given the world’s coordinate, returns the point’s eye’s coordinate.

Remember we knew the axis of the eye’s coordinate system as vectors in the world’s coordinate system, it make the inverse problem of the projection easy. Given a point $ (e_x, e_y, e_z)^T $ in the eyes coordinate system, all we need to do to compute $ (w_x, w_y, w_z)^T $ is to apply the axis as follow:

$\left(\begin{matrix}{w_x\\w_y\\w_z}\end{matrix}\right) = e_x \vec{E_x} + e_y \vec{E_y} + e_z \vec{E_z} + \left(\begin{matrix}{c_x\\c_y\\c_z}\end{matrix}\right)$

or simply

$ \vec{w} = (\vec{E_x}  \vec{E_y}  \vec{E_z})\vec{e} + \vec{c} $

So all we need to do is to express $ (e_x, e_y, e_z)^T $ in terms of $ (w_x, w_y, w_z)^T $ in the equation above. Note that the transformation is affine, so we could just form the 4 x 4 matrix and invert it. But there is an easier way.
Since $ \vec{E_x} $, $ \vec{E_y} $, $ \vec{E_z} $ is an orthonormal frame, we knew from linear algebra that the matrix is orthonormal and its inverse is simply its transpose, so we have:

$\begin{eqnarray*} \vec{w} & = & (\vec{E_x} \vec{E_y} \vec{E_z})\vec{e} + \vec{c} \\ \vec{w} - \vec{c} & = & (\vec{E_x} \vec{E_y} \vec{E_z})\vec{e} \\ \vec{e} & = & \left(\begin{matrix}{\vec{E_x} \\ \vec{E_y} \\ \vec{E_z}}\end{matrix}\right)(\vec{w} - \vec{c}) \end{eqnarray*}$

Which is yet another affine transformation that we can effectively code. Since the projection matrix doesn’t change much, it make sense to simply compute the matrix once and cache it for computing projections.

Since at the end of the day the screen is 2D, so what we will do is to simply drop the z-coordinate. 

No comments :

Post a Comment