You can use a simple shader for this, but I wouldn't do so, simply due to the fact that you're doing simple tinting with one color (or shades of one color) only. The Unity script above would work with some modifications, but you'll have to keep in mind that there's additional overhead/metadata in there that doesn't belong to the actual GLSL code.
What I'd do is split the texture based on tintable/non-tintable areas and then draw in two passes:
- One pass you'll render the un-tinted part of the texture.
- In another pass you'll render the tinted part of the texture utilizing
sf::Sprite::setColor() to set the actual color.
While this might be less efficient than using a shader, you'll get far better compatibility out of this (e.g. SFML's mobile ports don't support shaders so far). In addition to that, you won't have to hardcode multiple color checks/values/swaps (which you actually won't anyway, since it's better done programmatically).
Personally, I've used this strategy in the past with the following texture:
It's a simple sprite sheet of a guy running to the right (four frames of animation).
While the first row includes the full sprites that will be tinted, the second row contains the non-tinted areas.
To draw one of those characters, I'm using two sprites. Sprite one uses the first row of the texture and
sf::Sprite::setColor() to draw colored clothes. The second sprite is drawn on top without tinting to draw the hands and face using their original colors.
If you really want to do this in a shader, I'd avoid the branching
if () since that can slow down your code. Also it's quite tedious to update the code or work with multiple shades (which is a lot easier to be done with the tinting approach). So instead you could use a 1D texture 256 pixels wide. You'd just have to check a screen pixel's color and in case all three components are identical (or just red and cyan and green is 0), you'd use that value as the index in the 1D texture to get the replacement color.