2

I'm making a 2D game, where some graphics assets must be used with 2 user-selected team colors. What workflow do game developers use, so that the graphics artist only need to draw each asset once, and the code allows the end-user to choose two team colors, that the asset will be rendered in.

Notice, that each color may be draw with antialias to the background (transparent), or to another color.

Rendering is done with OpenGL

same graphics asset, shown with two different team colors

XPlatformer
  • 1,148
  • 8
  • 18
  • notice: I'm not a graphics artist myself. – XPlatformer Mar 17 '21 at 15:09
  • 1
    What did you try so far? Where is your code? Please read [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) and [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask). – Rabbid76 Aug 19 '21 at 15:01
  • Related [Recolor sprites on the fly](https://stackoverflow.com/questions/45822889/recolor-sprites-on-the-fly) and [Colorize sprites from grayscale to color](https://stackoverflow.com/questions/45962006/colorize-sprites-from-grayscale-to-color) – Rabbid76 Aug 20 '21 at 08:14

2 Answers2

0

If you only want solid colors, you can pass in colors alongside each vertex, pass the color from the vertex to fragment shader, then simply setting the fragment color in the fragment shader to that value.

If you want to use textures that can be colored or some other more complex scenario, you need to use mix with the vertex color and the texture color.

0

The most common/simple approaches would be:

  1. Use a shader and a second alpha channel, apply the team colour (in varying amounts based on alpha channel) at draw time. This extra channel is wasteful however, and depending on your use case shaders may not be appropriate
  2. There presumedly aren't thousands of teams, so you could just precalculate sprite sheets per-team using the same method as #1 but - eg. - at application/level startup. The memory overhead for this is negligible, and the performance impact is nil

NB: In your source sprite you likely want a neutral colour wherever team colours will be so that the blending works correctly.

Example of #1 / #2 in shadertoy: https://www.shadertoy.com/view/ssc3WM

Notes re. example:

  1. This example generates a "team alpha" in the Buffer A tab, but this could just as easily be authored manually.
  2. I added a colour cycle just to more clearly demonstrate that the team colour is dynamic

Whether you choose to do it in realtime, or precalculated - the method is the same:

// Team color (eg. RED)
vec3 teamColor = vec3(1.0, 0., 0.);

// Pixel color of the original sprite
vec3 spriteColor = texture(/* your sprite texture */, uv).xyz;
// Get just the red component of our black and white mask input
float teamAlpha = texture(/* your team mask texture */, uv).x;

// blend the original sprite with the team colour, based on the team alpha 
// and (optional) "intensity" of 0..1 (allowing you to turn down the blend)
vec3 col = mix(spriteColor, teamColor, teamAlpha * teamColorIntensity);

EDIT: adding screenshots from the shadertoy example since it was questioned whether blending and antialiasing works (it does).

showing partial blending the team mask used

Note that the team mask has varying alpha, so is doing blending - shadertoy doesn't allow uploading images so we're stuck with nyan cat

Here's the same shadertoy with linear interpolation active, note that the blended crumbs' edges and body receive varying amounts of the "team" colour

soft image to show blending works smoothly soft team mask


Visual example in case the shadertoy eventually vanishes:

Inputs:

base sprite team colour mask

Result:

result

(*forgive my cruddy pixel art, look at the Shadertoy example for a better demo)

pentaphobe
  • 337
  • 1
  • 4
  • 9
  • How does that answer the question? How does this solve the anti-aliasing and blending problem? In your answer all the pixels have a uniform color, there is no blending between the colors. – Rabbid76 Aug 26 '21 at 06:28
  • It does solve blending, click the shadertoy link - it uses greyscale values. The other images were just to clarify what was happening – pentaphobe Aug 27 '21 at 20:09
  • @Rabbid76 I added some screenshots of the shadertoy to demonstrate that this does indeed support blended / antialiased pixels – pentaphobe Aug 27 '21 at 20:19