3D Coding TAT - Tips And Tricks
In this section I will describe some short tricks which may help gain a few CLK-cycles here and there.
1. Re-used polygon edges & slopes
Just as a polyhedron can be made from reused vertices so can the edges (even clipped ones - keep the top and bottom clipping lengths and determine left or right polygon sides).
2. To table or not to table?
It seems that 80x86 and all other new CPUs don't like accessing memory, which is strange considering the pathetic number of registers most have. My advice is to keep tables to a reasonable length and "blitz" use them (do ALL the indexing into the table in one go so that CPU cache doesn't have to be refilled) and for 2d tables (arrays) organize the most likely data horizontally so element (x+1,y) directly follows (x,y) as this way the CPU will cache this kind of data in more quickly.
3. Avoid reading the video card at all cost.
Show me a video card which is as fast as the main CPU memory and I will stop complaining, until then send hate mail to IBM and all PC hardware developers.
4. Don't be fooled by conditional jumps, they are evil.
I have heard about fancy new CPUs with branch-prediction stuff which can fail causing performance hic-cups.
5. Reuse the same texture to fill all the polygons before drawing a new one. This will help maximum the cache benefits, but this method is NOT really practical in most cases unless you only use 1 texture.
6. Use a dithering method to help smooth out blocky texture fills so you can
get away with small textures.
Try MIP-MAPPING techniques (use smaller textures for very distant objects). This will cache in better because the CPU isn't skipping as many bytes to scale down the texture (wasting cache space).
7. Texture SOFTWARE caches 'could' be handy especially for 90°, 180° or 270° texture scanning which the CPU really hates. (Don't believe the iNTEL 1 CLK memory timings, they be lies.)
8. Use 'fog' or short corridors.
This will help reduce the amount of CPU workload that an infinite horizon would cause. In real life you never see an infinite horizon because (a) the Earth is curved so distant objects will appear to pop up (b) dust and other atmospheric stuff gets in the way.
9. Use 'horizon' maps.
This is another one of my untested ideas. For each window or doorway define an 'horizon' texture bitmap token. Now at render time if the door or window is beyond a certain distance then simply fill it with the horizon bitmap instead of rendering the pixel high objects which should be seen three miles away.
10. Keep data acesses to a WORD or DWORD boundary.
Misaligned data chews up valuable CPU ticks.
11. Restrict the view angles to 2 axises.
This removes a lot of multiples or you could use spherical or polar coordinates instead.
12. Use MIP-MAPPING (multiple copies of a texture at different sizes) or better still use surface detail links, so that mile away objects have the basic polygon shape and close up ones have bar-codes and other texture detail fancy bits.
13. Anti-alasising - smooth out these blocky or stair case lines.
This is best used for overlaying sprites (scores, ammo, weapons) so that chunky pixels don't appear to be that chunky.
14. Use dark environments.
This means that most walls and surfaces can be ignored and drawn as a solid black polygon (sly eh?).
15. This is THE golden rule, never read from a disk or CD when in the middle of a level. It really sux when the game suddenly halts while the disk or CD spins up to speed - not only does this break the illusion of the game but thrown it to the ground and stamps on the pieces.
16. Don't shade your polygons! I think (I could be wrong) that MDK didn't perform any realtime shading in their texture-mapper, so this removes 1 instruction (1 memory access) PER-PIXEL. When dealing with SVGA video modes which begin at 640x480 (307,200 pixels) this saving can be VERY large indeed. Even Monster Trucks 2 don't bother with shading their polygons either, they used dithering.
1: Need more MHZ ?
Texture mapping with shading can chew through even the fastest of today's CPUs. If we use a resolution of 640x480 at a SLOW vertical frequency of 60 Hz then to perform a silky smooth engine we need to draw and shade 18,432,000 pixels per second. A primitive texture mapper would need to do these operation:
a. Fetch a pixel from the bitmap texture (1 memory read) b. Index the pixel using a shade look-up table (1 memory read) c. Write the pixel to the screen (1 memory write)
Not including the CPU instructions to perform the above code a total of 36,864,000 reads and 1,843,200 writes need to be done thats 55,296,000 memory accesses! Remember this does NOT include all the other engine code, data processing and possible pixel overdraw or overlaid scores etc. Now shall we try a resolution of 1024x768 or higher? Nah, thought not (heh heh).
At the end of the day PCs are still extremely S-L-O-W on the video accessing side of things. Your super Pentium beast might be ticking on at 266 Mhz but the memory is probably only operating at 1/3rd of this speed (if you are lucky) but the video card is normally much slower because the CPU is fighting the video card to access the same memory. Thankfully this bottleneck is slowly, so very slowly being tackled with better video card developments, but it still is one of the worst things about the old PC (and I do mean old).
2: Crashing the Cache
Almost every modern CPU uses burst reads and burst writes along with caches to grab small linears blocks of memory. This is good for linear data structures like lists, tables and programs as all these tend to be mostly sequential. But for things such as texture mapping and accessing 2d arrays (i.e. bitmaps) it really sux. The main problem is that texture mapping often only needs a single byte from every Nth byte in memory whereas modern CPU like to read 16, 32 or more bytes at each address into it's cache.
3: Moral of the story
If you can, CHEAT! And cheat often as 99% of players don't really care if your texture-mapper using the mathematically correct formulas or a quick 'n' dirty approximation, so long as it runs smoothly and is playable then a lot of errors will be overlooked. Take a look at Jedi Knight or Tomb Raider, not exactly the perfect texture mappers are they? Players will often overlook graphical cheats if the game remains playable.