1
\$\begingroup\$

To give an example of what I'm asking about, I'll use Saints Row 3 since I've been playing that lately. In that game you can customize your looks and your car's appearance a lot. Your coat can have a primary color and a trim color. Your car can have a primary color and a stripe color, etc.

Is there just a single coat texture that is being shaded two different colors somehow or are they overlaying a transparent second texture for the trim/stripes that gets shaded differently?

If it's just one texture I'd like to know how it's done.

If it's two different textures it seems like it's a waste of space. The second texture would be the same size as the first one but mostly transparent if you just wanted to lay it on top of the first one. Or are they just carefully positioning a second, smaller texture so that it aligns properly with the first one?

\$\endgroup\$

2 Answers 2

1
\$\begingroup\$

There are a number of possible approaches.

It can be done with a single texture. Options include creating a texture for that specific car/player based on the source images at runtime, or if it's a relatively solid color, they might instead map a primary color to red, a secondary color to green, and then remap those colors in a pixel shader. Alternatively they might pack that information into an alpha channel, for example mapping opposite sides of 0.5 to different tints, while still handling non-solidly colored objects with the remaining RGB channels. Pixel shaders would be doing the magic in this case.

Multiple textures are also possible -- it's already common to have diffuse, specular, and normal map textures all on the same object. Both approaches -- a large transparent fourth texture on top of the others and lining up with them, or a decal texture separately positioned on the mesh from the others, are viable. In the latter case it'll likely share the same geometry, just with different UV coordinates, and if drawn as a separate draw call / pass, it will likely also not include any geometry it isn't applied to.

tl;dr: Yes, those are all options, which one a given game uses will likely be up to their tools and workflow, their standards, or even simple artist preference.

edit: Here's a link on how EVE Online has their textures set up:, if you want to dig into a specific system http://community.eveonline.com/devblog.asp?a=blog&bid=732

\$\endgroup\$
6
  • \$\begingroup\$ Thanks for the response and the link, very helpful! I want to see if I understand you correctly about the mapping opposite sides of alpha to 0.5. The part of the texture to tint as the primary color could all be under 0.5. The secondary part would all have alpha over 0.5. Then to calculate the actual alpha for that part of the texture we would just multiply that half by two and offset it appropriately? \$\endgroup\$ Dec 9, 2012 at 17:19
  • \$\begingroup\$ Also the Eve link said that just changing the color in the shader led to a "washed out" look. Is this common? Is it a bad idea to use shaders to generate what appear to be different colored textures? It sounds like the Eve team ended up generated a new texture for each faction, but it seems like it would be pretty tedious to generate a bunch of different textures for each possible color we want to show in our game. \$\endgroup\$ Dec 9, 2012 at 17:21
  • \$\begingroup\$ What I'm imagining is a continuous color tint, with 'no tint' in the middle. So you'd have: 0.0 = 100% primary tint, 0.25 = 50% primary tint, 0.5 = no tint, 0.75 = 50% secondary tint, 1.00 = 100% secondary tint. Of course, this doesn't let you color a pixel with both tints simultaniously. \$\endgroup\$ Dec 10, 2012 at 3:02
  • \$\begingroup\$ As for the washed out look, I'm guessing it's referring to linear color remixing leading to duller results. A visualization of a similar problem can be found here as an art tutorial: androidarts.com/art_tut.htm#hues Similarly, TF2 uses a gradiant texture to make lighting more colorful: valvesoftware.com/publications/2007/… . Generating different textures for each possible color is indeed unimaginably tedious: you're more likely to create a few swaths of color and then blend programatically between them for intermediate colors. \$\endgroup\$ Dec 10, 2012 at 3:10
  • \$\begingroup\$ Thanks for the links and comments. I have another somewhat-related question I suppose. When textures are generated with different data in the red, green, or blue channel of the texture, how is the real color of the texture determined? Or is the color completely disregarded at that point and only generated from some kind of shader? \$\endgroup\$ Dec 11, 2012 at 4:23
1
\$\begingroup\$

First I think it's important to hammer down some terminology. When geometry is rendered with a texture, the texture is not "shaded." Shading the process of coloring the geometry. The texture is used in the shading calculations. With that in mind, I can get to the core of your question.

It depends on how the shader is written. For an asset that has customizable color, the base color can be passed in as the vertex color, and then blended with the texture lookup to derive the final color of the pixel. This is also the cheapest way of accomplishing what you're asking about, since it then doesn't require extra texture memory, and only costs a little more data to be sent to the GPU. Certain parts of the car can be shaded using different materials (if you consider a material to be the combination of several textures and a shader program). Of course, this requires that the car be made of several separate meshes, which may not be ideal.

For a game as large and graphically intense as Saints Row, the car likely has several other textures associated with it, such as diffuse maps, normal maps, light maps, etc. All of these are blended together using different techniques to compute the final look of the surface.

That "using different techniques" part is what brings me back to how I began my question: it all depends on how the shader is written, and how the model is created.

One other possibility is that there is a texture associated with a car which would be called an alpha map. The lookup values in this map can be used such that the fragment of the car is shaded with the primary color if the alpha is 0, and the trim color is used if the alpha is 1. Such a computation might look like this:

float alpha = textureLookup(alphaMap, fragmentCoords).a;
vec4 primaryColor = vertexColor * (1.0 - alpha);
vec4 trimColor = vertexColor * (alpha);
FragColor = primaryColor + trimColor;

This is a bit of a crude GLSL-style example, but I think it demonstrates what I'm describing. Assuming it's feasible to incur the extra texture memory cost to store the alpha map, then this method can be useful.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .