135 lines
7.6 KiB
Markdown
135 lines
7.6 KiB
Markdown
------------------------ --------------------------------- --------------------
|
||
[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
|