Initial conversion to markdown
This commit is contained in:
parent
a96a114403
commit
5e10794a24
362 changed files with 67353 additions and 0 deletions
130
66-03.md
Normal file
130
66-03.md
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
------------------------ --------------------------------- --------------------
|
||||
[Previous](66-02.html) [Table of Contents](index.html) [Next](66-04.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
For each scan line, a z-sorted active polygon list (APL) is maintained.
|
||||
The x-sorted AEL is stepped through in order. As each new edge is
|
||||
encountered (that is, as each polygon starts or ends as we move left to
|
||||
right), the associated polygon is activated and sorted into the APL, as
|
||||
shown in Figure 66.3, or deactivated and removed from the APL, as shown
|
||||
in Figure 66.4, for a leading or trailing edge, respectively. If the
|
||||
nearest polygon has changed (that is, if the new polygon is nearest, or
|
||||
if the nearest polygon just ended), a span is emitted for the polygon
|
||||
that just stopped being the nearest, starting at the point where the
|
||||
polygon first because nearest and ending at the x coordinate of the
|
||||
current edge, and the current x coordinate is recorded in the polygon
|
||||
that is now the nearest. This saved coordinate later serves as the start
|
||||
of the span emitted when the new nearest polygon ceases to be in front.
|
||||
|
||||
Don’t worry if you didn’t follow all of that; the above is just a quick
|
||||
overview of edge-sorting to help make the rest of this chapter a little
|
||||
clearer. My thorough discussion of the topic will be in Chapter 67.
|
||||
|
||||
The spans that are generated with edge-sorting are exactly the same
|
||||
spans that ultimately emerge from span-sorting; the difference lies in
|
||||
the intermediate data structures that are used to sort the spans in the
|
||||
scene. With edge-sorting, the spans are kept implicit in the edges until
|
||||
the final set of visible spans is generated, so the sorting, clipping,
|
||||
and span emission is done as each edge adds or removes a polygon, based
|
||||
on the span state implied by the edge and the set of active polygons.
|
||||
With span-sorting, spans are immediately made explicit when each polygon
|
||||
is rasterized, and those intermediate spans are then sorted and clipped
|
||||
against other the spans on the scan line to generate the final spans, so
|
||||
the states of the spans are explicit at all times, and all work is done
|
||||
directly with spans.
|
||||
|
||||
Both span-sorting and edge-sorting work well, and both have been
|
||||
employed successfully in commercial projects. We’ve chosen to use
|
||||
edge-sorting in Quake partly because it seems inherently more efficient,
|
||||
with excellent horizontal coherence that makes for minimal time spent
|
||||
sorting, in contrast with the potentially costly sorting into linked
|
||||
lists that span-sorting can involve. A more important reason, though, is
|
||||
that with edge-sorting we’re able to share edges between adjacent
|
||||
polygons, and that cuts the work involved in sorting, clipping, and
|
||||
rasterizing edges nearly in half, while also shrinking the world
|
||||
database quite a bit due to the sharing.
|
||||
|
||||
\
|
||||
**Figure 66.3** *Activating a polygon when a leading edge is
|
||||
encountered in the AEL.*
|
||||
|
||||
One final advantage of edge-sorting is that it makes no distinction
|
||||
between convex and concave polygons. That’s not an important
|
||||
consideration for most graphics engines, but in Quake, edge clipping,
|
||||
transformation, projection, and sorting have become a major bottleneck,
|
||||
so we’re doing everything we can to get the polygon and edge counts
|
||||
down, and concave polygons help a lot in that regard. While it’s
|
||||
possible to handle concave polygons with span-sorting, that can involve
|
||||
significant performance penalties.
|
||||
|
||||
\
|
||||
**Figure 66.4** *Deactivating a polygon when a trailing edge is
|
||||
encountered in the AEL.*
|
||||
|
||||
Nonetheless, there’s no cut-and-dried answer as to which approach is
|
||||
better. In the end, span-sorting and edge-sorting amount to the same
|
||||
functionality, and the choice between them is a matter of whatever you
|
||||
feel most comfortable with. In Chapter 67, I’ll go into considerable
|
||||
detail about edge-sorting, complete with a full implementation. I’m
|
||||
going the spend the rest of this chapter laying the foundation for
|
||||
Chapter 67 by discussing sorting keys and 1/z calculation. In the
|
||||
process, I’m going to have to make a few forward references to aspects
|
||||
of edge-sorting that I haven’t yet covered in detail; my apologies, but
|
||||
it’s unavoidable, and all should become clear by the end of Chapter 67.
|
||||
|
||||
### Edge-Sorting Keys {#Heading9}
|
||||
|
||||
Now that we know we’re going to sort edges, using them to emit spans for
|
||||
the polygons nearest the viewer, the question becomes: How can we tell
|
||||
which polygons are nearest? Ideally, we’d just store a sorting key in
|
||||
each polygon, and whenever a new edge came along, we’d compare its
|
||||
surface’s key to the keys of other currently active polygons, and could
|
||||
easily tell which polygon was nearest.
|
||||
|
||||
That sounds too good to be true, but it is possible. If, for example,
|
||||
your world database is stored as a BSP tree, with all polygons clipped
|
||||
into the BSP leaves, then BSP walk order is a valid drawing order. So,
|
||||
for example, if you walk the BSP back-to-front, assigning each polygon
|
||||
an incrementally higher key as you reach it, polygons with higher keys
|
||||
are guaranteed to be in front of polygons with lower keys. This is the
|
||||
approach Quake used for a while, although a different approach is now
|
||||
being used, for reasons I’ll explain shortly.
|
||||
|
||||
If you don’t happen to have a BSP or similar data structure handy, or if
|
||||
you have lots of moving polygons (BSPs don’t handle moving polygons very
|
||||
efficiently), another way to accomplish your objectives would be to sort
|
||||
all the polygons against one another before drawing the scene, assigning
|
||||
appropriate keys based on their spatial relationships in viewspace.
|
||||
Unfortunately, this is generally an extremely slow task, because every
|
||||
polygon must be compared to every other polygon. There are techniques to
|
||||
improve the performance of polygon sorts, but I don’t know of anyone
|
||||
who’s doing general polygon sorts of complex scenes in realtime on a PC.
|
||||
|
||||
An alternative is to sort by z distance from the viewer in screenspace,
|
||||
an approach that dovetails nicely with the excellent spatial coherence
|
||||
of edge-sorting. As each new edge is encountered on a scan line, the
|
||||
corresponding polygon’s z distance can be calculated and compared to the
|
||||
other polygons’ distances, and the polygon can be sorted into the APL
|
||||
accordingly.
|
||||
|
||||
Getting z distances can be tricky, however. Remember that we need to be
|
||||
able to calculate z at any arbitrary point on a polygon, because an edge
|
||||
may occur and cause its polygon to be sorted into the APL at any point
|
||||
on the screen. We could calculate z directly from the screen x and y
|
||||
coordinates and the polygon’s plane equation, but unfortunately this
|
||||
can’t be done very quickly, because the z for a plane doesn’t vary
|
||||
linearly in screenspace; however, 1/z *does* vary linearly, so we’ll use
|
||||
that instead. (See Chris Hecker’s 1995 series of columns on texture
|
||||
mapping in *Game Developer* magazine for a discussion of screenspace
|
||||
linearity and gradients for 1/z.) Another advantage of using 1/z is that
|
||||
its resolution increases with decreasing distance, meaning that by using
|
||||
1/z, we’ll have better depth resolution for nearby features, where it
|
||||
matters most.
|
||||
|
||||
------------------------ --------------------------------- --------------------
|
||||
[Previous](66-02.html) [Table of Contents](index.html) [Next](66-04.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
* * * * *
|
||||
|
||||
Graphics Programming Black Book © 2001 Michael Abrash
|
||||
Loading…
Reference in a new issue