Recolor sprites on the fly

I want to replace specific colors in Sprite. Example found in google:

It’s from here http://gmc.yoyogames.com/index.php?showtopic=589348
And this shader for gm engine https://github.com/rafaelcp/Super-Mega-Engine/blob/master/shaders/shColorReplaceBlend.shader

How same re-color can be done in cocos2d-x?

Assuming you’ve already go it working with the shader you gave remapping 1 color set, then I can think of two ways

Opt 1. Use same shader, with Array instead.
Use a vec4[] array uniform instead of float in your shader with const size vec4 colorsIn[12] and vec4 colorsOut[12]. Then just fill out all 11 colors for in and out when applying shader uniform(s). Then in the shader just add a for loop (with i < 12 or #define constant - see cocos2d’s 3d lighting shader) to apply the color for each of the mappings instead of just the one.

Opt 2 Use a palette texture.
More versatile than Opt1, and no memory required like Opt3, but not as simple as Opt 1 if you only plan on a single set of colors to swap.
https://stackoverflow.com/questions/26132160/simulating-palette-swaps-with-opengl-shaders-in-libgdx .
https://stackoverflow.com/questions/14572745/palette-swap-using-fragment-shaders .
https://gamedev.stackexchange.com/questions/43294/creating-a-retro-style-palette-swapping-effect-in-opengl .

Heh, I don’t know how to use it. I don’t know openGL or shaders at all. I just can use code, like it was here for example: Blur at pause works very slow

Links you provide looks like what I need, but I don’t know how to use it and write some shader, that why I’m asking for help :slight_smile:

Image from link you gave looks like what I need:

And ideally is it possible to implement changing of color gradually? Or I just need to interpolate color in to out, when changing it…

Overall, I have 7 colors palette and a lot of sprite on the scene. Imagine something like different variations of pixel_guy.png and up to 50 Sprites on the scene, which I want to change color of… gradually from one color to another.

1 Like

Well you’ll probably have to learn how to write a shader. To apply one to a sprite is fairly straight-forward. You’ll have to figure out which uniforms you want to set globally for the shader. If you need to pass in values per sprite or vertex you’ll want to look into either using attributes. You can use the pre-existing ones if you need: a_position, a_color, a_texCoord.

// sprite - a sprite you want to apply shader 
std::string kShaderFrag = "MyShader.fsh";
std::string kShaderVert = "MyShader.vsh";

// use the cache so we don't create new if we call this code multiple times
auto glCache = GLProgramCache::getInstance();
auto glprog = glCache->getGLProgram(kShaderKey);
if(! glprog)
{
    // create and cache
    glprog = GLProgram::createWithFilenames(kShaderVert, kShaderFrag);
    glCache->addGLProgram(glprog, kShaderKey);
    CHECK_GL_ERROR_DEBUG();
}

if(glprog) 
{
    // attach and use
    Texture2D* texture = sprite->getTexture(); // or get from wherever
    auto glstate = GLProgramState::getOrCreateWithGLProgram(glprog);
    glstate->setUniformTexture2D("u_paletteTexture", texture);
    sprite->setGLProgramState(glstate);
    CHECK_GL_ERROR_DEBUG();
}

Probably some day I will, and giving me full example would really help to understand that.
Now I just want to have all code example. Can you help like before with blur Joseph39 helped? It’s more clear for me when I have just a code which works. Now you just want to teach me how to use it… well I’m noob and nothing works I don’t understand what to fix and how.
Moreover, I need to implement this in my game for a whole bunch of sprites in real time, I hope there will be not lags of drop FPS…

There’s a handful of examples if you search “custom shader”, but mine is here:
https://github.com/stevetranby/cocos2dx-shader-cookbook .
http://discuss.cocos2d-x.org/t/shader-positioning/26853/4?u=stevetranby .
http://discuss.cocos2d-x.org/t/solved-passing-a-variable-to-a-shader/27141/14?u=stevetranby .

Another example.
http://discuss.cocos2d-x.org/t/learning-and-using-opengl-shader/26551/8?u=stevetranby .

Thanks, probably someday… I will start learn.
Can you please give some full code example like was in sutiation with pause at blur… for noobs like me?
Also, how to better update color at runtime in update for list of sprites? I believe better I need to create some sub class of sprite, and just executed something like colorSprite->updateColors(…); ?

Well I just gave you like 10+ full examples in the cookbook. Also the other links are two examples with all the shader-specific code, and one about uniforms. Good luck.

If you aren’t going to figure it out or learn then just create a bunch of sprites and limit the color options. Most modern devices have plenty of texture memory for a handful of color combos.

Or create a grayscale monotone version and then just set the color, it’s not as neat, but allows for “infinite” colors. You could even layer multiple grayscale sprites to apply more than one color.

Save texture memory by shrinking the source image and setScale(2).

Many options. Just depends on how much time/study/etc you want to invest based on cost/benefit of your desired outputs.

So this will consume a lot or memory? And for example using this vertex and fragment shader compare to this will give different results? Speed? Which better to use?

Sure, not neat and I’m creating quality games, so not an option at all. Currently all these color just stored in “duplicated” textures, just recolored in Illustrator.

Ideally I just want to pick some working shader and use it, like some people just use my SpriteBuilderX, on which I’m working. So they just take my source code and use it. I want the same. I want just some class like ColorSprite and method in it which just takes an array of RGB colors(in\out) and replace them in the sprite. :slight_smile:

a little upd(looks really good for me! ) : https://gamedevelopment.tutsplus.com/tutorials/how-to-use-a-shader-to-dynamically-swap-a-sprites-colors--cms-25129 how to use it with cocos2d-x ?

take a look at this

68747470733a2f2f7261772e6769746875622e636f6d2f616c65783331342f626c6f625f66696c65732f6d61737465722f696d616765732f4343537072697465576974684875654578616d706c652e706e67

Yea, I saw that before, but I have a palette of 11 colors which I need to replace vs other 11 colors. Is it works with list of colors? Also, it’s not for cocos2d-x and I have no idea how to update it or fix… just to try.

I’m supportive of giving away code, and it’s great you’re working on SpriteBuilderX, but no one should expect any code.

I’ll assume you were just hoping someone knew of code that was already posted that does what you want. It appears there’s not anything that does that exactly.

Shaders are fundamental, though. You should really learn them.

Godspeed on this issue.

I just thought for someone familiar with shaders will be very easy to help me. Later I’ve found this tutorial and probably it can help some smart guys to help me :slight_smile: Hmm?

Like this? https://gist.github.com/KAMIKAZEUA/0e0d9f4fcb25cb2f8361a317c7ccd8c6
And how to use it…?

That looks like it should work. Just copy the default Sprite shader ‘ccPositionTextureColor_noMVP’ or look at the example I posted to figure out what the default position, texture, and color variables are named.
https://gist.github.com/stevetranby/95231e6122aaf97179b3 .

Don’t figure out copy from where?

Ehhm, but there are :

prog = GLProgram::createWithFilenames("res/" + kShaderKey + ".vert",
                                          "res/" + kShaderKey + ".frag");

But I don’t have like vert and frag, right?
And next question will be how to pass colorIn array of RGB colors? Also how to update it in real time for my Sprite? It’s like problem almost solved but you want that I’ve learned something :sunny: yes, I want! But can you please give some code snippet specially for that shader from gist? THank you in advance!>

Search the Cocos2d-x code base.

See my post above: http://discuss.cocos2d-x.org/t/recolor-sprites-on-the-fly/38713/4?u=stevetranby

Search cocos2d-x codebase for GLProgramState class and its ‘setUniformXXXXXX’ methods. You’ll find one that pertains to arrays.

You can’t just provide fully working example code snippet? like here - How to implement this Vignet shader for cocos2dx 3.15?

@Joseph39 :joy: ? It’s only you one who can really help!

When I decide to take the time to work on an exact version I will. I’ve been meaning to implement the “Option 2” for a while now so I’ll probably add it to the todo list and will probably work on it maybe 2-3 from now. Sorry, it’s on, but not near the top of my current task list (which is heavy pending iOS 11 launch) and while I’m taking way more time posting replies to this than I should I assumed at the beginning that my links would be enough, tbh