Search Unity

hue shift a texture

Discussion in 'Editor & General Support' started by Chowderman, Feb 2, 2010.

  1. Chowderman

    Chowderman

    Joined:
    May 21, 2009
    Posts:
    92
    Hey guys,

    Im trying to figure out how to change the hue on a texture. I know I can tint the texture by clicking the colour box above the texture in the material, but this only adds a layer of tint over the texture. How can I achieve a true hue shift, as if I went into Photoshop and used the Hue slider?

    The ability to change this during the game (picking different colours for suits, cars, etc) is also very important. Any ideas?
     
  2. magwo

    magwo

    Joined:
    May 20, 2009
    Posts:
    402
    This would typically require a custom shader, as far as I know. It could then expose this hue parameter to the material interface.

    However I'm not sure if you can efficiently write a pixel shader that modifies Hue in realtime, from RGBA texels.
     
  3. J_P_

    J_P_

    Joined:
    Jan 9, 2010
    Posts:
    1,027
  4. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    If you need to alter the texture data directly, there's an HSB colour class script on the Unify wiki.
     
  5. Chowderman

    Chowderman

    Joined:
    May 21, 2009
    Posts:
    92
    thanks for the heads up andeeee! However as a non-coder I have no idea how to use this script. I added them in my Project/Assets/Plugins folder (a folder I had to create manually) but I'm not sure how to use them.

    Thanks for your help so far, i hope this all works!
     
  6. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    The Texture2D has methods called GetPixels and SetPixels that let you modify the pixel data as an array of colour values. Rotating the hue of an image is a matter of reading in the existing pixel colour (of type Color), converting it to an HSB colour, altering the hue angle and then converting back to the Color type again:-
    Code (csharp):
    1. var rotAngle: float;
    2.  
    3.  
    4. private var newTex: Texture2D;
    5. private var origTex: Texture2D;
    6.  
    7.  
    8. function Start() {
    9.     origTex = renderer.material.mainTexture;
    10.     newTex = new Texture2D(origTex.width, origTex.height);
    11. }
    12.  
    13.  
    14. function Update () {
    15.     HueRot(origTex, newTex, rotAngle);
    16.     renderer.material.mainTexture = newTex;
    17. }
    18.  
    19.  
    20. function HueRot(inTex: Texture2D, outTex: Texture2D, angle: float) {
    21.     var pix: Color[] = inTex.GetPixels(0, 0, inTex.width, inTex.height);
    22.    
    23.    
    24.     for (i = 0; i < pix.Length; i++) {
    25.         var hsb: HSBColor = HSBColor.FromColor(pix[i]);
    26.         hsb.h = hsb.h + angle;
    27.         pix[i] = hsb.ToColor();
    28.        
    29.     }
    30.    
    31.     outTex.SetPixels(0, 0, inTex.width, inTex.height, pix);
    32.     outTex.Apply();
    33. }
     
  7. opticfibre

    opticfibre

    Joined:
    Apr 6, 2010
    Posts:
    26
    Will this code apply to the S B components just by modifying the hsb.h = hsb.h + angle or is there a different type of code for S B.

    many thanks :)
     
  8. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    The H (hue) component is a cyclic value from 0º to 360º which represents the position on the standard colour wheel, where red is at the 0º position. The S (saturation) component is a value from 0 to 1 the represents the vividness of the colour, where 1 means the pure colour and 0 means the equivalent grey level. B (brightness) is a also a value from 0 to 1 where 1 is the maximally bright colour and 0 is black. HSB is a rather awkward colour model to use if you need accurate transitions and consistent brightness, but it is OK for some simple transitions especially if they only modify a single component.
     
  9. AaronC

    AaronC

    Joined:
    Mar 6, 2006
    Posts:
    3,552
    Hi Andeee This script doesnt appear to do anything. Is it gestural or just not working as planned? Maybe I need to have the texture in some specific format? I changed materials to sharedMaterials and the texture import settings are set to "readable" I also used @script ExecuteInEditMode to see it before playing.

    Cheers
    Aaron
     
  10. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    This is what I get for not checking the HSBColor script before I posted...

    It seems that it does work but the hue component is actually going from 0 to 1 in this case. This is an equally valid way to represent the hue (ie, a fraction of a circle rather than an angle). The hue shift does work in the 0..1 range, at least for me.
     
  11. AaronC

    AaronC

    Joined:
    Mar 6, 2006
    Posts:
    3,552
    so by shifting rotAngle between 0 and 1 you observe a color shift?
     
  12. opticfibre

    opticfibre

    Joined:
    Apr 6, 2010
    Posts:
    26
    Yes, i figured out the 0..1 for hue shifting, but i get an odd effect with saturation.

    Turning the saturation down causes the image to get really bright, not really an exact representation of grey, of course i could be doing something wrong, but it works enough for my purposes.
     
  13. andeeeee

    andeeeee

    Joined:
    Jul 19, 2005
    Posts:
    8,768
    The brightness value of the HSB model is a bit misleading. It is actually the maximum of the three RGB levels, but this doesn't correspond at all well to the perceived luminance of the colour. The similar-sounding HSL model is actually conceptually different and does a better job of getting the luminance right for a given shade regardless of saturation. There is a script that implements an HSL class in this thread.
     
  14. Arkhivrag

    Arkhivrag

    Joined:
    Apr 25, 2012
    Posts:
    2,978
    Last edited: Mar 3, 2022
  15. Blobstermedia

    Blobstermedia

    Joined:
    Dec 21, 2021
    Posts:
    4
    and to do this in c# is....?
     
  16. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,674
  17. allpublic

    allpublic

    Joined:
    Nov 10, 2020
    Posts:
    13
    I found this Shader example for this challenge.
    https://github.com/greggman/hsva-unity
    But not tried yet.
    You have to be aware, if you change the picture itself with get and setPixel, its very slow and it holds the picture in RAM as well.
    Shader will be more efficent I guess.
    Still searching for an more easy way.

    (This thread is very on top in google to this challenge)