Visibility is determining what is in the view volume. Visibility is needed for many algorithms: propagation (light, radio, sound), bullet tracing, visual rendering, heat transfer, etc.
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 have been using visibility when rendering our scenes thus far: we have used OpenGL to draw the closest objects to our camera viewpoint. We will consider a few algorithms:
- Painter's algorithm
- Z-buffer (what we use)
In the painter's algorithm, sort the objects by distance, paint the farthest and remove from the list, continue till all objects are painted. This algorithm cannot handle objects that overlap!
This algorithm uses clipping, or cutting object shapes against other shapes. This results in new shapes, split by the clipping shape.
- Sort objects by distance, find closest
- Clip all objects against closest (in 2D)
- Results in 2 lists: inside and outside
- 3D clip objects against closest
- Objects inside and behind are discarded
- Recurs into rest of inside list, result list is visible
- Apply algorithm to outside list...
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 sorted. It also allows the depth values to be saved for later. However, it can have depth precision issues and cannot handle transparency very well.
Some OpenGL Z-buffer commands:
Turn on Z-buffer checks:
Clear the depth buffer:
Depth precision is set when creating the OpenGL context