Strip comments and inline ids onto h*

This commit is contained in:
James Gregory 2013-12-30 15:11:04 +11:00
commit 0f5f617adb
362 changed files with 2519 additions and 6694 deletions

View file

@ -10,16 +10,9 @@
<meta name="vspubdate" content="07/01/97" />
<meta name="vscategory" content="Web and Software Development: Game Development,Web and Software Development: Graphics and Multimedia Development" />
<title>Michael Abrash's Graphics Programming Black Book Special Edition: Quake's Lighting Model</title><!-- HEADER -->
<!-- Empty Reference Subhead -->
<!--ISBN=1576101746//-->
<!--TITLE=Michael Abrash's Graphics Programming Black Book Special Edition//-->
<!--AUTHOR=Michael Abrash//-->
<!--PUBLISHER=The Coriolis Group, Inc.//-->
<title>Michael Abrash's Graphics Programming Black Book Special Edition: Quake's Lighting Model</title>
<meta name="chapter" content="68" />
<meta name="pages" content="1251-1254" />
<!--UNASSIGNED1//-->
<!--UNASSIGNED2//-->
</head>
<body>
@ -41,19 +34,18 @@
<p>So what does surface-based lighting buy us? First and foremost, it provides consistent, perspective-correct lighting, eliminating all rotational, viewing, and clipping variance, because lighting is done in surface space rather than in screen space. By lighting in surface space, we bind the lighting to the texels in an invariant way, and then the lighting gets a free ride through the perspective texture mapper and ends up perfectly matched to the texels. Surface-based lighting also supports good, although not perfect, detail for overlapping lights and shadows. The 16-texel grid has a resolution of two feet in the Quake frame of reference, and this relatively fine resolution, together with the filtering performed when the light map is built, is sufficient to support complex shadows with smoothly fading edges. Additionally, surface-based lighting eliminates lighting glitches at t-junctions, because lighting is unrelated to vertices. In short, surface-based lighting meets all of Quake&rsquo;s visual quality goals, which leaves only one question: How does it perform?</p>
<h4 align="left"><a id="Heading9"></a>Size and Speed</h4>
<h4 align="left" id="Heading9">Size and Speed</h4>
<p>As it turns out, the raw speed of surface-based lighting is pretty good. Although an extra step is required to build the surface, moving lighting and tiling into a separate loop from texture mapping allows each of the two loops to be optimized very effectively, with almost all variables kept in registers. The surface-building inner loop is particularly efficient, because it consists of nothing more than interpolating intensity, combining it with a texel and using the result to look up a lit texel color, and storing the results with a dword write every four texels. In assembly language, we got this code down to 2.25 cycles per lit texel in Quake. Similarly, the texture-mapping inner loop, which overlaps an FDIV for floating-point perspective correction with integer pixel drawing in 16-pixel bursts, has been squeezed down to 7.5 cycles per pixel on a Pentium, so the combined inner loop times for building and drawing a surface is roughly in the neighborhood of 10 cycles per pixel. It&rsquo;s certainly possible to write a Gouraud-shaded perspective-correct texture mapper that&rsquo;s somewhat faster than 10 cycles, but 10 cycles/pixel is fast enough to do 40 frames/second at 640x400 on a Pentium/100, so the cycle counts of surface-based lighting are acceptable. It&rsquo;s worth noting that it&rsquo;s possible to write a one-pass texture mapper that does approximately perspective-correct lighting. However, I have yet to hear of or devise such an inner loop that isn&rsquo;t complicated and full of special cases, which makes it hard to optimize; worse, this approach doesn&rsquo;t work well with the procedural and post-processing techniques I&rsquo;ll discuss shortly.</p>
<p><a id="Fig3"><!-- </A><A HREF="javascript:displayWindow('images/68-03.jpg',406,465 )"> --><img src="images/68-03.jpg" /><br />
<!-- </A>
<BR><A HREF="javascript:displayWindow('images/68-03.jpg',406,465)"> --><b>Figure 68.3</b></a>&nbsp;&nbsp;<i>Tiling the texture and lighting the texels from the light map.</i></p>
<p><a id="Fig3"><img src="images/68-03.jpg" /><br />
<b>Figure 68.3</b></a>&nbsp;&nbsp;<i>Tiling the texture and lighting the texels from the light map.</i></p>
<p>Moreover, surface-based lighting tends to spend more of its time in inner loops, because polygons can have any number of sides and don&rsquo;t need to be split into multiple smaller polygons for lighting purposes; this reduces the amount of transformation and projection that are required, and makes polygon spans longer. So the performance of surface-based lighting stacks up very well indeed&mdash;except for caching.</p>
<p>I mentioned earlier that a 64x64 texture tile fits nicely in the processor cache. A typical surface doesn&rsquo;t. Every texel in every surface is unique, so even at 320x200 resolution, something on the rough order of 64,000 texels must be read in order to draw a single scene. (The number actually varies quite a bit, as discussed below, but 64,000 is in the ballpark.) This means that on a Pentium, we&rsquo;re guaranteed to miss the cache once every 32 texels, and the number can be considerably worse than that if the texture access patterns are such that we don&rsquo;t use every texel in a given cache line before that data gets thrown out of the cache. Then, too, when a surface is built, the surface buffer won&rsquo;t be in the cache, so the writes will be uncached writes that have to go to main memory, then get read back from main memory at texture mapping time, potentially slowing things further still. All this together makes the combination of surface building and unlit texture mapping a potential performance problem, but that never posed a problem during the development of Quake, thanks to surface caching.</p>
<h3><a id="Heading10"></a>Surface Caching</h3>
<h3 id="Heading10">Surface Caching</h3>
<p>When he thought of surface-based lighting, John immediately realized that surface building would be relatively expensive. (In fact, he assumed it would be considerably more expensive than it actually turned out to be with full assembly-language optimization.) Consequently, his design included the concept of caching surfaces, so that if the same surface were visible in the next frame, it could be reused without having to be rebuilt.</p>
@ -76,10 +68,6 @@
<div align="center">
Graphics Programming Black Book &copy; 2001 Michael Abrash
</div><!-- all of the reference materials (books) have the footer and subfoot reveresed -->
<!-- reference_subfoot = footer -->
<!-- reference_footer = subfoot -->
<!-- BEGIN SUB FOOTER -->
<!-- END FOOTER -->
</div>
</body>
</html>