Visibility

[Hill: Chapter 13. Foley & van Dam: p. 649-651]
Visibility algorithms are needed to determine which objects in the scene are obscured by other objects. They are typically classified into two groups:

The Z-buffer

[Hill: 436-439. Foley & van Dam: p. 668-672]
The z-buffer records depth information with each pixel:

Summary of Z-buffer algorithm:
for all i,j {
  Depth[i,j] = MAX_DEPTH
  Image[i,j] = BACKGROUND_COLOUR
}
for all polygons P {              
  for all pixels in P {           
    if (Z_pixel < Depth[i,j]) {   
      Image[i,j] = C_pixel
      Depth[i,j] = Z_pixel
    }
  }
}

Characteristics of the z-buffer algorithm:

When does the z-buffer perform poorly?

Scan-converting Z

Scan conversion proceeds much like the 2D case, only now appropriate Z-values must be generated. In order to determine z = f(x,y), we begin with the plane equation of the polygon in device coordinates as given by

   0 = A x + B y + C z + D,

We can solve for z as

   z = ( - A x - B y - D ) /C.

The value of z at the adjacent pixel (x+1, y) is

   z' = ( - A (x+1) - B y - D ) /C.

or

   z' = z - A/C.

Generating z-values when travelling across a scanline is thus simple once the z-value is known at the left edge of the polygon. This can also be calculated in an incremental fashion, knowing that

   x' = x + 1/m.

The new left edge of the polygon is (x+1/m, y+1) and we can determine the difference in z as being

   z' = z - (A/m + B )/C.

Bilinear interpolation

The A-Buffer

[Not covered in Hill]

The data for each surface includes:



BSP trees

[Hill: 707-711. Foley & van Dam: p. 675-680]

  • binary space partition
  • object space, produces back-to-front ordering
  • preprocess scene the scene once to build BSP tree
  • traversal of BSP tree is view dependent

 

BSPtree *BSPmaketree(polygon list) {
   choose a polygon as the tree root
   for all other polygons
      if polygon is in front, add to front list
      if polygon is behind, add to behind list
      else split polygon and add one part to each list
   BSPtree = BSPcombinetree(BSPmaketree(front list),
                            root,
                            BSPmaketree(behind list) )
}

  

DrawTree(BSPtree) {
   if (eye is in front of root) {
	DrawTree(BSPtree->behind)
	DrawPoly(BSPtree->root)
	DrawPoly(BSPtree->front)
   } else {
	DrawTree(BSPtree->front)
	DrawPoly(BSPtree->root)
	DrawTree(BSPtree->behind)
   }
}




Depth-sorting Algorithms

[Hill: 706,711-713. Foley & van Dam: p. 672-675]
Several object-space algorithms achieve a front-to-back ordering in other ways. These depth-sort algorithms have the following basic steps:

  • sort polygons by z
  • resolve ambiguities where z-extents overlap
  • scan-convert polygons in back-to-front order

Ambiguities can be resolved in several ways.

  • bounding rectangles do not overlap in xy-plane
  • A is completely behind C
  • C is completely in front of A
  • projections on xy-plane do not overlap

If these fail, exchange the order of the surfaces and repeat. If this still fails, the polygons can be intersected to split one of the polygons if necessary. In the worst case, the algorithm can generate O(n^2) new polygons.

Scan-line algorithms

[Hill: 713-716. Foley & van Dam: p. 680-684]

  • modify scan-conversion to handle multiple polygons
  • priority according to Z
  • resolve visibility one scanline at a time
  • less memory

for each scanline (row) in image
  for each pixel in scanline
    determine closest object
    calculate pixel colour, draw pixel
  end
end  


Ray Tracing

[Hill: Chapter 14. Foley & van Dam: p. 701-712]

for each pixel on screen
  determine ray from eye through pixel
  find closest intersection of ray with an object
  cast off reflected and refracted ray, recursively
  calculate pixel colour, draw pixel
end
  • rays cast through image pixels
  • solves visibility, some global illumination
  • requires efficient intersection tests
    O(mnN): m x n pixels, N objects