About Store Forum Documentation Contact



Post Reply 
Recolorable textures
Author Message
SamNainocard Offline
Member

Post: #1
Recolorable textures
I'm wondering how do I make recolorable textures in the game? I'm thinking about create additional Mesh and Material and link MeshPtr and MaterialPtr to them, is this the right way?

Also, in order to make a fully customizable color (can choose any color) which color I should aim for when making a base texture, I think it's White or Greyscale, right?
01-26-2016 04:39 PM
Find all posts by this user Quote this message in a reply
georgatos7 Offline
Member

Post: #2
RE: Recolorable textures
Hey can you post a screenshot of the model you want to achieve this effect on? For now i can only guess two different cases that you might need to consider.

If your model can afford having the parts that need a different color as different geometry parts then you can just assign different materials to each part and then access and change the color values (rgb) of each material. In this case your base textures need to be completely desaturated (greyscale) versions of the originals.

But if those color varying parts don't share boundaries with the geometry then you'll have to make your own shader that will probably utilize texture masks (as in 4 greyscale masks per texture, 1 per channel) or a more sophisticated hue shifting technique.
(This post was last modified: 01-27-2016 02:05 AM by georgatos7.)
01-26-2016 10:12 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #3
RE: Recolorable textures
You can make a custom shader, that will work faster when you change the color frequently, but if you just want to create the texture once and use it for a long time, then it's better to just call CreateBaseTextures with manually modified textures on the CPU.
01-27-2016 07:30 AM
Find all posts by this user Quote this message in a reply
SamNainocard Offline
Member

Post: #4
RE: Recolorable textures
Sorry, I'm not good with these techniques stuff, but I'll try to explain what I'm doing more. smile

I want to make, let's say, an object with recolorable channel parts, like recoloring furniture in Sims 3, or choosing RGB for character's hair. But I don't know how to achieve this, so I think that I need a base texture that can be recolor to any color and a way to apply custom to that texture per objects. (because changing material will change all object that uses material).

From what I read, I should make a greyscale version for texture part (let's say, hair texture) to be recolorable in the game, then I should apply a custom shader that draws a custom color on it?
01-27-2016 06:10 PM
Find all posts by this user Quote this message in a reply
Esenthel Offline
Administrator

Post: #5
RE: Recolorable textures
You don't need to have a greyscale texture, it's up to you how to make the colorization part.
There are many ways to do that.
Having original source color texture you have RGB values, you can modify them up to you (like multiply, add by some constant values: RGB*mul+add).
You can adjust the hue/saturation/brightness using Color* functions in the Color.h header.
If you want to apply those changes only in some certain parts of the texture, you can make a mask texture, and then apply the changes based on mask color intensities.
For example, have a base image like this:
   
With colorization mask like this:
   

You can make texture variations like this:


Attached File(s) Image(s)
       
01-28-2016 05:05 AM
Find all posts by this user Quote this message in a reply
SamNainocard Offline
Member

Post: #6
RE: Recolorable textures
Interesting, but how do I apply it in-game? Unless custom shader is really needed which is currently out of my field. smile

So let's say I used mesh variations way, by creating additional variations in the game then changing Material.color, with this I able to change color tint for whole texture for each character using same mesh/material, but I don't know how to do the colorization mask for changing specified texture part.

I'm thinking about iterate through all colorization mask pixel, checking for color code and change the base_0? Are these performance intense by the way?
Code:
From Dynamic Image tutorial
FREPD(y, mask.h())
FREPD(x, mask.w())
{
   if(mask.color(x,y)==RED)base_0.color(x, y, RED_PART_COLOR_REPLACE);
}
01-28-2016 10:55 AM
Find all posts by this user Quote this message in a reply
georgatos7 Offline
Member

Post: #7
RE: Recolorable textures
As an example since within a shader it is better to avoid conditionals if you want to maintain good performance, especially with older gpus, this is what i would probably try first.

Again this is a simple cpu-equivalent of the method i would try first within a shader. If you end up doing this on the cpu (which method-wise is not so limiting), feel free to optimize/adjust this in any way you want or even use a completely different method.

Code:
Image image;

void InitPre()
{
   EE_INIT();
}

Bool Init()
{
   //The color you want to apply to the each channel mask.
   Vec r_channel_color = Vec(0.4, 0.8, 0.4);
   Vec g_channel_color = Vec(0.8, 0.2, 0.2);
   Vec b_channel_color = Vec(0.4, 0.4, 0.8);
   Vec a_channel_color = Vec(0.4, 0.7, 0.7);
  
   ImagePtr orig_ptr = Original_UID; //Original texture
   ImagePtr mask_ptr = Mask_UID;  //One Mask*Brightness per channel

   image.create2D(128, 128, IMAGE_B8G8R8A8, 1); // create 128X128 image, B8G8R8A8 type, 1 mipmap
  
   if(image.lock() && orig_ptr->lockRead() && mask_ptr->lockRead())
   {
      FREPD(y, image.h()) // iterate through all y's
      FREPD(x, image.w()) // iterate through all x's
      {
         Vec4 orig_color  = orig_ptr->colorF(x, y);
         Vec4 mask_color  = mask_ptr->colorF(x, y);
         Vec4 final_color = Vec4(mask_color.x * r_channel_color +
                                 mask_color.y * g_channel_color +
                                 mask_color.z * b_channel_color +
                                 mask_color.w * a_channel_color , 1.0) + orig_color;
        
         image.colorF(x, y, final_color); // set image color at (x,y) coordinates
      }
      image.unlock();
      mask_ptr->unlock();
      orig_ptr->unlock();
   }
   return true;
}

void Shut()
{
}

Bool Update()
{
   if(Kb.bp(KB_ESC))return false;
   return true;
}

void Draw()
{
   D.clear(BLACK);

   image.draw(Rect(-0.5, -0.5, 0.5, 0.5));
}

Also i bet that using a hue shifting method would probably achieve better results, since it would preserve more color info in comparison with the method above.
This is of course just an example that came into mind and you should probably get more opinions on the matter.

The textures i used:
Original Texture
Mask
(This post was last modified: 01-28-2016 09:41 PM by georgatos7.)
01-28-2016 09:01 PM
Find all posts by this user Quote this message in a reply
Post Reply