We wanted the MotoGP bikes to show visible damage after they crashed. This wasn't a core feature, just a nice-to-have if we could make it work without too much effort.
These were the days of shader model 1.1, which is limited to 8 pixel shader instructions. And I had already used 7 of them for the lighting model. We couldn't afford to draw extra geometry, so I had to figure out a way to render damage with a single shader instruction.
We thought about dynamically modifying the bike textures when damage occurred, but these were in DXT compressed format, which isn't something you can efficiently render onto. We couldn't afford to store them uncompressed, or to store a second version of each texture with damage built in, because we were already running low on memory.
- The artists created a single 512x512 texture page, which included a number of different scratch and dent patterns, separated by areas of zero alpha. This was shared by all the bike models, so it didn't cost too much memory.
- Bike were first textured with a diffuse color map, which was different for each bike. The shared damage texture was then mapped over the top, using a second texture coordinate channel so the artists could control the position of every scrape and dent.
- I added a single extra instruction to my pixel shader, which blended the damage texture over the top of the diffuse map, using a shader parameter to control the amount of the blend. This parameter was initialized to zero, so the damage layer was invisible.
- When a bike crashed, we changed the parameter to fade in the scrapes and dents.
This system was very crude, because the entire damage layer faded in at the same time, and there was no way to make it appear only in the spot where the collision occurred. But when bikes crash, they tend to crash hard, tumbling and sliding all over the place, unlike cars which can bounce off each other and remain upright. So we decided this was good enough.
Here's an example of a scratched up bike:
Shortly after this system came on line, one of the artists asked whether they should map the damage texture onto the wheels as well as the body. Lightbulb! We couldn't fade in damage for individual parts of the body, because this was controlled by a per-bike shader parameter, but we could fade it separately for the body versus the wheels. Each wheel was drawn as a separate batch (a necessity since we had to change the transform matrix to make them spin) so it cost nothing to change the damage amount at the same time.
We decided to make the wheels look dirty when you drove off the road. Using the same overlay texture that already provided the body scratches, the artists textured the wheels to add a layer of grass stains over the rubber. We faded this in when you drove on the grass, then (unlike the body damage) gradually faded it out when you returned to the road.
Two effects for the price of one!