We are all used to RGB color scheme. It seems very logical from the first sight. But this week we ran into a little problem with that. And the solution for the problem was quite phenomenal for us.

Imagine that you have a game world originally painted in blue color scheme. Later you decide to create another world that is different and the main color there is red. Is there an easy way of doing this reusing old graphics to have it in different color that feels the same as original one? Of course, you can ask artist to make another set of textures. That means a lot of duplicated textures in different colors, more work for artists, almost no flexibility at runtime and bigger game size.

So where is the problem?
Any pixel in RGB is represented as Red, Green and Blue respectively. Blue color is (0, 0, 1). Pink color is (1, 0, 1). Changing from blue to pink is easy (0, 0, 1) + (1, 0, 0) = (1, 0, 1). That’s fine. But almost always textures have different variations of blue color and you cannot just simply add (1, 0, 0) to the whole picture. (blacks will become blue too! (0, 0, 0) + (1, 0, 0) = (1, 0, 0) )

Solution?
Use HSV(Hue-Saturation-Value)! When you want to change the color of any texture, convert the color of each pixel to HSV, modify Hue value, convert it back to RGB and put it on the screen.

The idea is that the Hue value is like a base color of your image. When you change it, Saturation and Value (level of black) remain the same. There you go. You have a texture that is the same feels the same as original but in different color!

HSV model was formally described by Alvy Ray Smith the cofounder of pixar in the August 1978.

WARNING: Shaders ahead.

Here is the example of the shader that uses this method.

half4 frag (v2f i) : COLOR{        
   float4 textureColor = tex2D (_MainTex, i.uv);
   float4 resultedColor;
   float3 textureColorInHSV =

   rgb_to_hsv(float3(textureColor.r, textureColor.g, textureColor.b));

   textureColorInHSV.r = ColorHue;
resultedColor = hsv_to_rgb(textureColorInHSV);
        
   return resultedColor;
}

Advertisements