Adventures in Unity – 2.5a Palette Shift

Official_unity_logo

 

For the C64 version of Bounder, the text colour of the start and end tiles bounces between black and white.

Start-2a2

Goal-2a2

 

I wanted to replicate this in my version – But I wasn’t sure how.

I eventually worked through six potential implementations;

  1. Colour Lerp.
  2. HBSC
  3. Palette Swap
  4. Quad Cut-Out
  5. Shader
  6. Texture Sheet Animation.

 

This post covers the first three attempts;

  • Colour Lerp.
  • HBSC
  • Palette Swap

 

The next post will expand on the final three.

  • Quad Cut-Out
  • Shader
  • Texture Sheet Animation.

 


 

1. Colour Lerp

The most straight forward approach; it uses the built in method color.lerp alongside Mathf.PingPong to bounce colours between black & white – The result is applied to the start/end textures.

How this works…

The Color lerpedColor holds the colour to be displayed.

public Color lerpedColor = Color.white;

Every loop, color.lerp is used to calculate the current colour – Mathf.PingPong ‘animates’ the colour – bouncing it between (in this case) black & white.

lerpedColor = Color.Lerp(Color.white, Color.black, Mathf.PingPong(Time.time, 1));
GetComponent<Renderer>().material.color = lerpedColor;

The end results look great; but unsurprisingly the entire texture changes colour, not just the text.

 

ColourLerp-1b

 


 

2. HBSC

Using the HSBColor class, provided in the Unity3D wiki.

The wiki description explains that HSBColor ‘provides a Hue/Saturation/Brightness/Alpha color model in addition to Unity’s built in Red/Green/Blue/Alpha colors. It is useful for interpolating between colors in a more pleasing fashion

Rather than following their usage/setup instructions, I instead just stripped the [System.Serializable] tag & used the code like a standard class.

How this works…

Define a global HSBColor object.

public float time = 2.0f;
private HSBColor hsbc;

Which is initialized in the start method.

hsbc = HSBColor.FromColor(color);

Then, every loop the next colour to display is calculated (I think it rotates through six different colours)

hsbc.h = (hsbc.h + Time.deltaTime / time) % 1.0f;
GetComponent().material.color = HSBColor.ToColor(hsbc);

The result may give you a headache;

HSBC-1a

 


 

3. Palette Swap

This reuses the Palette Swap code I wrote for the Spectrum tiles – I really like the effect – (Though I’d need to figure out why some white pixels have turned yellow when being displayed). I’d expected a huge performance hit with this method, but when tested, the game ran at a good pace.

How this works…

Each tile prefab has a material component attached. Each material component has a texture attached. This is the texture used when drawing the tile to screen.

Since the intention is to change the colours of the materials texture, the script keeps a master copy that is unaffected by the paletteSwap code – paletteSwap code uses this master copy as a reference every loop/colour update.

(Rather than using a reference textures; the script could instead, store a copy of the last colour applied and pass that to the paletteSwap code to change every loop – Unfortunately the banner letters lerp between black and white – & the texture has some black pixels in place which may accidently get caught up in the animation).

 

First the script defines a global texture to be used to hold the master/base texture;

Texture2D paletteSwapTexture;

A copy of this texture is assigned to paletteSwapTexture – (I’m guessing it’s a copy and not a reference, since changing the colours in rend.material.maintexture has no effect on the contents of paletteSwapTexture)

rend = GetComponent();
paletteSwapTexture = (Texture2D) rend.material.mainTexture;

The ‘toColour‘ colour array is defined – This is used to identify which colour in the texture to look for (index 0) & what colour to change it to (index 1).

Color[] toColour = new Color[2] { Color.white, Color.white };

Then, every loop ‘Colour Lerp’ (& Mathf.PingPong) calculates the next colour to display – This is then passed to the PaletteSwap method.

toColour[1] = Color.Lerp(Color.white, Color.black, Mathf.PingPong(Time.time, 1));
Renderer rend = GetComponent();
rend.material.mainTexture = PaletteSwap(toColour, paletteSwapTexture);

Which swaps the colours and returns a new Start/Goal tile texture;

Texture PaletteSwap(Color[] toColours, Texture2D inTexture)
{

     Texture2D source = inTexture;
     Texture2D destination = new Texture2D(source.width, source.height);

     //---

     Color[] pixels = source.GetPixels(0, 0, source.width, source.height);

     int pixelsLength = pixels.Length;
     for (int counter = 0; counter < pixelsLength; counter++)      {           //if (pixels[counter] == toColours[0])           if (pixels[counter].r >= 0.98 && pixels[counter].g >= 0.99)
          pixels[counter] = toColours[1];

     }

     destination.SetPixels(0, 0, destination.width, destination.height, pixels);
     destination.Apply();

     //---

     return (Texture)destination;

     //---

}

Which ultimatly looks like this – Nice effect, pain in the arse yellow pixels;

PaletteSwap-1b

 


 

Next post: 2.5a Palette Shift

Last post: 2.4 Edge Padding

Contents page.

 


 

Advertisements

1 thought on “Adventures in Unity – 2.5a Palette Shift”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s