ENDS 489 Course Notes - Fall 2000

Section 7-1

Hidden Surface Removal


(Based on material from Fundamentals of Three-Dimensional Computer Graphics, A. Watt,  Addison_Wesley,1989)
(last update 11/1/00)


 


The major hidden surface removal algorithms are described in most computer graphics textbooks and are classified in a highly relevant paper by Sutherland et al. (1974).  In this paper algorithms are characterized as to whether they operate primarily in object space or image (screen) space and the different uses of 'coherence' that the algorithms employ.  Coherence is a term used to describe the process where geometrical units, such as areas or scan line segments, instead of single points are operated on by the hidden surface removal algorithm.
 
There appear to be two popular approaches to hidden surface removal.  These are scan line based systems and Z-buffer based systems. Other approaches to hidden surface removal such as area subdivision (Warnock, 1969), or depth list schemes (Newell et al., 1972) are not particularly popular now or are reserved for special-purpose applications such as flight simulation.
 
The Z-buffer algorithm

We start by considering the easier of the two approaches - the Z-buffer renderer.  The Z-buffer algorithm, developed by Catmull(1975), is as ubiquitous in computer graphics as the Phong reflection model and interpolator, and the combination of these represents the most popular rendering option.  Using Sutherland's classification scheme (Sutherland et al., 1974) it is an algorithm that operates in image or screen space.
 
Pixels in the interior of a polygon are shaded, using an incremental shading scheme, and their depth is evaluated by interpolatio from the z values of the polygon vertices after the viewing transformation has been applied.  Thus we can imagine a three-dimensional screen space, where the (x, y) values are pixel coordinates and the z value is the interpolated viewing space depth.
 
The Z-buffer algorithm is equivalent, for each point (X, y), to a search through the associated z values of each interior polygon point to find that point with the minimum z value.  This search is conveniently implemented by using a Z-buffer that holds for a current point (x, y) the smallest z value so far encountered.  During the processing of a polygon we either write the intensity of a point (x, y) into the frame buffer or not, depending on whether the depth z, of the current point is less than the depth so far encountered as recorded in the Z-buffer.
 
The overwhelming advantage of the Z-buffer algorithm is its simplicity of implementation.  Its main disadvantage is the amount of  memory required for the Z-buffer.  The size of the Z-buffer depends on the accuracy to which the depth value of each point (x, y) is to be stored, which is a function of scene complexity. 20-32 bits are usually deemed sufficient and the scene has to be scaled to this fixed range of z so that accuracy within the scene is maximized.  Note that for frame buffers smaller than 24 bits per pixel, say, the Z-buffer will in fact be larger than the frame buffer.  In the past Z-buffers have tended to be part of the main memory of the host processor, but now graphics terminals are available with dedicated Z-buffers and this represents the best solution.
 
The Z-buffer imposes no constraints on database organization (other than those required by the shading interpolation) and in its simplest form can be driven on a polygon-by-polygon basis, with polygons being presented in any convenient order.
 
In principle, for each polygon we compute:

    (1)   the (x, y) value of the interior pixels,

    (2)   the z depth for each point (x, y), and

    (3)   the intensity I for each point (x, y)
 
Thus  we have three concurrent bilinear interpolation processes and a triple nested loop. The z values and intensities I are available at each vertex and the interpolation scheme for z and I is distributed between the two inner loops of the algorithm.
 
An extended version of the by-polygon algorithm with Z-buffer hidden surface removal is as follows:

For (all x, y) do
   Z-Buffer [x, y] = maximum-depth

for (each polygon) do
   {construct an edge list from the polygon edges
   (that is, for each edge, calculate the values of x, z and I for each
   scan line by interpolation and store them in the edge list)}
   for y = ymin to ymax do

for {each segment in EdgeList[y]) do
   {get Xleft, Xright, Zleft, Zright, Ileft, Iright)

   for x = Xleft to Xright do
      {linearly interpolate z and I between
      Zleft, Zright and Ileft, Iright respectively}
      if z < Z-Buffer[x, y] then
         {Z-Buffer[x, y]  = z
          frame-buffer[x, y] = I}
 
The structure of the algorithm reveals the major inefficiency of the method in that shading calculations are performed on hidden pixels which are then either ignored or subsequently overwritten.  The extent of this duplication will be a function of the overall order in which the polygons in the scene are examined.  If preprocessing is possible, so that those polygons nearest the view point are processed first, considerable savings can be made.
 
If Phong interpolation is used then the final reflection model calculations, which are a function of the interpolated normal, should also appear within the innermost loop; that is, interpolate N rather than I, and replace the last line with:

        frame-buffer[x, y]  = ShadingFunction (N)

Scan line Z-buffer

There is a variation of the Z-buffer algorithm for use with scan line based renderers, known (not surprisingly) as a scan line Z-buffer.  This is simply a Z-buffer which is only one pixel high, and is used to solve the hidden surface problem for a given scan line.  It is re-initialized for each new scan line.  Its chief advantage lies in the small amount of memory it requires relative to a full-blown Z-buffer; in fact it is very common to see a scan line Z-buffer based program running on systems which do not have sufficient memory to support a full Z-buffer.

Spanning hidden surface removal

A spanning hidden surface removal algorithm attempts, for each scan line, to find 'spans' across which shading can be performed.  The hidden surface removal problem is thus solved by dividing the scan line into lengths over which a single surface is dominant.  This means that shading calculations are performed only once per pixel, removing the basic inefficiency inherent in the Z-buffer method.  Set against this is the problem that spans do not necessarily correspond to polygon segments, making it harder to perform incremental shading calculations (the start values must be calculated at an arbitrary point along a polygon segment, rather than being set to the values at the left-hand edge).  The other major drawback is in the increase in complexity of the algorithm itself, as will be seen.
 
It is generally claimed that spanning algorithms are more efficient than Z-buffer based algorithms, except for very large numbers of polygons (Foley and Van Dam, 1982; Sutherland et al., 1974).  However, since extremely complex scenes are now becoming the norm, it is becoming clear that, overall, the Z buffer is more efficient, unless a very complex shading function is being used.

A spanning scan line algorithm
 
The basic idea, as has been mentioned, is that, rather than solving the hidden surface problem on a pixel-by-pixel basis using incremental z calculation, the spanning scan line algorithm uses spans along the scan line over which there is no depth conflict.  The hidden surface removal process uses coherence in x and deals in units of many pixels.  The processing implication is that a sort in x is required for each scan line and the spans have to be evaluated.
 
The easiest way to see how a scan line algorithm works is to consider the situation in three-dimensional screen space (xs,ys,zs). A  scan line algorithm effectively moves a scan line plane, that is a plane parallel to the (x,y,z,) plane, down the y, axis.  This plane intersects objects in the scene and reduces the hidden surface problem to two-dimensional space (xs,zs).  Here the intersections of the scan line plane with object polygons become lines (see the figure below).

                                                                       
               A scan line plane is moved down-through thescene producing line segments and spans.

Note that the precise orientation of this plane, with respect to the objects in world coordinates, depends on the transformations used.  If a perspective transformation is employed then the objects would be distorted in three-dimensional screen space.  These line segments are then compared to solve the hidden surface problem by considering 'spans'.  A span is that part of a line segment that is contained between the edge intersections of all active polygons.  A span can be considered a coherence unit within the extent of which the hidden surface removal problem is 'constant' and can be solved by depth comparisons at either end of the span.  Note that a more complicated approach has to be taken if penetrating polygons are allowed.
 
It can be seen from this geometric overview that the first stage in a spanning scan line algorithm is to sort the polygon edges by y, vertex values.  This results in an active edge list which is updated as the scan line moves down the y, axis.  If penetrating polygons are not allowed, then each edge intersection with the current scan line specifies a point on the scan line where 'something is changing', and so these collectively define all the span boundary points.
 
By going through the active edge list in order, it is possible to generate a set of line segments, each of which represents the intersection of the scan line plane with a polygon.  These are then sorted in order of increasing xs.

 Within a span the hidden surface problem is resolved by
 considering depths along one of the span boundaries.

The innermost loop then processes each span in the current scan line.  Active line segments are clipped against span boundaries and are thus subdivided by these boundaries.  The depth of each subdivided segment is then evaluated at one of the span boundaries and hidden surface removal is effected by searching within a span for the closest subdivided segment.  This process is shown in the figure above.

In pseudo-code the algorithm is:

for {each polygon}
   {Generate and bucket sort in ys the polygon edge information.)

for {each scanline}
   for {each active polygon)
     {Determine the segment or intersection of the scan plane and polygon.
      Sort these active segments in xs.
     Update the rate of change per scan line of the shading parameters. }

{Generate the span boundaries.}
   for {each span}
      {Clip active segments to span boundaries.
       Evaluate the depth for all clipped segments at one of the span boundaries.
       Solve the hidden surface problem for the span by finding the segment with minimum zs.
       Shade the visible clipped line segment.
       Update the shading parameters for all other line segments by the rate of change per pixel times the span width. }

Note that integrating shading information is far more cumbersome than with the Z-buffer.  Records of values at the end of clipped line segments have to be kept and updated.  This places another scene complexity overhead (together with the overhead of the absolute number of polygons) on the efficiency and memory requirements of the process.
 
Comparative Points

From an ease of implementation point of view the Z-buffer is best.  It has significant memory requirements, particularly for high resolution frame buffers.  However, it places no upwards limit on the complexity of scenes, an advantage that is now becoming increasingly important.  It renders scenes one object at a time and for each object one polygon at a time. This is both a natural and a convenient order as far as database considerations are concerned.
 
An important restriction it places on the type of object that can be rendered by a Z-buffer is that it cannot deal with transparent objects without costly modification.  A partially transparent polygon may:

 (1)   be completely covered by an opaque nearer polygon, in which case there is no problem, or

 (2)   be the nearest polygon, in which case a list of all polygons behind it must be maintained so that an appropriate combination of the transparent polygon and the next nearest can be computed (the next nearest polygon is not of course known until all polygons are processed).

Compared with scan line algorithms, anti-aliasing solutions, particularly hardware implementations, are more difficult.

Cook et al. (1987) point out that a Z-buffer has an extremely important 'system' advantage.  It provides a 'back door' in that it can combine point samples with point samples from other algorithms that have other capabilities such as radiosity or ray tracing.
 
If memory requirements are too prodigious then a scan line Z- buffer is the next best solution.  Unless a renderer is to work efficiently on simple scenes, it is doubtful whether it is worth contemplating the large increase in complexity that a spanning scan linealgorithm demands.
 
Historically there has been a shift in research away from hidden surface problems to realistic image synthesis.  This has been motivated by the easy availability of high spatial and colour resolution terminals.  All the 'classic' hidden surface removal algorithms were developed prior to the advent of shading complexities and it looks as if the Z-buffer will be the most popular survivor for conventional rendering.