I am in a need of implementing something we see in RTS games: team colors. Basically, I am looking for a way to colorize certain parts of a model. How would I achieve this? I have no idea where to even begin. Do I need to make some adjustments to the 3d model first?
The way I would do this is based on the texture maps you are applying to the units. For most stuff you would have some regions that need to be tinted and some that do not. So for example, you might have a normal tank but you want to just change the color of some flags.
If you paint the texture as if the colored regions are grayscale you can then use the alpha channel to designate which regions need to be colorized.
So in your shader you could go (for the most simple way):
float3 finalColor; if (colorFromTex.a > 0) finalColor = colorFromTex.rgb; else finalColor = colorFromTex.rgb*myTintColor.rgb;
That's not optimal though since you will a have a hard transition and have a branch in your shader. Instead it's better to go:
float3 finalColor = lerp(colorFromTex.rgb, colorFromTex.rgb*myTintColor.rgb, colorFromTex.a);
One technique is to have two sets of textures for each model - one red, the other blue. Then depending on which team the character is assigned to you apply that texture set.
Obviously this only works if you have just two teams. While you might get away with it for more than two it starts to get inefficient.
Another way is to blend two textures - the first being the base texture for the model, the second being a coloured overlay which you could generate at runtime.
A third way could be to change the colour of the base model and have no textures (or partially transparent textures) over those parts of the model that you want to show the team colours.
Devoting a texture alpha channel to team color makes DXT textures 2x bigger, so I would rather use chroma key to calculate team color. Designate one color (e.g. green, blue, magenta) as the "reserved color" in your textures.
When the engine boots up, make a matrix for each team color that rotates the "reserved color" onto the team color. Just before drawing a team object, set this matrix as a pixel shader constant.
In the pixel shader, transform the pixel color by the team color matrix. Lerp the untransformed pixel color with the transformed pixel color, by an amount proportional to the angle of the pixel's chroma to the "reserved color's" chroma.
This will cost you some ALU instructions and trig in the pixel shader, but that's a lot cheaper than bloating up your texture cache with textures 2x as big.
You also have the ability to have multiple chroma keys (e.g. magenta and cyan get mapped onto a primary and secondary team color) without devoting one texture channel to each color.