Normal quotes

This commit is contained in:
James Gregory 2013-12-30 18:34:31 +11:00
commit 18011c595a
352 changed files with 6040 additions and 6040 deletions

View file

@ -12,15 +12,15 @@ vertex calculations are performed.
Early on, we decided to allow lower drawing quality for triangle models
than for the world, in the interests of speed. For example, the
triangles in the models are small, and usually distant—and generally
part of a quickly moving monster that’s trying its best to do you in—so
part of a quickly moving monster that's trying its best to do you in—so
the quality benefits of perspective texture mapping would add little
value. Consequently, we chose to draw the triangles with affine texture
mapping, avoiding the work required for perspective. Mind you, the
models are perspective-correct at the vertices; it’s just the pixels
models are perspective-correct at the vertices; it's just the pixels
between the vertices that suffer slight warping.
![](images/69-01.jpg)\
**Figure 69.1**  *Quake’s triangle-model drawing pipeline.*
**Figure 69.1**  *Quake's triangle-model drawing pipeline.*
#### Trading Subpixel Precision for Speed {#Heading8}
@ -45,10 +45,10 @@ because the integer execution pipes can process independently while FDIV
executes.
Finally, we decided to Gouraud-shade the triangle models, because this
makes them look considerably more 3-D. However, we can’t afford to
makes them look considerably more 3-D. However, we can't afford to
calculate where all the relevant light sources for each model are in
each frame, or even which is the primary light source. Instead, we
select each model’s lighting level based on how brightly the floor point
select each model's lighting level based on how brightly the floor point
it was standing on is lit, and use that lighting level for both ambient
lighting (so all parts of the model have some illumination) and Gouraud
shading—but the lighting vector for Gouraud shading is a fixed vector,
@ -56,22 +56,22 @@ so the model is always lit from the same direction. Somewhat
surprisingly, in practice this looks considerably better than pure
ambient lighting.
#### An Idea that Didn’t Work {#Heading9}
#### An Idea that Didn't Work {#Heading9}
As we implemented triangle models, we tried several ideas that didn’t
work out. One that’s notable because it seems so appealing is caching a
model’s image from one frame and reusing it in the next frame as a
As we implemented triangle models, we tried several ideas that didn't
work out. One that's notable because it seems so appealing is caching a
model's image from one frame and reusing it in the next frame as a
sprite. Our thinking was that clipping, transforming, projecting, and
drawing a several-hundred-triangle model was going to be a lot more
expensive than drawing a sprite, too expensive to allow very many models
to be visible at once. We wanted to be able to display at least a dozen
simultaneous models, so the idea was that for all but the closest
models, we’d draw into a sprite, then reuse that sprite at the model’s
models, we'd draw into a sprite, then reuse that sprite at the model's
new locations for the next two or three frames, amortizing the 3-D
drawing cost over several frames and boosting overall model-drawing
performance. The rendering wouldn’t be exactly right when the sprite was
performance. The rendering wouldn't be exactly right when the sprite was
reused, because the view of the model would change from frame to frame
as the viewer and model moved, but it didn’t seem likely that that
as the viewer and model moved, but it didn't seem likely that that
slight inaccuracy would be noticeable for any but the nearest and
largest models.
@ -81,13 +81,13 @@ fact they looked a lot like the sprites used in DOOM—precisely the
effect we were trying to avoid. This was especially true if we reused
them more than once—and if we reused them only once, then we had to do
one full 3-D rendering plus two sprite renderings every two frames,
which wasn’t much faster than simply doing two 3-D renderings.
which wasn't much faster than simply doing two 3-D renderings.
The sprite architecture also introduced considerable code complexity,
increased memory footprint because of the need to cache the sprites, and
made it difficult to get hidden surfaces exactly right because sprites
are unavoidably 2-D. The performance of drawing the sprites dropped
sharply as models got closer, and that’s also where the sprites looked
sharply as models got closer, and that's also where the sprites looked
worse when they were reused, limiting sprites to use at a considerable
distance. All these problems could have been worked out reasonably well
if necessary, but the sprite architecture just had the feeling of being
@ -103,7 +103,7 @@ suffering heavily from effects such as texture aliasing and pixel
quantization, he reasoned, so it should work just as well if we could
come up with another way of drawing blobs of approximately equal
quality. The trick was to come up with such an alternative approach. We
tossed around half-formed ideas like flood-filling the model’s image
tossed around half-formed ideas like flood-filling the model's image
within its silhouette, or encoding the model as a set of deltas, picking
a visible seed point, and working around the visible side of the model
according to the deltas. The first approach that seemed practical enough
@ -114,7 +114,7 @@ triangles were large, and the quality was very erratic. However, it did
point the way to something that in the end did the trick.
One morning I came in to the office to find that overnight (and well
into the morning), John had designed and implemented a technique I’ll
into the morning), John had designed and implemented a technique I'll
call *subdivision rasterization*. This technique scans out approximately
the right pixels for each triangle, with almost no overhead, as follows.
First, all vertices in the model are drawn. Ideally, only the vertices