119 lines
6.5 KiB
Markdown
119 lines
6.5 KiB
Markdown
Chapter 42\
|
||
Wu'ed in Haste; Fried, Stewed at Leisure {#Heading1}
|
||
-----------------------------------------
|
||
|
||
### Fast Antialiased Lines Using Wu's Algorithm {#Heading2}
|
||
|
||
The thought first popped into my head as I unenthusiastically picked
|
||
through the salad bar at a local "family" restaurant, trying to decide
|
||
whether the meatballs, the fried clams, or the lasagna was likely to
|
||
shorten my life the least. I decided on the chicken in mystery sauce.
|
||
|
||
The thought recurred when my daughter asked, "Dad, is that fried
|
||
chicken?"
|
||
|
||
"I don't think so," I said. "I think it's stewed chicken."
|
||
|
||
"It looks like fried chicken."
|
||
|
||
"Maybe it's fried, stewed chicken," my wife volunteered hopefully. I
|
||
took a bite. It was, indeed, fried, stewed chicken. I can now,
|
||
unhesitatingly and without reservation, recommend that you avoid fried,
|
||
stewed chicken at all costs.
|
||
|
||
The thought I had was as follows: *This is not good food*. Not a
|
||
profound thought, but it raises an interesting question: Why was I
|
||
eating in this restaurant? The answer, to borrow a phrase from E.F.
|
||
Schumacher, is *appropriate technology*. For a family on a budget, with
|
||
a small child, tired of staring at each other over the kitchen table,
|
||
this was a perfect place to eat. It was cheap, it had greasy food and
|
||
ice cream, no one cared if children dropped things or talked loudly or
|
||
walked around, and, most important of all, it wasn't home. So what if
|
||
the food was lousy? Good food was a luxury, a bonus; everything on the
|
||
above list was necessary. A family restaurant was the appropriate
|
||
dining-out technology, given the parameters within which we had to work.
|
||
|
||
When I read through SIGGRAPH proceedings and other state-of-the-art
|
||
computer-graphics material, all too often I feel like I'm dining at a
|
||
four-star restaurant with two-year-old triplets and an empty wallet.
|
||
We're talking incredibly inappropriate technology for PC graphics here.
|
||
Sure, I say to myself as I read about an antialiasing technique, that
|
||
sounds wonderful—if I had 24-bpp color, and dedicated hardware to do the
|
||
processing, and all day to wait to generate one image. Yes, I think,
|
||
that is a good way to do hidden surface removal—in a system with
|
||
hardware z-buffering. Most of the stuff in the journal *Computer
|
||
Graphics* is riveting, but, alas, pretty much useless on PCs. When an
|
||
x86 has to do all the work, speed becomes the overriding parameter,
|
||
especially for real-time graphics.
|
||
|
||
Literature that's applicable to fast PC graphics is hard enough to find,
|
||
but what we'd really like is above-average image quality combined with
|
||
terrific speed, and there's almost no literature of that sort around.
|
||
There is some, however, and you folks are right on top of it. For
|
||
example, alert reader Michael Chaplin, of San Diego, wrote to suggest
|
||
that I might enjoy the line-antialiasing algorithm presented in Xiaolin
|
||
Wu's article, "An Efficient Antialiasing Technique," in the July 1991
|
||
issue of *Computer Graphics*. Michael was dead-on right. This is a great
|
||
algorithm, combining excellent antialiased line quality with speed
|
||
that's close to that of non-antialiased Bresenham's line drawing. This
|
||
is the sort of algorithm that makes you want to go out and write a
|
||
wire-frame animation program, just so you can see how good those smooth
|
||
lines look in motion. Wu antialiasing is a wonderful example of what can
|
||
be accomplished on inexpensive, mass-market hardware with the proper
|
||
programming perspective. In short, it's a splendid example of
|
||
appropriate technology for PCs.
|
||
|
||
### Wu Antialiasing {#Heading3}
|
||
|
||
Antialiasing, as we've been discussing for the past few chapters, is the
|
||
process of smoothing lines and edges so that they appear less jagged.
|
||
Antialiasing is partly an aesthetic issue, because it makes images more
|
||
attractive. It's also partly an accuracy issue, because it makes it
|
||
possible to position and draw images with effectively more precision
|
||
than the resolution of the display. Finally, it's partly a flat-out
|
||
necessity, to avoid the horrible, crawling, jagged edges of temporal
|
||
aliasing when performing animation.
|
||
|
||
The basic premise of Wu antialiasing is almost ridiculously simple: As
|
||
the algorithm steps one pixel unit at a time along the major (longer)
|
||
axis of a line, it draws the two pixels bracketing the line along the
|
||
minor axis at each point. Each of the two bracketing pixels is drawn
|
||
with a weighted fraction of the full intensity of the drawing color,
|
||
with the weighting for each pixel equal to one minus the pixel's
|
||
distance along the minor axis from the ideal line. Yes, it's a mouthful,
|
||
but Figure 42.1 illustrates the concept.
|
||
|
||
The intensities of the two pixels that bracket the line are selected so
|
||
that they always sum to exactly 1; that is, to the intensity of one
|
||
fully illuminated pixel of the drawing color. The presence of aggregate
|
||
full-pixel intensity means that at each step, the line has the same
|
||
brightness it would have if a single pixel were drawn at precisely the
|
||
correct location. Moreover, thanks to the distribution of the intensity
|
||
weighting, that brightness is centered at the ideal line. Not
|
||
coincidentally, a line drawn with pixel pairs of aggregate single-pixel
|
||
intensity, centered on the ideal line, is perceived by the eye not as a
|
||
jagged collection of pixel pairs, but as a smooth line centered on the
|
||
ideal line. Thus, by weighting the bracketing pixels properly at each
|
||
step, we can readily produce what looks like a smooth line at precisely
|
||
the right location, rather than the jagged pattern of line segments that
|
||
non-antialiased line-drawing algorithms such as Bresenham's (see
|
||
Chapters 35, 36, and 37) trace out.
|
||
|
||
\
|
||
**Figure 42.1** *The basic concept of Wu antialiasing.*
|
||
|
||
You might expect that the implementation of Wu antialiasing would fall
|
||
into two distinct areas: tracing out the line (that is, finding the
|
||
appropriate pixel pairs to draw) and calculating the appropriate
|
||
weightings for each pixel pair. Not so, however. The weighting
|
||
calculations involve only a few shifts, XORs, and adds; for all
|
||
practical purposes, tracing and weighting are rolled into one step—and a
|
||
very fast step it is. How fast is it? On a 33-MHz 486 with a fast VGA, a
|
||
good but not maxed-out assembly implementation of Wu antialiasing draws
|
||
a more than respectable 5,000 150-pixel-long vectors per second. That's
|
||
especially impressive considering that about 1,500,000 actual pixels are
|
||
drawn per second, meaning that Wu antialiasing is drawing at around 50
|
||
percent of the maximum memory bandwidth—half the fastest theoretically
|
||
possible drawing speed—of an AT-bus VGA. In short, Wu antialiasing is
|
||
about as fast an antialiased line approach as you could ever hope to
|
||
find for the VGA.
|