I have spent a long time recreating a system that used to be trivial.
Back in the early days of computers and arcade machines cycling colors was a novel effect. Even on the Atari 2600, a computer that couldn’t even draw an entire frame to the screen and instead had to parcel it out to individual crt scanlines, programmer figured out ways to cycle though a palette of colors. On some games the most animation you were likely to see was color cycling.
Of course, later machines had the ability to take one tile or chunk of graphics data and swap it’s colors on the fly. Often a system would have few different sets of colors and certain sprite objects could change what set of colors they were using moment to moment. This means that Mario can flash for a few frames or change his outfit to show that he now holds a fire flower without having to store an entirely unique version of the character in the extremely limited space of a NES cartridge.
As machines got more powerful, changing out colors of an object became ubiquitous. Everything could do it. Today you could play entire videos as a texture across a moving, animating, characters body. It’s simple. Right?
That’s what I thought. It should be absolutely the most simple thing in the world to change the colors of a textured 3D model on the fly. It’s not. While we have the ability to target specific fragments, pixels or even sub-pixels, being drawn to the screen for any number of modifications and mathematical manipulations hundreds or thousands of times per second, just changing a designated area of a model from one color to another is oddly difficult.
I ended up having to create an entire system and custom shader that loads a shared palette resource and addresses each individual color by a numeric index. I then set the models up so that the vertexes carry specific greyscale color values. At runtime I swap the built in color of the model with an arbitrary value from the palette.
On most models I have up to 16 different slots that can be recolored with any color from a 256 value palette. These can be animated and modified in realtime. I have objects that cycle through a set of colors or flash when they are hit without ever changing anything about their base values. My game system uses a single shader for everything. A single palette texture 1x256 pixels in size. Meshes don’t even need UV maps. Just vertex colors. The memory footprint is miniscule and, while it does need a GPU made within the last fifteen or twenty years, the system can run at a truly ridiculous framerate.
I’m still giving this system a workout and testing the limits, so it might break during some edge case or other, but I will probably do a more full writeup on how it works sometime down the road.