Visibility
We are concerned with visibility for visual rendering: we want the closest objects to occlude far objects. We also want object outside the view volume to be hidden.
We will use OpenGL to draw the closest objects to our camera viewpoint. OpenGL uses a Z-buffer to determine which object is 'in front'.
Z-buffer
Raster images are images on grids. This means that they have samples for each grid point (pixels). So, we only need visibility results at pixels.
Z-buffering solves visibility only for discrete samples.
- Create a buffer to store distances (or depths)
- Set the buffer depth values to the far plane distance
- Process polygons to fragments
- For each fragment
- Check if fragment depth less than z-buffer depth
- Update depth value, save fragment color
Z-buffering is simple and doesn't need the objects to be in any special order. It also allows the depth values to be saved for later. However, it can have depth precision issues and cannot handle transparency very well.
Using the Z-buffer
OpenGL will automatically provide a Z-buffer. The user does not need to manage the buffer unless they have a special use case that treats the depth values in an unusual way. The default depth buffer (z-buffer) is created when the OpenGL context is created. Depth precision is set when creating the OpenGL context. Our default context uses floats to record depth.
Some OpenGL Z-buffer commands:
-
glEnable(GL_DEPTH_TEST)
: Turn on Z-buffer checks
This should be turned on when depth sorting is needed. Often, this is done at the start of the program. -
glClear(GL_DEPTH_BUFFER_BIT)
: Clear the depth buffer
This needs to be done every frame, otherwise the Z-buffer becomes full of old depth values and cannot properly determine which objects are 'in front'. On clear, the buffer is set to the maximum depth values.