Initial conversion to markdown
This commit is contained in:
parent
a96a114403
commit
5e10794a24
362 changed files with 67353 additions and 0 deletions
135
68-01.md
Normal file
135
68-01.md
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
------------------------ --------------------------------- --------------------
|
||||
[Previous](67-05.html) [Table of Contents](index.html) [Next](68-02.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
Chapter 68\
|
||||
Quake’s Lighting Model {#Heading1}
|
||||
-----------------------
|
||||
|
||||
### A Radically Different Approach to Lighting Polygons {#Heading2}
|
||||
|
||||
It was during my senior year in college that I discovered computer
|
||||
games. Not Wizardry, or Choplifter, or Ultima, because none of those
|
||||
existed yet—the game that hooked me was the original Star Trek game, in
|
||||
which you navigated from one 8x8 quadrant to another in search of
|
||||
starbases, occasionally firing phasers or photon torpedoes. This was
|
||||
less exciting than it sounds; after each move, the current quadrant had
|
||||
to be reprinted from scratch, along with the current stats—and the
|
||||
output device was a 10 cps printball console. A typical game took over
|
||||
an hour, during which nothing particularly stimulating ever happened
|
||||
(Klingons appeared periodically, but they politely waited for your next
|
||||
move before attacking, and your photon torpedoes never missed, so the
|
||||
outcome was never in doubt), but none of that mattered; nothing could
|
||||
detract from the sheer thrill of being in a computer-simulated universe.
|
||||
|
||||
Then the college got a PDP-11 with four CRT terminals, and suddenly Star
|
||||
Trek could redraw in a second instead of a minute. Better yet, I found
|
||||
the source code for the Star Trek program in the recesses of the new
|
||||
system, the first time I’d ever seen any real-world code other than my
|
||||
own, and excitedly dove into it. One evening, as I was looking through
|
||||
the code, a really cute girl at the next terminal asked me for help
|
||||
getting a program to run. After I had helped her, eager to get to know
|
||||
her better, I said, “Want to see something? This is the actual source
|
||||
for the Star Trek game!” and proceeded to page through the code,
|
||||
describing each subroutine. We got to talking, and eventually I worked
|
||||
up the nerve to ask her out. She said sure, and we ended up having a
|
||||
good time, although things soon fell apart because of her two or three
|
||||
other boyfriends (I never did get an exact count). The interesting
|
||||
thing, though, was her response when I finally got around to asking her
|
||||
out. She said, “It’s about time!” When I asked what she meant, she said,
|
||||
“I’ve been trying to get you to ask me out all evening—but it took you
|
||||
forever! You didn’t actually think I was interested in that Star Trek
|
||||
program, did you?”
|
||||
|
||||
Actually, yes, I had thought that, because *I* was interested in it. One
|
||||
thing I learned from that experience, and have had reinforced countless
|
||||
times since, is that we—you, me, anyone who programs because they love
|
||||
it, who would do it for free if necessary—are a breed apart. We’re
|
||||
different, and luckily so; while everyone else is worrying about
|
||||
downsizing, we’re in one of the hottest industries in the world. And, so
|
||||
far as I can see, the biggest reason we’re in such a good situation
|
||||
isn’t intelligence, or hard work, or education, although those help;
|
||||
it’s that we actually *like* this stuff.
|
||||
|
||||
It’s important to keep it that way. I’ve seen far too many people start
|
||||
to treat programming like a job, forgetting the joy of doing it, and
|
||||
burn out. So keep an eye on how you feel about the programming you’re
|
||||
doing, and if it’s getting stale, it’s time to learn something new;
|
||||
there’s plenty of interesting programming of all sorts to be done.
|
||||
Follow your interests—and don’t forget to have fun!
|
||||
|
||||
### The Lighting Conundrum {#Heading3}
|
||||
|
||||
I spent about two years working with John Carmack on Quake’s 3-D
|
||||
graphics engine. John faced several fundamental design issues while
|
||||
architecting Quake. I’ve written in earlier chapters about some of those
|
||||
issues, including eliminating non-visible polygons quickly via a
|
||||
precalculated potentially visible set (PVS), and improving performance
|
||||
by inserting potentially visible polygons into a global edge list and
|
||||
scanning out only the nearest polygon at each pixel.
|
||||
|
||||
In this chapter, I’m going to talk about another, equally crucial design
|
||||
issue: how we developed our lighting approach for the part of the Quake
|
||||
engine that draws the world itself, the static walls and floors and
|
||||
ceilings. Monsters and players are drawn using completely different
|
||||
rendering code, with speed the overriding factor. A primary goal for the
|
||||
world, on the other hand, was to be as precise as possible, getting
|
||||
everything right so that polygons, textures, and sophisticated lighting
|
||||
would be pegged in place, with no visible shifting or distortion under
|
||||
all viewing conditions, for maximum player immersion—all with good
|
||||
performance, of course. As I’ll discuss, the twin goals of performance
|
||||
and rock-solid, complex lighting proved to be difficult to achieve with
|
||||
traditional lighting approaches; ultimately, a dramatically different
|
||||
approach was required.
|
||||
|
||||
### Gouraud Shading {#Heading4}
|
||||
|
||||
The traditional way to do realistic lighting in polygon pipelines is
|
||||
Gouraud shading (also known as *smooth shading*). Gouraud shading
|
||||
involves generating a lighting value at each polygon vertex by applying
|
||||
all relevant world lighting, linearly interpolating between lighting
|
||||
values down the edges of the polygon, and then linearly interpolating
|
||||
between the edges of the polygon across each span. If texture mapping is
|
||||
desired (and all polygons are texture mapped in Quake), then at each
|
||||
pixel in each span, the pixel’s corresponding texture map location
|
||||
(texel) is determined, and the interpolated lighting is applied to the
|
||||
texel to generate a final, lit pixel. Texels are generally taken from a
|
||||
32x32 or 64x64 texture that’s tiled repeatedly across the polygon, for
|
||||
several reasons: performance (a 64x64 texture sits nicely in the 486 or
|
||||
Pentium cache), database size, and less artwork.
|
||||
|
||||
The interpolated lighting can consist of either a color intensity value
|
||||
or three separate red, green, and blue values. RGB lighting produces
|
||||
more sophisticated results, such as colored lights, but is slower and
|
||||
best suited to RGB modes. Games like Quake that are targeted at
|
||||
palettized 256-color modes generally use intensity lighting; each pixel
|
||||
is lit by looking up the pixel color in a table, using the texel color
|
||||
and the lighting intensity as the look-up indices.
|
||||
|
||||
Gouraud shading allows for decent lighting effects with a relatively
|
||||
small amount of calculation and a compact data set that’s a simple
|
||||
extension of the basic polygon model. However, there are several
|
||||
important drawbacks to Gouraud shading, as well.
|
||||
|
||||
#### Problems with Gouraud Shading {#Heading5}
|
||||
|
||||
The quality of Gouraud shading depends heavily on the average size of
|
||||
the polygons being drawn. Linear interpolation is used, so highlights
|
||||
can only occur at vertices, and color gradients are monotonic across the
|
||||
face of each polygon. This can make for bland lighting effects if
|
||||
polygons are large, and makes it difficult to do spotlights and other
|
||||
detailed or dramatic lighting effects. After John brought the initial,
|
||||
primitive Quake engine up using Gouraud shading for lighting, the first
|
||||
thing he tried to improve lighting quality was adding a single vertex
|
||||
and creating new polygons wherever a spotlight was directly overhead a
|
||||
polygon, with the new vertex added directly underneath the light, as
|
||||
shown in Figure 68.1. This produced fairly attractive highlights, but
|
||||
simultaneously made evident several problems.
|
||||
|
||||
------------------------ --------------------------------- --------------------
|
||||
[Previous](67-05.html) [Table of Contents](index.html) [Next](68-02.html)
|
||||
------------------------ --------------------------------- --------------------
|
||||
|
||||
* * * * *
|
||||
|
||||
Graphics Programming Black Book © 2001 Michael Abrash
|
||||
Loading…
Reference in a new issue