Initial conversion to markdown
This commit is contained in:
parent
a96a114403
commit
5e10794a24
362 changed files with 67353 additions and 0 deletions
138
70-06.md
Normal file
138
70-06.md
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
------------------------ --------------------------------- --------------------
|
||||
[Previous](70-05.html) [Table of Contents](index.html) [Next](70-07.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
#### The Subdivision Rasterizer {#Heading12}
|
||||
|
||||
This rasterizer, which we call the *subdivision rasterizer*, first draws
|
||||
all the vertices in the model. Then it takes each front-facing triangle,
|
||||
and determines if it has a side that’s at least two pixels long. If it
|
||||
does, we split that side into two pieces at the pixel nearest to the
|
||||
middle (using adds and shifts to average the endpoints of that side),
|
||||
draw the vertex at the split point, and process each of the two split
|
||||
triangles recursively, until we get down to triangles that have only
|
||||
one-pixel sides and hence have nothing left to draw. This approach is
|
||||
hideously slow and quite ugly (due to inaccuracies from integer
|
||||
quantization) for 100-pixel triangles—but it’s very fast for, say,
|
||||
five-pixel triangles, and is indistinguishable from more accurate
|
||||
rasterization when a model is 25 or 50 feet away. Better yet, the
|
||||
subdivider is ridiculously simple—a few dozen lines of code, far simpler
|
||||
than the affine rasterizer—and was implemented in an evening,
|
||||
immediately making the drawing of distant models about three times as
|
||||
fast, a very good return for a bit of conceptual work. The affine
|
||||
rasterizer got fairly close to the same performance with further
|
||||
optimization—in the range of 10% to 50% slower—but that took weeks of
|
||||
difficult programming.
|
||||
|
||||
We switch between the two rasterizers based on the model’s distance and
|
||||
average triangle size, and in almost any scene, most models are far
|
||||
enough away so subdivision rasterization is used. There are undoubtedly
|
||||
faster ways yet to rasterize distant models adequately well, but the
|
||||
subdivider was clearly a win, and is a good example of how thinking in a
|
||||
radically different direction can pay off handsomely.
|
||||
|
||||
#### Sprites {#Heading13}
|
||||
|
||||
We had hoped to be able to eliminate sprites completely, making Quake
|
||||
100% 3-D, but sprites—although sometimes very visibly 2-D—were used for
|
||||
a few purposes, most noticeably the cores of explosions. As of CGDC last
|
||||
year, explosions consisted of an exploding spray of particles (discussed
|
||||
below), but there just wasn’t enough visual punch with that
|
||||
representation; adding a series of sprites animating an explosion did
|
||||
the trick. (In hindsight, we probably should have made the explosions
|
||||
polygon models rather than sprites; it would have looked about as good,
|
||||
and the few sprites we used didn’t justify the considerable amount of
|
||||
code and programming time required to support them.) Drawing a sprite is
|
||||
similar to drawing a normal polygon, complete with perspective
|
||||
correction, although of course the inner loop must detect and skip over
|
||||
transparent pixels, and must also perform z-buffering.
|
||||
|
||||
#### Particles {#Heading14}
|
||||
|
||||
The last drawing entity type is particles. Each particle is a
|
||||
solid-colored rectangle, scaled by distance from the viewer and drawn
|
||||
with z-buffering. There can be up to 2,000 particles in a scene, and
|
||||
they are used for rocket trails, explosions, and the like. In one sense,
|
||||
particles are very primitive technology, but they allow effects that
|
||||
would be extremely difficult to do well with the other types of
|
||||
entities, and they work well in tandem with other entities, as, for
|
||||
example, providing a trail of fire behind a polygon-model lava ball that
|
||||
flies into the air, or generating an expanding cloud around a sprite
|
||||
explosion core.
|
||||
|
||||
### How We Spent Our Summer Vacation: After Shipping Quake {#Heading15}
|
||||
|
||||
Since shipping Quake in the summer of 1996, we’ve extended it in several
|
||||
ways: We’ve worked with Rendition to port it to the Verite accelerator
|
||||
chip, we’ve ported it to OpenGL, we’ve ported it to Win32, we’ve done
|
||||
QuakeWorld, and we’ve added features for Quake 2. I’ll discuss each of
|
||||
these briefly.
|
||||
|
||||
#### Verite Quake {#Heading16}
|
||||
|
||||
Verite Quake (VQuake) was the first hardware-accelerated version of
|
||||
Quake. It looks extremely good, due to bilinear texture filtering, which
|
||||
eliminates most pixel aliasing, and because it provides good performance
|
||||
at higher resolutions such as 512x384 and 640x480. Implementing VQuake
|
||||
proved to be an interesting task, for two reasons: The Verite chip’s
|
||||
fill rate was marginal for Quake’s needs, and Verite contains a
|
||||
programmable RISC chip, enabling more sophisticated processing than most
|
||||
3-D accelerators. The need to squeeze as much performance as possible
|
||||
out of Verite ruled out the use of a standard API such as Direct 3D or
|
||||
OpenGL; instead, VQuake uses Rendition’s proprietary API, Speedy3D, with
|
||||
the addition of some special calls and custom Verite code.
|
||||
|
||||
Interestingly, VQuake is very similar to software Quake; in order to
|
||||
allow Verite to handle the high pixel processing loads of high-res,
|
||||
VQuake uses an edge list and builds span lists on the CPU, just as in
|
||||
software Quake, then Verite DMAs the span descriptors to onboard memory
|
||||
and draws them. (This was only possible because Verite is fully
|
||||
programmable; most accelerators wouldn’t be able to support this
|
||||
architecture.) Similarly, the CPU builds lit, tiled surfaces in system
|
||||
RAM, then Verite DMAs them to an onboard surface cache, from which they
|
||||
are texture-mapped. In short, VQuake is very much like normal Quake,
|
||||
except that the drawing of the spans is done by a specialized processor.
|
||||
|
||||
This approach works well, but some of the drawbacks of a surface cache
|
||||
become more noticeable when hardware is involved. First, the DMAing is
|
||||
an extra step that’s not necessary in software, slowing things down.
|
||||
Second, onboard memory is a relatively limited resource (4 MB total),
|
||||
and textures must be 16-bpp (because hardware can only do filtering in
|
||||
RGB modes), thus eating up twice as much memory as the software
|
||||
version’s 8-bpp textures—and memory becomes progressively scarcer at
|
||||
higher resolutions, especially given the need for a z-buffer and two
|
||||
16-bpp pages. (Note that using the edge list helps here, because it
|
||||
filters out spans from polygons that are in the PVS but fully occluded,
|
||||
reducing the number of surfaces that have to be downloaded.) Surface
|
||||
caching in VQuake usually works just fine, but response when coming
|
||||
around corners into complex scenes or when spinning can be more sluggish
|
||||
than in software Quake.
|
||||
|
||||
An alternative to surface caching would have been to do two passes
|
||||
across each span, one tiling the texture, and the other doing an alpha
|
||||
blend using the light map as a texture, to light the texture (two-pass
|
||||
alpha lighting). This approach produces exactly the same results as the
|
||||
surface cache, without requiring downloading and caching of large
|
||||
surfaces, and has the advantage of very level performance. However, this
|
||||
approach requires at least twice the fill rate of the surface cache
|
||||
approach, and Verite didn’t have enough fill rate for that at higher
|
||||
resolutions. It’s also worth noting that two-pass alpha lighting doesn’t
|
||||
have the same potential for procedural texturing that surface caching
|
||||
does. In fact, given MMX and ever-faster CPUs, and the ability of the
|
||||
CPU and the accelerator to process in parallel, it will become
|
||||
increasingly tempting to use the CPU to build surfaces with procedural
|
||||
texturing such as bump mapping, shimmers, and warps; this sort of
|
||||
procedural texturing has the potential to give accelerated games highly
|
||||
distinctive visuals. So the choice between surface caching and two-pass
|
||||
alpha lighting for hardware accelerators depends on a game’s needs, and
|
||||
it seems most likely that the two approaches will be mixed together,
|
||||
with surface caching used for special surfaces, and two-pass alpha
|
||||
lighting used for most drawing.
|
||||
|
||||
------------------------ --------------------------------- --------------------
|
||||
[Previous](70-05.html) [Table of Contents](index.html) [Next](70-07.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
* * * * *
|
||||
|
||||
Graphics Programming Black Book © 2001 Michael Abrash
|
||||
Loading…
Reference in a new issue