A palette swap is a technique used in games. It is the computational equivalent of colour by numbers. In colour by numbers you get a page with some numbers identifying a series of shapes, and a collection of little paint pots with numbers on the lids. The numbers tell you what shape should be which colour. The computer does the same thing with the palette swap. The computer wants to render a picture, each pixel of this picture has a colour code. (An RGB number is 3 numbers that identify a number in terms of how much of Red, Green and Blue to mix) The computer takes the colour code to the palette and the palette exchanges that number for a new number and, in doing so, swaps the colour that would have been rendered. This technique was initially developed to be able to show a lot of different types of characters using only one texture. This allowed developers to save a lot of space in the memory and has been used ever since.
The reason I’ve been developing a palette swapping shader is for use in my gravity inversion game. I found it quite difficult to sense which direction gravity was pointing, kind of the whole point, so I decided to completely change the colours of everything on the screen while gravity was inverted. This let me quickly change the colour of all of the textures rendered in my game by only changing a small 16 pixel sprite. I found that using this didn’t cause any noticeable slow down, even on mobile devices. Then I came to the idea that, if the palettes are small and easy to produce, why not let the player choose which colour schemes they would like.
I’m developing my game in Unity2D, so how did I manage it? I give two textures to the shader. One is the original texture, the other is the palette. I then need to convert the colour of the first texture into the coordinates of the second. I decided to use the number for the red composition only and then use that value of between 0 and 1 to translate to how far along the palette to go. Once I had the new colour I was nearly in the clear. I also wanted to preserve the transparency of the original texture, so after changing the render type from opaque I copy the old alpha (transparency) value to the new colour. I’m using textures not sprites to preserve texture scrolling for my parallax background.
After putting it all together, I’ve found it works well. All I have to do is send an event to the ColourInverter script I wrote which accesses the shader properties and swaps out the current palette. I decided to do it this way as I found the shader if statement to be less efficient than changing the palette texture (I haven’t tested this on low end phones.)