This was the long awaited week where we moved to 3D. Instead of drawing a square, we are now doing a cube and a plane.
To draw a 3D mesh on the screen, we use three transforms (matrices).
- Local to world transform: This matrix transform vertices in object’s local space to world space. Each mesh is defined in the local space, centered at origin. Because we might want to draw the mesh at different positions/rotations in the world, takes a mesh in its local space and places it in the world space with the desired transformation.
- World to view transform: This takes vertices in the world space and transforms them to the camera’s view space. Its like saying, if the camera was at origin looking, where would everything else be. This helps simplify further math because, if we fix the camera to be at origin and looking forward (Z) then it becomes easier to project all the objects onto the camera’s screen in the next step.
- View to screen transform: The last step is to transform everything from the view space to the screen space. This is also known as the projection space. This transformation matrix is used to project the world in the view space onto the screen space (Ha!). For example, a simple orthographic proejction would mean that we just drop the z coordinate and clip everything that lies outside the (1:-1) range on xy axes.
As you can see the box intersects the plane. To do this we use a depth buffer to determine which pixel value needs to be drawn. The depth buffer stores the depth of each pixel in an array and a pixel is drawn if the depth is less than the stored depth for that pixel. In our case, we use less than comparsion and set the buffer to 1 by default. 1 is the highest value that corresponds to the far plane and 0 corresponds to the near plane. The less than comparison means that if a object is nearer, it has a lesser depth and is drawn on top.
I also had to add a third dimension to my mesh, a third value to the position table.
For the camera, I simply have a static translation vector in my Graphics that is updated every frame. This affects the world-to-view transform and the updated transform is used to draw the objects each frame. The camera location is temporary, as I didn’t want to engineer something without knowing what we will be doing with it.
Controls: Arrow keys to move box, WASD to move camera. Esc to quit.