Retidy, removing align=left from headings and empty paragraphs

This commit is contained in:
James Gregory 2013-12-30 15:37:13 +11:00
commit a96a114403
362 changed files with 8472 additions and 5040 deletions

View file

@ -1,5 +1,4 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
@ -19,22 +18,26 @@
<center>
<table border="1">
<tr>
<td><a href="68-02.html">Previous</a></td>
<td>
<a href="68-02.html">Previous</a>
</td>
<td><a href="index.html">Table of Contents</a></td>
<td>
<a href="index.html">Table of Contents</a>
</td>
<td><a href="68-04.html">Next</a></td>
<td>
<a href="68-04.html">Next</a>
</td>
</tr>
</table>
</center>
<p><br /></p>
<p>Quake&rsquo;s approach, which I&rsquo;ll call surface-based lighting, preprocesses differently, and adds an extra rendering step. During off-line preprocessing, a grid, called a light map, is calculated for each polygon in the world, with a lighting value every 16 texels horizontally and vertically. This lighting is done by casting light from all the nearby lights in the world to each of the grid points on the polygon, and summing the results for each grid point. The Quake preprocessor filters the values, so shadow edges don&rsquo;t have a stair-step appearance (a technique suggested by Billy Zelsnack); additional preprocessing could be done, for example Phong shading to make surfaces appear smoothly curved. Then, at runtime, the polygon&rsquo;s texture is tiled into a buffer, with each texel lit according to the weighted average intensities of the four nearest light map points, as shown in Figure 68.3. If dynamic lighting is needed, the light map is modified accordingly before the buffer, which I&rsquo;ll call a surface, is built. Then the polygon is drawn with perspective texture mapping, with the surface serving as the input texture, and with no lighting performed during the texture mapping.</p>
<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" id="Heading9">Size and Speed</h4>
<h4 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>
@ -51,16 +54,20 @@
<p>With surface rebuilding needed only rarely, thanks to surface caching, Quake&rsquo;s rasterization speed is generally the speed of the unlit, perspective-correct texture-mapping inner loop, which suffers from more cache misses than Gouraud-shaded, tiled texture mapping, but doesn&rsquo;t have the overhead of Gouraud shading, and allows the use of larger polygons. In the worst case, where everything in a frame is a new surface, the speed of the surface-caching approach is somewhat slower than Gouraud shading, but generally surface caching provides equal or better performance, so once surface caching was implemented in Quake, performance was no longer a problem&mdash;but size became a concern.</p>
<p><br /></p>
<center>
<table border="1">
<tr>
<td><a href="68-02.html">Previous</a></td>
<td>
<a href="68-02.html">Previous</a>
</td>
<td><a href="index.html">Table of Contents</a></td>
<td>
<a href="index.html">Table of Contents</a>
</td>
<td><a href="68-04.html">Next</a></td>
<td>
<a href="68-04.html">Next</a>
</td>
</tr>
</table>
</center>