More Visible Surface Determination Algorithms
Binary Space Partitioning
This method uses a binary tree to partition a set of polygons.
The tree can be used to display the polygons in back-to-front order, from
any viewpoint.
An example of viewpoint-independent preprocessing.
Constructing the tree. The following algorithm creates a BSP tree
from a set of polygons. (Assume that we are given a method makeTree
which constructs a binary tree, given a root data item and left and right
subtrees.)
BSPTree constructBSPTree(PolygonSet S)
{
PolygonSet Sin,Sout;
if S is empty, return an empty tree;
Choose a polygon P from S;
Let Sin and Sout be empty polygon sets;
for each polygon Q in S - {P} {
if Q is on the inside of the
plane containing P
insert
Q in Sin;
else if Q is on the outside of
the plane containing P
insert
Q in Sout;
else
split
Q into two polygons Qin (on the inside of P's plane) and Qout (on the outside
of P's plane);
insert
Qin in Sin;
insert
Qout in Sout;
}
return makeTree(P,constructBSPTree(Sin),constructBSPTree(Sout));
}
Now, the tree can be traversed to produce a back-to-front ordering:
void traverse(BSPTree t,Point viewer)
{
if t is not empty {
P = t.data; // P is the
polygon in the root node of the tree
if(viewer is on the inside of
P's plane){
traverse(t.right);
display
P;
traverse(t.left);
}
else {
traverse(t.left);
display
P;
traverse(t.right);
}
}
}
- Better to limit the number of required splits (How?)
- Tree is independent of viewpoint (in contrast to depth-sort method)
- If, for any polygon in the algorithm, the view volume is completely
on one side or the other of the polygon's plane, the other side need not be
traversed at all.
Scan Line Algorithms
- Image-precision
- A modified version of scan-line algorithms for simple polygons in
2-D.
- We deal with not just one polygon but a set of polygons.
Data structures:
Edge table (ET)
- One entry for each nonhorizontal edge of every polygon projected onto
the view plane.
- Sorted into buckets based on the smaller y coordinate (ymin).
- Within each bucket, ordered by increasing x coordinate of the end
with the smaller y coordinate (xmin).
- Each ET entry contains:
- the x coordinate of the end with the smaller y coordinate
- the y coordinate of the edge’s other end (ymax)
- the x increment, Dx, used in stepping
from one scan line to the next (Dx is the inverse
slope of the edge).
- the polygon identification number, indicating the polygon to which
the edge belongs.
Polygon table (PT). For each polygon, it contains:
- The coefficients of the plane equation (Ax + By + Cz + D = 0).
- Shading or color information for the polygon.
- An in-out boolean flag, initialized to false and used in scan-line
processing.
Active-edge table (AET).
- Contains one entry for each edge intersected by the current scan line.
- Kept in order of increasing x. The edges are processed from
left to right. The in-out flag true if the scan is now inside the polygon.
- For each span between two x values in the AET,
if only one polygon is "inside", use its color to color the span;
otherwise, compute the z value corresponding to the current x- and y-values
for each polygon,
using the plane equation, then
color the span with the color of the polygon with the largest z value;
- To use this algorithm properly for penetrating polygons, divide one
of the polygons along the line of intersection.
- Alternatively, the algorithm can be modified to find the point of
penetration on a scan line as the scan line processed.
Area Subdivision Algorithms
Basic idea: Repeatedly divide viewing area into regions. Continue
until each region contains the projection of only a single visible surface
or none at all, or has been reduced to a single pixel.
Warnock’s Algorithm
- Use equal area (quadtree-like) subdivisions
- At each stage in the recursive-subdivision process, the projection
of each polygon has 1 of 4 relationships to the area of interest (surrounding,
intersection, contained, or disjoint polygons).
- In four cases, a decision about an area can be made easily, so the
area does not need to be divided further to be conquered.
- All the polygons are outside the area. Color with the background
color.
- There is only one overlapping or inside polygon. Scan-convert
the polygon.
- There is only one surrounding polygon. Fill with the color
of the surrounding polygon.
- More than one polygon is intersecting, contained in, or surrounding
the area, but one is a surrounding polygon that is in front of all the other
polygons. Fill with the color of the surrounding polygon.
- If none of these cases holds, subdivide the area and continue by
applying the above tests to each subdivision.
Problem: The algorithm needs to use image-precision operations to
terminate because it can clip a polygon only againgst a rectangular area.
the Weiler-Atherton Algorithm
- Uses polygonal subdivisions
- Subdivides the screen area along polygon boundaries rather than along
rectangle boundaries.
The algorithm in pseudocode:
- Order polygons by z-value; // Use this as a starting point
- Let P = the polygon at the front of the list;
- Clip every other polygon to P, retaining both the inside parts and
outside parts. Form two lists: the inside parts and the outside
parts;
- Discard the inside parts which are behind P;
- If the inside list consists only of P, draw P; otherwise, apply the
algorithm recursively to the inside list;
- Apply the algorithm recursively to the outside list;
Visible Surface Ray Tracing
- Ray tracing determines the visibility of surfaces by tracing imaginary
rays of light from the viewer’s eye to the objects in the scene.
- A center of projection (the viewer’s eye) and a window on an arbitrary
view plane are selected. The window may be thought of as being divided into
a regular grid whose elements correspond to pixels at the desired resolution.
- For each pixel in the window, an eye ray is fired from the center
of projection through the pixel’s center into the scene.
- Computing the intersections of the ray with the objects is at the
heart of any ray tracer. It's easy for planes, spheres, more difficult
for other objects.
- We must also determine the surface normal at the point of intersection
in order to shade the surface
Simple ray tracing algorithm:
for (each scan line in image) {
for (each pixel in scan line ) {
determine ray from eye through
the center of the pixel;
for(each object in scene) {
determine
the intersection between the ray and the object;
if(object
is intersected and is closest considered thus far)
record intersection point and object id.
}
determine the surface normal
at the closest intersection point;
apply the illumination model
to the intersection point, and use the result to color the pixel;
}
}
Problem: The number of intersections to be computed is k * M, where
k is the number of objects in the scene and M is the number of pixels.
For a scene of 100 polygons displayed on a 1024x1024 viewing window, this
is 100 million intersections.
Some techniques for improving efficiency:
- Optimize intersection calculations.
- Precompute parts of the intersection formula which are ray-independent
or object-independent.
- Apply coordinate transformation to simplify calculations.
- Intersect with bounding volume first (for complex objects)
- Organize bounding volumes in hierarchies.
- Create a super-bounding volume which encloses a set of bounding volumes.
- Continue until a tree structure is created.
- To find a given ray's closest intersection with an object, traverse
the tree, beginning with the root.
- If a ray does not intersect a parent bounding volume, it is not necessary
to consider any of its children.
- Spatial partioning.
- Conceptually similar to BSP tree -- construct a partitioning of space,
top-down.
- Start with a bounding box for the entire scene.
- Recursively split the box into subboxes, keeping a list of the objects
which are completely or partially contained in each.
- When processing a ray, it is necessary to find the intersections
only of the objects contained in partitions intersected by the ray.
Antialiasing can be done by casting (adaptively) several rays per pixel.