abrash-black-book/70-02.md
2013-12-30 20:26:41 +11:00

101 lines
6.1 KiB
Markdown

Getting proper front-to-back drawing order is a little more complicated
with polygons on nodes. As we walk the BSP tree front-to-back, in each
leaf we mark the polygons that are at least partially in that leaf, and
then after we've recursed and processed everything in front of a node,
we then process all the marked polygons on that node, after which we
recurse to process the polygons behind the node. So putting the polygons
on the nodes saves memory and improves performance significantly, but
loses the simple approach of simply recursing the tree and processing
the polygons in each leaf as we come to it, in favor of recursing and
marking in front of a node, processing marked polygons on the node, then
recursing behind the node.
After the BSP is built, the outer surfaces of the level, which no one
can ever see (because levels are sealed spaces), are removed, so the
interior of the level, containing all the empty space through which a
player can move, is completely surrounded by a solid region. This
eliminates a great many irrelevant polygons, and reduces the complexity
of the next step, calculating the potentially visible set.
### The Potentially Visible Set (PVS) {#Heading3}
After the BSP tree is built, the potentially visible set (PVS) for each
leaf is calculated. The PVS for a leaf consists of all the leaves that
can be seen from anywhere in that leaf, and is used to reduce to a
near-minimum the polygons that have to be considered for drawing from a
given viewpoint, as well as the entities that have to be updated over
the network (for multiplayer games) and drawn. Calculating the PVS is
expensive; Quake levels take 10 to 30 minutes to process on a
four-processor Alpha, and even with speedup tweaks to the BSPer (the
most effective of which was replacing many calls to **malloc()** with
stack-based structures—beware of **malloc()** in performance-sensitive
code), Quake 2 levels are taking up to an hour to process. (Note,
however, that that includes BSPing, PVS calculations, and radiosity
lighting, which I'll discuss later.)
Some good news, though, is that in the nearly two years since we got the
Alpha, Pentium Pros have become as fast as that generation of Alphas, so
it is now possible to calculate the PVS on an affordable machine. On the
other hand, even 10 minutes of BSPing does hurt designer productivity.
John has always been a big advocate of moving code out of the runtime
program into utilities, and of preprocessing for performance and runtime
simplicity, but even he thinks that in Quake, we may have pushed that to
the point where it interfered too much with workflow. The real problem,
of course, is that even a huge amount of money can't buy orders of
magnitude more performance than commodity computers; we are getting an
eight-R10000 SGI compute server, but that's only about twice as fast as
an off-the-shelf four-processor Pentium Pro.
The size of the PVS for each leaf is manageable because it is stored as
a bit vector, with a 1-bit for the position in the overall leaf array of
each leaf that's visible from the current leaf. Most leaves are
invisible from any one leaf, so the PVS for each leaf consists mostly of
zeros, and compacts nicely with run-length encoding.
There are two further interesting points about the PVS. First, the Quake
PVS does not exclude quite as many leaves from potential visibility as
it could, because the surfaces that precisely describe leaf-to-leaf
visibility are quadratic surfaces; in the interests of speed and
simplicity, planar surfaces with some slope are used instead. Second,
the PVS describes visibility from anywhere in a leaf, rather than from a
specific viewpoint; this can cause two or three times as many polygons
as are actually visible to be considered. John has been researching the
possibility of an EVS—an *exactly visible set*—and has concluded that a
6-D BSP with hyperbolic separating planes could do the job; the problem
now is that he doesn't know how to get the math to work, at least at any
reasonable speed.
An interesting extension of the PVS is what John calls the *potentially
hearable set* (PHS)—all the leaves visible from a given leaf, plus all
the leaves visible from *those* leaves—in other words, both the directly
visible leaves and the one-bounce visible leaves. Of course, this is not
exactly the hearable space, because sounds could echo or carry further
than that, but it does serve quite nicely as a potentially *relevant*
space—the set of leaves that have any interest to the player. In Quake,
all sounds that happen anywhere in the world are sent to the client, and
are heard, even through walls, if they're close enough; an explosion
around the corner could be well within hearing and very important to
hear, so the PVS can't be used to reject that sound, but unfortunately
an explosion on the other side of a solid wall will sound exactly the
same. Not only is it confusing hearing sounds through walls, but in a
modem game, the bandwidth required to send all the sounds in a level can
slow things down considerably. In a recent version of QuakeWorld, a
specifically multiplayer variant of Quake I'll discuss later, John uses
the PHS to determine which sounds to bother sending, and the resulting
bandwidth improvement has made it possible to bump the maximum number of
players from 16 to 32. Better yet, a sound on the other side of a solid
wall won't be heard unless there's an opening that permits the sound to
come through. (In the future, John will use the PVS to determine fully
audible sounds, and the PHS to determine muted sounds.) Also, the PHS
can be used for events like explosions that might not have their center
in the PVS, but have portions that reach into the PVS. In general, the
PHS is useful as an approximation of the space in which the client might
need to be notified of events.
The final preprocessing step is light map generation. Each light is
traced out into the world to see what polygons it strikes, and the
cumulative effect of all lights on each surface is stored as a light
map, a sampling of light values on a 16-texel grid. In Quake 2,
radiosity lighting—a considerably more expensive process, but one that
produces highly realistic lighting—is performed, but I'll save that for
later.