Best way to handle recolor

Godot Version

4.3

I have some high resolution sprites that I need to change the color of. I need to change the color of different parts of the sprite separately. What is the best way to do this?

Premake all the sprites colored as desired and store multiple versions? (this seems like a waste of time)

Create a sprite in multiple layers based on which parts are colored together, export each layer individually, make node have multiple sprites that make up the entire image, then modulate each sprite individually? (this seems like a waste of space)

Create a shader that uses seperate black and white masking textures to determine which parts to recolor? (this seems like a waste of cycles)

Some other method I’m not thinking of?

What is the most performant way to do this, the way that requires the least amount of files or will take up the least amount of space, the best way?

Depending on how and what you want to recolor I’m sure you could make a shader that takes single texture to specify up to 4 different colors with mixing or 4 billion different colors without mixing. And I believe this is the fastest and smallest option.

Oh are you saying, use a single mask texture to determine all of the areas. I didn’t think of that, I assumed using black and white texture would save the most space, but if I add additional colors, I guess each color could be its own mask

So I wrote a shader to do just that, it works great in the editor, but breaks immediately because of the imprecision of floating point values. I added an epsilon value, but couldn’t get it to work at runtime.

So I took a break from that and wrote a script to do the same thing using modulation.

Which one of these would be more performant?

If you only have one color to change then modulation is very slightly better, it’s still a shader, but doing one color multiply instead of (based on your description) a branch and a mix. Both of these are extremely performant. Shaders are very fast, and on a dedicated chip

I decided to go with the shader. Turns out the reason it wasn’t working was because it was being overwritten by another shader. lol

I have 4 different parts of the sprite that need to be colored separately. So now my workflow is create a sprite, then create a greyscale mask for that sprite. Then I can get the different color shades in the mask and adjust colors, brightness, contract, gamma, hue, ect. just for each masked part of the existing sprite. It works great.

the sprite is 6mb and the mask is only 400k as greyscale. I’m wondering how much I can actually get away with when it comes to save quality of the mask. I could get it to under 100k, but I think there might be artifacting which will affect the shader.

How many of those sprites will you have on screen? How many unique materials? Is this something important in your game (character, boss fight), or is this something secondary? If it’s something important and you don’t have too many on screen, i wouldn’t stress about it.

I would say, maybe 10, maximum 20 of the very high resolution ones on screen. I plan to use the shader on almost every object though. Most of them are small low res sprites though.

I would say no more than a few hundred objects using the same shader. And I would say the majority of the smaller low res ones would be using the same material.

So it would be 50 unique materials, 300 objects max.

1 Like