Exemple #1
0
 public Color[] BuildPaletteColors()
 {
     Color[] colors = new Color[colorsCount * shades];
     for (int i = 0, c = 0; c < colorsCount; c++)
     {
         for (int s = 0; s < shades; s++, i++)
         {
             float t = (s + 0.5f) / shades;
             t         = minBrightness + (maxBrightness - minBrightness) * t;
             colors[i] = ColorConversion.GetColorFromRGBSL(this.colors[c].r, this.colors[c].g, this.colors[c].b, saturation, t);
         }
     }
     return(colors);
 }
Exemple #2
0
        /// <summary>
        /// Returns the nearest color in the palette
        /// </summary>
        public Color GetNearestColor(Color[] palette, Color color, ColorMatchMode colorMatchMode, float threshold, ColorEntry[] colorOperations, bool enableColorAdjustments, ColorAdjustments colorAdjustments)
        {
            if (colorOperations != null && colorOperations.Length > 0)
            {
                HSLColor hsl = ColorConversion.GetHSLFromRGB(color.r, color.g, color.b);

                for (int k = 0; k < colorOperations.Length; k++)
                {
                    switch (colorMatchMode)
                    {
                    case ColorMatchMode.RGB: {
                        float dr = colorOperations[k].color.r < color.r ? color.r - colorOperations[k].color.r : colorOperations[k].color.r - color.r;
                        float dg = colorOperations[k].color.g < color.g ? color.g - colorOperations[k].color.g : colorOperations[k].color.g - color.g;
                        float db = colorOperations[k].color.b < color.b ? color.b - colorOperations[k].color.b : colorOperations[k].color.b - color.b;
                        if (dr <= threshold && dg <= threshold && db <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.Red: {
                        float dr = colorOperations[k].color.r < color.r ? color.r - colorOperations[k].color.r : colorOperations[k].color.r - color.r;
                        if (dr <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.Green: {
                        float dg = colorOperations[k].color.g < color.g ? color.g - colorOperations[k].color.g : colorOperations[k].color.g - color.g;
                        if (dg <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.Blue: {
                        float db = colorOperations[k].color.b < color.b ? color.b - colorOperations[k].color.b : colorOperations[k].color.b - color.b;
                        if (db <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.HSL: {
                        HSLColor hslOp = ColorConversion.GetHSLFromRGB(colorOperations[k].color.r, colorOperations[k].color.g, colorOperations[k].color.b);
                        float    dh    = hslOp.h < hsl.h ? hsl.h - hslOp.h : hslOp.h - hsl.h;
                        float    ds    = hslOp.s < hsl.s ? hsl.s - hslOp.s : hslOp.s - hsl.s;
                        float    dl    = hslOp.l < hsl.l ? hsl.l - hslOp.l : hslOp.l - hsl.l;
                        if (dh <= threshold && ds <= threshold && dl <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.Hue: {
                        float hue = ColorConversion.GetHue(colorOperations[k].color.r, colorOperations[k].color.g, colorOperations[k].color.b);
                        float dh  = hue < hsl.h ? hsl.h - hue : hue - hsl.h;
                        if (dh <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.Saturation: {
                        float sat = ColorConversion.GetSaturation(colorOperations[k].color.r, colorOperations[k].color.g, colorOperations[k].color.b);
                        float ds  = sat < hsl.s ? hsl.s - sat : sat - hsl.s;
                        if (ds <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;

                    case ColorMatchMode.Lightness: {
                        float l  = ColorConversion.GetLightness(colorOperations[k].color.r, colorOperations[k].color.g, colorOperations[k].color.b);
                        float dl = l < hsl.l ? hsl.l - l : l - hsl.l;
                        if (dl <= threshold)
                        {
                            if (colorOperations[k].operation == ColorOperation.Preserve)
                            {
                                return(color);
                            }
                            else if (colorOperations[k].operation == ColorOperation.Replace)
                            {
                                return(colorOperations[k].replaceColor);
                            }
                        }
                    }
                    break;
                    }
                }
            }

            float md      = float.MaxValue;
            Color nearest = color;

            switch (colorMatchMode)
            {
            case ColorMatchMode.RGB: {
                for (int c = 0; c < palette.Length; c++)
                {
                    float dr = (palette[c].r - color.r) * 0.299f;
                    float dg = (palette[c].g - color.g) * 0.587f;
                    float db = (palette[c].b - color.b) * 0.114f;
                    float d  = dr * dr + dg * dg + db * db;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.Red: {
                for (int c = 0; c < palette.Length; c++)
                {
                    float dr = palette[c].r - color.r;
                    float d  = dr * dr;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.Green: {
                for (int c = 0; c < palette.Length; c++)
                {
                    float dg = palette[c].g - color.g;
                    float d  = dg * dg;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.Blue: {
                for (int c = 0; c < palette.Length; c++)
                {
                    float db = palette[c].b - color.b;
                    float d  = db * db;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.HSL: {
                HSLColor hsl = ColorConversion.GetHSLFromRGB(color.r, color.g, color.b);
                for (int c = 0; c < palette.Length; c++)
                {
                    HSLColor paletteHSL = ColorConversion.GetHSLFromRGB(palette[c].r, palette[c].g, palette[c].b);
                    float    dh         = (paletteHSL.h - hsl.h);
                    float    ds         = (paletteHSL.s - hsl.s);
                    float    dl         = (paletteHSL.l - hsl.l);
                    float    d          = dh * dh + ds * ds + dl * dl;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.Hue: {
                float h = ColorConversion.GetHue(color.r, color.g, color.b);
                for (int c = 0; c < palette.Length; c++)
                {
                    float paletteH = ColorConversion.GetHue(palette[c].r, palette[c].g, palette[c].b);
                    float dh       = (paletteH - h);
                    float d        = dh * dh;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.Saturation: {
                float s = ColorConversion.GetSaturation(color.r, color.g, color.b);
                for (int c = 0; c < palette.Length; c++)
                {
                    float paletteS = ColorConversion.GetSaturation(palette[c].r, palette[c].g, palette[c].b);
                    float dh       = (paletteS - s);
                    float d        = dh * dh;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;

            case ColorMatchMode.Lightness: {
                float l = ColorConversion.GetLightness(color.r, color.g, color.b);
                for (int c = 0; c < palette.Length; c++)
                {
                    float paletteL = ColorConversion.GetLightness(palette[c].r, palette[c].g, palette[c].b);
                    float dh       = (paletteL - l);
                    float d        = dh * dh;
                    if (d < md)
                    {
                        md      = d;
                        nearest = palette[c];
                    }
                }
            }
            break;
            }
            nearest.a = color.a;
            color     = nearest;

            if (enableColorAdjustments)
            {
                if (colorAdjustments.applyLUT && colorAdjustments.LUT != null)
                {
                    color = ApplyLUT(color, colorAdjustments.LUT);
                }
                // vibrance
                float vibrance = colorAdjustments.vibrance;
                if (vibrance > 0)
                {
                    float maxComponent = color.r > color.g ? color.r : color.g;
                    maxComponent = color.b > maxComponent ? color.b : maxComponent;
                    float minComponent = color.r < color.g ? color.r : color.g;
                    minComponent = color.b < minComponent ? color.b : minComponent;
                    float sat = maxComponent - minComponent;
                    if (sat < 0)
                    {
                        sat = 0;
                    }
                    else if (sat > 1f)
                    {
                        sat = 1f;
                    }
                    float luma = color.GetLuma();
                    color.r *= 1f + vibrance * (1f - sat) * (color.r - luma);
                    color.g *= 1f + vibrance * (1f - sat) * (color.g - luma);
                    color.b *= 1f + vibrance * (1f - sat) * (color.b - luma);
                }
                // tinting
                float tintAmount = colorAdjustments.tintAmount;
                if (tintAmount > 0)
                {
                    Color tintedColor = new Color(color.r * colorAdjustments.tintColor.r, color.g * colorAdjustments.tintColor.g, color.b * colorAdjustments.tintColor.b);
                    color = Color.Lerp(color, tintedColor, tintAmount);
                }
                // contrast
                float contrast = colorAdjustments.contrast + 1f;
                if (contrast != 1f)
                {
                    color.r = (color.r - 0.5f) * contrast + 0.5f;
                    color.g = (color.g - 0.5f) * contrast + 0.5f;
                    color.b = (color.b - 0.5f) * contrast + 0.5f;
                }
                // brightness
                float brightness = colorAdjustments.brightness + 1f;
                if (brightness != 1f)
                {
                    color.r *= brightness;
                    color.g *= brightness;
                    color.b *= brightness;
                }
            }

            return(color);
        }
Exemple #3
0
        public void BuildHueColors()
        {
            if (colors == null || colors.Length != 256)
            {
                colors = new Color[256];
            }

            if (scheme == ColorScheme.Custom)
            {
                colorsCount = 0;
            }
            else
            {
                colorsCount = Mathf.Max(hueCount, scheme.minHues());
            }

            switch (scheme)
            {
            case ColorScheme.Custom:
                break;

            case ColorScheme.Monochromatic:
                for (int k = 0; k < colorsCount; k++)
                {
                    colors[k] = primaryColor;
                }
                break;

            case ColorScheme.Complementary: {
                for (int k = 0; k < colorsCount; k++)
                {
                    colors[k] = Color.Lerp(primaryColor, complementary1Color, (float)k / (colorsCount - 1));
                }
            }
            break;

            case ColorScheme.Gradient: {
                for (int k = 0; k < colorsCount; k++)
                {
                    colors[k] = Color.Lerp(primaryColor, complementary1Color, (float)k / (colorsCount - 1));
                }
            }
            break;

            case ColorScheme.SplitComplementary: {
                const float third     = 1f / 3f;
                const float twoThirds = 2f / 3f;
                for (int k = 0; k < colorsCount; k++)
                {
                    float t = (float)k / colorsCount;
                    if (t < third)
                    {
                        colors[k] = Color.Lerp(primaryColor, complementary1Color, t / third);
                    }
                    else if (t < twoThirds)
                    {
                        colors[k] = Color.Lerp(complementary1Color, complementary2Color, (t - third) / third);
                    }
                    else
                    {
                        colors[k] = Color.Lerp(complementary2Color, primaryColor, (t - twoThirds) / third);
                    }
                }
            }
            break;

            case ColorScheme.Analogous: {
                for (int k = 0; k < colorsCount; k++)
                {
                    float t = (float)k / (colorsCount - 1);
                    if (t < 0.5f)
                    {
                        colors[k] = Color.Lerp(complementary1Color, primaryColor, t / 0.5f);
                    }
                    else
                    {
                        colors[k] = Color.Lerp(primaryColor, complementary2Color, (t - 0.5f) / 0.5f);
                    }
                }
            }
            break;

            case ColorScheme.Triadic: {
                const float third     = 1f / 3f;
                const float twoThirds = 2f / 3f;
                for (int k = 0; k < colorsCount; k++)
                {
                    float t = (float)k / colorsCount;
                    if (t < third)
                    {
                        colors[k] = Color.Lerp(primaryColor, complementary1Color, t / third);
                    }
                    else if (t < twoThirds)
                    {
                        colors[k] = Color.Lerp(complementary1Color, complementary2Color, (t - third) / third);
                    }
                    else
                    {
                        colors[k] = Color.Lerp(complementary2Color, primaryColor, (t - twoThirds) / third);
                    }
                }
            }
            break;

            case ColorScheme.Tetradic: {
                for (int k = 0; k < colorsCount; k++)
                {
                    float t = (float)k / colorsCount;
                    if (t < 0.25f)
                    {
                        colors[k] = Color.Lerp(primaryColor, complementary1Color, t / 0.25f);
                    }
                    else if (t < 0.5f)
                    {
                        colors[k] = Color.Lerp(complementary1Color, complementary2Color, (t - 0.25f) / 0.25f);
                    }
                    else if (t < 0.75f)
                    {
                        colors[k] = Color.Lerp(complementary2Color, complementary3Color, (t - 0.5f) / 0.25f);
                    }
                    else
                    {
                        colors[k] = Color.Lerp(complementary3Color, primaryColor, (t - 0.75f) / 0.25f);
                    }
                }
            }
            break;

            case ColorScheme.Square: {
                for (int k = 0; k < colorsCount; k++)
                {
                    float t = (float)k / colorsCount;
                    if (t < 0.25f)
                    {
                        colors[k] = Color.Lerp(primaryColor, complementary1Color, t / 0.25f);
                    }
                    else if (t < 0.5f)
                    {
                        colors[k] = Color.Lerp(complementary1Color, complementary2Color, (t - 0.25f) / 0.25f);
                    }
                    else if (t < 0.75f)
                    {
                        colors[k] = Color.Lerp(complementary2Color, complementary3Color, (t - 0.5f) / 0.25f);
                    }
                    else
                    {
                        colors[k] = Color.Lerp(complementary3Color, primaryColor, (t - 0.75f) / 0.25f);
                    }
                }
            }
            break;

            case ColorScheme.AccentedAnalogous: {
                for (int k = 0; k < colorsCount; k++)
                {
                    float t = (float)k / colorsCount;
                    if (t < 0.25f)
                    {
                        colors[k] = Color.Lerp(primaryColor, complementary1Color, t / 0.25f);
                    }
                    else if (t < 0.5f)
                    {
                        colors[k] = Color.Lerp(complementary1Color, complementary2Color, (t - 0.25f) / 0.25f);
                    }
                    else if (t < 0.75f)
                    {
                        colors[k] = Color.Lerp(complementary2Color, complementary3Color, (t - 0.5f) / 0.25f);
                    }
                    else
                    {
                        colors[k] = Color.Lerp(complementary3Color, primaryColor, (t - 0.75f) / 0.25f);
                    }
                }
            }
            break;

            case ColorScheme.Spectrum:
                for (int k = 0; k < colorsCount; k++)
                {
                    colors[k] = ColorConversion.GetColor((float)k / colorsCount);
                }
                break;
            }

            // Add custom colors
            for (int k = START_INDEX_CUSTOM_COLOR; k < keyColors.Length; k++)
            {
                if (colorsCount < colors.Length && keyColors[k].visible)
                {
                    colors[colorsCount++] = keyColors[k].color;
                }
            }

            // Apply color temp correction
            if (colorTempStrength > 0)
            {
                Color ct = Mathf.CorrelatedColorTemperatureToRGB(kelvin);
                float ac = 1f - colorTempStrength;
                for (int k = 0; k < colorsCount; k++)
                {
                    colors[k].r = colors[k].r * (ct.r * colorTempStrength + ac);
                    colors[k].g = colors[k].g * (ct.g * colorTempStrength + ac);
                    colors[k].b = colors[k].b * (ct.b * colorTempStrength + ac);
                }
            }
            UpdateMaterial();
        }
Exemple #4
0
        Color GetTransformedColor(Color originalColor)
        {
            switch (currentBrush)
            {
            case Brush.Darken: {
                if (originalColor.a == 0)
                {
                    return(originalColor);
                }
                HSLColor hsl = ColorConversion.GetHSLFromRGB(originalColor.r, originalColor.g, originalColor.b);
                hsl.l -= 0.05f;
                if (hsl.l < 0.01f)
                {
                    hsl.l = 0.01f;
                }
                return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
            }

            case Brush.Lighten: {
                if (originalColor.a == 0)
                {
                    return(originalColor);
                }
                HSLColor hsl = ColorConversion.GetHSLFromRGB(originalColor.r, originalColor.g, originalColor.b);
                hsl.l += 0.05f;
                if (hsl.l > 0.99f)
                {
                    hsl.l = 0.99f;
                }
                return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
            }

            case Brush.Dry: {
                if (originalColor.a == 0)
                {
                    return(originalColor);
                }
                HSLColor hsl = ColorConversion.GetHSLFromRGB(originalColor.r, originalColor.g, originalColor.b);
                hsl.s -= 0.05f;
                if (hsl.s < 0.01f)
                {
                    hsl.s = 0.01f;
                }
                return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
            }

            case Brush.Vivid: {
                if (originalColor.a == 0)
                {
                    return(originalColor);
                }
                HSLColor hsl = ColorConversion.GetHSLFromRGB(originalColor.r, originalColor.g, originalColor.b);
                hsl.s += 0.05f;
                if (hsl.s > 0.99f)
                {
                    hsl.s = 0.99f;
                }
                return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
            }

            case Brush.Noise: {
                if (originalColor.a == 0)
                {
                    return(originalColor);
                }
                HSLColor hsl = ColorConversion.GetHSLFromRGB(originalColor.r, originalColor.g, originalColor.b);
                hsl.l += Random.value * 0.1f - 0.05f;
                if (hsl.l > 0.99f)
                {
                    hsl.l = 0.99f;
                }
                else if (hsl.l < 0.01f)
                {
                    hsl.l = 0.01f;
                }
                return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
            }

            case Brush.NoiseTone: {
                if (originalColor.a == 0)
                {
                    return(originalColor);
                }
                HSLColor hsl = ColorConversion.GetHSLFromRGB(originalColor.r, originalColor.g, originalColor.b);
                hsl.h += Random.value * 0.1f - 0.05f;
                if (hsl.h > 0.99f)
                {
                    hsl.l = 0.99f;
                }
                else if (hsl.h < 0.01f)
                {
                    hsl.h = 0.01f;
                }
                return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
            }

            case Brush.Gradient: {
                HSLColor hsl      = ColorConversion.GetHSLFromRGB(_brushColor.r, _brushColor.g, _brushColor.b);
                int      distance = Mathf.Max(Mathf.Abs(startTexelPos.x - currentTexelPos.x), Mathf.Abs(startTexelPos.y - currentTexelPos.y));
                if (distance > 0)
                {
                    hsl.l -= 0.05f * distance;
                    if (hsl.l < 0.01f)
                    {
                        hsl.l = 0.01f;
                    }
                    return(ColorConversion.GetColorFromHSL(hsl.h, hsl.s, hsl.l));
                }
                return(_brushColor);
            }
            }
            return(_brushColor);
        }