• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!

Colour Gradient Function!

Status
Not open for further replies.
I scripted a really fast, really & easy to use colour gradient function after finding a colour gradient function on SC2Mapster that was absolutely massive, really slow, and didn't work half the time. I wanted to share it with you guys so you can do colour gradients for meters, text, etc. easily. The function itself is 48 lines long, in GUI the custom script part is 10 lines long. To call it you'd do gf_ColorGradient(Start Colour, End Colour, Percent Fade).

Percent Fade being how far you fade from your start colour into your end colour. This is a value between 0.0 and 1.0.

Just look at the examples of use I include with the map.

Here's the script:

JASS:
//==================================================================================================
// 
// Generated Map Script
// 
// Name:   Colour Gradient Function
// Author: BlueBerryWizard
// 
//==================================================================================================
include "TriggerLibs/NativeLib"
include "TriggerLibs/NativeLib"
include "TriggerLibs/NativeLib"

//--------------------------------------------------------------------------------------------------
// Library Initialization
//--------------------------------------------------------------------------------------------------
void InitLibs () {
    libNtve_InitLib();
    libNtve_InitLib();
    libNtve_InitLib();
}

//--------------------------------------------------------------------------------------------------
// Global Function Declarations
//--------------------------------------------------------------------------------------------------
color gf_ColorGradient (color lp_colorA, color lp_colorB, fixed lp_percentFade);

//--------------------------------------------------------------------------------------------------
// Trigger Variables
//--------------------------------------------------------------------------------------------------
trigger gt_Test;
trigger gt_Test2;

//--------------------------------------------------------------------------------------------------
// Global Functions
//--------------------------------------------------------------------------------------------------
color gf_ColorGradient (color lp_colorA, color lp_colorB, fixed lp_percentFade) {
    int init_i;

    // Variable Declarations
    fixed[3] lv_red;
    fixed[3] lv_green;
    fixed[3] lv_blue;

    // Variable Initialization
    init_i = 0;
    while (init_i <= 2) {
        lv_red[init_i] = 0.0;
        init_i = init_i + 1;
    }
    init_i = 0;
    while (init_i <= 2) {
        lv_green[init_i] = 0.0;
        init_i = init_i + 1;
    }
    init_i = 0;
    while (init_i <= 2) {
        lv_blue[init_i] = 0.0;
        init_i = init_i + 1;
    }

    // Implementation
    lv_red[0] = (ColorGetComponent(lp_colorA, c_colorComponentRed) * 2.55);
    lv_green[0] = (ColorGetComponent(lp_colorA, c_colorComponentGreen) * 2.55);
    lv_blue[0] = (ColorGetComponent(lp_colorA, c_colorComponentBlue) * 2.55);
    
    lv_red[1] = (ColorGetComponent(lp_colorB, c_colorComponentRed) * 2.55);
    lv_green[1] = (ColorGetComponent(lp_colorB, c_colorComponentGreen) * 2.55);
    lv_blue[1] = (ColorGetComponent(lp_colorB, c_colorComponentBlue) * 2.55);
    
    lv_red[2] = lv_red[1] - lv_red[0];
    lv_green[2] = lv_green[1] - lv_green[0];
    lv_blue[2] = lv_blue[1] - lv_blue[0];
    
    lv_red[2] = (lv_red[2] * lp_percentFade) + lv_red[0];
    lv_green[2] = (lv_green[2] * lp_percentFade) + lv_green[0];
    lv_blue[2] = (lv_blue[2] * lp_percentFade) + lv_blue[0];
    
    return Color((lv_red[2]/255)*100, (lv_green[2]/255)*100, (lv_blue[2]/255)*100);
}

//--------------------------------------------------------------------------------------------------
// Trigger: Test
//--------------------------------------------------------------------------------------------------
bool gt_Test_Func (bool testConds, bool runActions) {
    // Variable Declarations
    fixed lv_r;
    const color lv_colourA = Color(0,66*100/255,100);
    const color lv_colourB = Color(229*100/255,91*100/255,176*100/255);
    text lv_text;

    // Variable Initialization
    lv_r = 0.0;
    lv_text = StringExternal("Param/Value/67BE9703");

    // Actions
    if (!runActions) {
        return true;
    }

    while(lv_r <= 1.0) {
        TriggerDebugOutput(1, TextWithColor(lv_text, gf_ColorGradient(lv_colourA, lv_colourB, lv_r)), true);
        lv_r += 0.05;
    }
    return true;
}

//--------------------------------------------------------------------------------------------------
void gt_Test_Init () {
    gt_Test = TriggerCreate("gt_Test_Func");
    TriggerAddEventMapInit(gt_Test);
}

//--------------------------------------------------------------------------------------------------
// Trigger: Test 2
//--------------------------------------------------------------------------------------------------
bool gt_Test2_Func (bool testConds, bool runActions) {
    // Variable Declarations
    int lv_i;
    string lv_s;
    text lv_t;
    const color lv_colourA = Color(20*100/255,134*100/255,107*100/255);
    const color lv_colourB = Color(100.00, 100.00, 0.00);
    const string lv_string = "BlueBerryWizard";
    int lv_length;

    // Variable Initialization
    lv_i = 0;
    lv_s = "";
    lv_t = null;
    lv_length = StringLength(lv_string);

    // Actions
    if (!runActions) {
        return true;
    }

    while(lv_i <= lv_length) {
        lv_s = StringSub(lv_string, lv_i, lv_i);
        lv_t += TextWithColor(StringToText(lv_s), gf_ColorGradient(lv_colourA, lv_colourB, (IntToFixed(lv_i) / IntToFixed(lv_length))));
        lv_i += 1;
    }
    TriggerDebugOutput(1, lv_t, true);
    return true;
}

//--------------------------------------------------------------------------------------------------
void gt_Test2_Init () {
    gt_Test2 = TriggerCreate("gt_Test2_Func");
    TriggerAddEventMapInit(gt_Test2);
}

//--------------------------------------------------------------------------------------------------
// Trigger Initialization
//--------------------------------------------------------------------------------------------------
void InitTriggers () {
    gt_Test_Init();
    gt_Test2_Init();
}

//--------------------------------------------------------------------------------------------------
// Map Initialization
//--------------------------------------------------------------------------------------------------
void InitMap () {
    InitLibs();
    InitTriggers();
}

& there's the map ↓

Not sure if this is the right place for this btw... if anyone knows where this is supposed to go, tell me pl0x?

Edit: Here's a pic of it in use ↓


Is this posted in the right section?
 

Attachments

  • Colour Gradient Function.SC2Map
    12.2 KB · Views: 57
  • Colour Gradient Example Pic.png
    Colour Gradient Example Pic.png
    62.9 KB · Views: 133
Last edited by a moderator:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
The function is not very efficient... Incorrect use of arrays, pointless itteration to set the locals to 0 and you do pointless maths (multiplying by 2.55 then some allmgihty complex division).

This is my equivilent of the "gf_ColorGradient" function you made.
Code:
//Takes 2 colors to use as samples and a fixed representing the distance between them (0 is at from and 1 is at to).
//Returns the resulting Interpolated color
//Note : ignores alpha
color ColorInterpolate (color from, color to, fixed percent) {
    fixed fromr = ColorGetComponent(from, c_colorComponentRed);
    fixed fromg = ColorGetComponent(from, c_colorComponentGreen);
    fixed fromb = ColorGetComponent(from, c_colorComponentBlue);
    return Color(((ColorGetComponent(to, c_colorComponentRed) - fromr) * percent) + fromr,
                 ((ColorGetComponent(to, c_colorComponentGreen) - fromg) * percent) + fromg,
                 ((ColorGetComponent(to, c_colorComponentBlue) - fromb) * percent) + fromb);
}
Firslty, cache the origan color components. Then create a new color using the desternation color and the percent via interpolation.

Do not think my code is perfect...
Possible improvements would be to reduce procedural coupling but making a ColorGetComponentRed function which takes just a colour and returns the fixed red component and repeating for each channel. Additionally it does not do alpha although colours do support it. You could also break the interpolation process into a separate function and call that many times instead of repeating the maths (another reduction in procedural coupling). Efficiency could be improved by skipping reference colors and instead using reference components (saves native calls).
 
Status
Not open for further replies.
Top