Mini tech art tutorial: How to colour coordinate everything, but the programmer way. #techart #indiedev
First of all, you want to pick a nice colour palette. If you need help with that, check out how to make a good colour palette programmatically in this thread: https://twitter.com/usefulslug/status/1265604318016811011
When using a colour palette, it's best if it's applied to everything, so you don't end up with something sticking out as looking like it doesn't belong. Sometimes you have assets you need to use, that don't conform to said colour palette, and fixing them by hand is work.
Ideally we don't want to mess up how it looks too much, but just tweak the art assets so they fit our pallette. We want to find the closest colour from our pallette, and use that hue / chroma.
As usual, RGB color space is terrible for this. We need something better, that has a sense of hue, lightness etc. Oklab by @bjornornorn is perfect for this. It maintains perceptual lightness, and is easy to implement. Check that out here: https://bottosson.github.io/posts/oklab/ 
Now we take each colour that we have in our source asset, be that the colours in a texture, or elsewhere, and we convert it to Oklab. We end up with values for "L" -lightness, and "a" - green/red, "b" blue/yellow.
We also have to convert our colour palette to Oklab, here's the one I am using for my game, with the converted Oklab values.
Now we need a way to compare the distance between two colours, to find the best match. This is a hideously complex subject, but let's just say that it ends up being a bit of a give/take on perceptual accuracy vs complexity, and a touch of what works best for you.
You actually get surprisingly far with just treating it as euclidean distance (like the length of a vector), but you'll soon spot that some things look weird. The Oklab suggestion is to use the CIEDE2000 color distance formula, I ended up with something called DeltaE.
The main reason I landed on deltaE was that I don't like it when code I don't understand is long, and CIEDE2000 is not a breeze.
Here's deltaE, copy pasta'd to work with unity: https://gist.github.com/usefulslug/a6ae17e2322e53be01d7aac2213d0749
And here's CIEDE2000, copy pasta'd to work with unity:
https://gist.github.com/usefulslug/51fd47e7e69d3710cfe28ac9f8e23056
Whichever way you go, loop through and find the closest colour from your palette. Now, while you want to maintain the lightness of your original colour, you want to change the a and b values, so that they fit your colour palette.
In other words, your newLab.L = oldLab.L, but newLab.a = closestFromPalette.a and newLab.b = closestFromPalette.b.
That seems weird, but it works rather well. Perceptually the colours are going to have the same brightness as before, but visually they will fit with the pallette.
Finally some closeup examples:
You can follow @usefulslug.
Tip: mention @twtextapp on a Twitter thread with the keyword “unroll” to get a link to it.

Latest Threads Unrolled: