public float GetError(List <PaletteEntry> ramp)
        {
            var palette = this;
            var values  = ramp
                          .Select(x => palette.GetValue(x.Color))
                          .ToList();

            // Show final error
            float error = 0;

            for (int i = 0; i < ramp.Count; i++)
            {
                int weight = ramp[i].Weight;
                var source = ramp[i].Color;
                var target = GetColor(values[i]);

                var vector = XnaHSL.BiconeDifference(source, target);

                float length = vector.LengthSquared();
                error += length * weight;
            }
            int totalWeight = ramp.Select(x => x.Weight).Sum();

            error /= totalWeight;

            return(error);
        }
        public GeneratedColorPalette(
            PaletteGenerator generator,
            PaletteParameters parameters)
        {
            // Adjust base color up if black level is too close to it
            XnaHSL baseColor = AdjustBaseColor(parameters.BaseColor, generator.BlackLevel);

            // Tint just a little toward yellow based on yellow light
            XnaHSL untintedBaseColor = baseColor;

            if (baseColor.Saturation > 0)
            {
                baseColor = baseColor.LerpHue(60, parameters.YellowLight * 0.075f);
            }

            XnaHSL highlight, specular;

            GetHighlight(baseColor, generator, parameters,
                         out highlight, out specular);

            XnaHSL shadow, darkest;

            GetShadow(untintedBaseColor, generator, parameters,
                      out shadow, out darkest);

            // Set the calculated values
            BaseColor    = baseColor;
            Darkest      = darkest;
            Shadow       = shadow;
            Highlight    = highlight;
            Specular     = specular;
            ReducedDepth = parameters.ReducedDepth;
        }
Example #3
0
        internal static IEnumerable <int> ColorLumaOrder(IEnumerable <Color> colors)
        {
            List <int> order = Enumerable
                               .Range(0, colors.Count())
                               .Select(x =>
            {
                Color color = colors.ElementAt(x);
                XnaHSL hsl  = new XnaHSL(color);
                return(Tuple.Create(x, color, hsl));
            })
                               // This actually needs to use luma instead of lightness,
                               // because the perceptual order is important
                               .OrderBy(x => GeneratedColorPalette.ValueFormula(x.Item2))
                               .ThenBy(x => x.Item3.Lightness)
                               // If colors have the same lightness,
                               // use the one with the least saturation
                               .ThenBy(x => x.Item3.Saturation)
                               // If colors have the same lightness,
                               // use the one with the most alpha
                               .ThenByDescending(x => x.Item2.A)
                               .Select(x => x.Item1)
                               .ToList();

            return(order);
        }
        private float SaturationMultiplier(GeneratedColorPalette rawPalette, PaletteRamp ramp, int index)
        {
            Color target = rawPalette.GetColor(ColorValues[index]);
            Color source = ramp.Colors[index];

            XnaHSL targetHsl = new XnaHSL(target);
            XnaHSL sourceHsl = new XnaHSL(source);

            return(SaturationMultiplier(targetHsl, sourceHsl));
        }
 private static float SaturationMultiplier(XnaHSL targetHsl, XnaHSL sourceHsl)
 {
     if (targetHsl.Saturation < sourceHsl.Saturation && sourceHsl.Saturation > 0)
     {
         return(targetHsl.Saturation / sourceHsl.Saturation);
     }
     else
     {
         return(1f);
     }
 }
        private static void GetHighlight(
            XnaHSL baseHSL,
            PaletteGenerator generator,
            PaletteParameters parameters,
            out XnaHSL highlight,
            out XnaHSL specular)
        {
            Color baseSpecular = PaletteGenerator.BaseSpecularColor(baseHSL.GetColor());

            // Tint yellow
            XnaHSL specularHSL = new XnaHSL(baseSpecular);

            // If greyscale, simply treat the hue as yellow
            if (float.IsNaN(specularHSL.Hue))
            {
                specularHSL = specularHSL.SetHue(60);
            }
            specularHSL = specularHSL.LerpHue(60, parameters.YellowLight);
            specularHSL = specularHSL.SetSaturation(MathHelper.Lerp(
                                                        specularHSL.Saturation, 1f, parameters.YellowLight));
            specularHSL = specularHSL.SetLightness(MathHelper.Lerp(
                                                       specularHSL.Lightness, Math.Max(0.5f, specularHSL.Lightness), parameters.YellowLight));

            // Add specular
            specularHSL = specularHSL.SetLightness(MathHelper.Lerp(
                                                       specularHSL.Lightness, 1f, generator.Specularity));
            // Reduce the lightness if the base color is darker than the generator color
            if (generator.BaseLightness > 0 && baseHSL.Lightness < generator.BaseLightness)
            {
                float lightnessDiff = generator.BaseLightness - baseHSL.Lightness;
                specularHSL = specularHSL.SetLightness(specularHSL.Lightness - (lightnessDiff));
            }
            float highlightAmount = 0.5f;
            // If the base color is sufficiently bright, lighten the specular
            // to keep the contrast from getting too low
            float lightnessRatio = (baseHSL.Lightness - 0.5f) * 2f;

            if (lightnessRatio > 0)
            {
                specularHSL = specularHSL.SetLightness(
                    MathHelper.Lerp(specularHSL.Lightness, 1f, lightnessRatio));
                highlightAmount = MathHelper.Lerp(0.5f, 1f, lightnessRatio);
            }

            // Get highlight
            XnaHSL highlightHSL = XnaHSL.Lerp(baseHSL, specularHSL, highlightAmount);

            highlight = highlightHSL;
            specular  = specularHSL;
        }
        private static void GetShadow(
            XnaHSL baseHSL,
            PaletteGenerator generator,
            PaletteParameters parameters,
            out XnaHSL shadow,
            out XnaHSL darkest)
        {
            XnaHSL blackHSL = new XnaHSL(
                baseHSL.Hue,
                baseHSL.Saturation * generator.ShadowAmount,
                generator.BlackLevel,
                baseHSL.Alpha);

            // If the base color is sufficiently bright, lighten the darker shades
            float lightnessRatio = (baseHSL.Lightness - 0.5f) * 2f;

            if (lightnessRatio > 0)
            {
                blackHSL = blackHSL.SetSaturation(blackHSL.Saturation * (1f - lightnessRatio * 0.95f));

                float blackLuma = Color_Util.GetLuma(blackHSL.GetColor());
                // Increase the lightness by more if it's a color with a low
                // luma to lightness ratio
                float lumaRatio = 1f;
                if (blackLuma > 0)
                {
                    lumaRatio = blackHSL.Lightness / blackLuma;
                }

                blackHSL = blackHSL.SetLightness(
                    MathHelper.Lerp(blackHSL.Lightness,
                                    MathHelper.Lerp(blackHSL.Lightness, 1f, 0.25f),
                                    lightnessRatio * lumaRatio));
            }

            // Tint black and shadow blue
            blackHSL = blackHSL.LerpHue(240, parameters.BlueShadow);
            blackHSL = blackHSL.SetSaturation(MathHelper.Lerp(blackHSL.Saturation, 1f, parameters.BlueShadow / 4f));

            XnaHSL shadowHSL = XnaHSL.Lerp(blackHSL, baseHSL, generator.ShadowAmount);

            shadowHSL = shadowHSL.SetSaturation(MathHelper.Lerp(blackHSL.Saturation, baseHSL.Saturation, 0.5f));
            shadowHSL = shadowHSL.SetHue(blackHSL.Hue);
            shadowHSL = shadowHSL.LerpHue(baseHSL.Hue, 0.25f);

            shadow  = shadowHSL;
            darkest = blackHSL;
        }
Example #8
0
        public GeneratedColorPalette GetColorPalette(PaletteParameters parameters)
        {
            parameters = (PaletteParameters)parameters.Clone();

            // Adjust the lightness of the base color
            XnaHSL baseHsl       = new XnaHSL(this.BaseColor);
            XnaHSL parametersHsl = new XnaHSL(parameters.BaseColor);

            parametersHsl = parametersHsl.SetLightness(
                MathHelper.Lerp(
                    parametersHsl.Lightness,
                    baseHsl.Lightness,
                    parameters.OriginalLightness));
            parameters.BaseColor = parametersHsl.GetColor();

            return(Ramp.Generator.GetPalette(parameters));
        }
        public Color GetColor(float value)
        {
            var ranges = GetRanges();
            var start  = ranges.First();

            foreach (var end in ranges.Skip(1))
            {
                if (value < end.Item2)
                {
                    float  range = end.Item2 - start.Item2;
                    XnaHSL hsl   = XnaHSL.Lerp(start.Item1, end.Item1,
                                               (value - start.Item2) / range);
                    return(DepthColor(hsl.GetColor()));
                }
                start = end;
            }
            return(DepthColor(Specular.GetColor()));
        }
Example #10
0
        public static ColorVector ColorDifference(Color source, Color target, bool blueYellowRamp = false)
        {
            XnaHSL sourceHsl = new XnaHSL(source);
            XnaHSL targetHsl = new XnaHSL(target);

            float hue;

            if (float.IsNaN(sourceHsl.Hue) || float.IsNaN(targetHsl.Hue))
            {
                hue = 0;
            }
            else
            {
                if (blueYellowRamp)
                {
                    hue = GetBlueYellowHue(targetHsl.Hue) -
                          GetBlueYellowHue(sourceHsl.Hue);
                }
                else
                {
                    hue  = targetHsl.Hue - sourceHsl.Hue;
                    hue %= 360;
                    if (hue <= -180)
                    {
                        hue += 360;
                    }
                    else if (hue > 180)
                    {
                        hue -= 360;
                    }
                }
            }
            float sat = targetHsl.Saturation - sourceHsl.Saturation;
            float lit = targetHsl.Lightness - sourceHsl.Lightness;

            return(new ColorVector(hue, sat, lit, blueYellowRamp));
        }
Example #11
0
        public XnaHSL GetHsl(float index)
        {
            PaletteEntry entry = Palette.GetEntry(Ramp.Colors.FirstOrDefault());
            XnaHSL       black = new XnaHSL(entry.Color);

            black = black.SetSaturation(0f);
            black = black.SetLightness(0f);
            entry = Palette.GetEntry(Ramp.Colors.LastOrDefault());
            XnaHSL white = new XnaHSL(entry.Color);

            white = white.SetSaturation(0f);
            white = white.SetLightness(1f);

            XnaHSL left  = black;
            XnaHSL right = white;

            for (int i = 0; i <= Ramp.Count; i++, index -= 1f, left = right)
            {
                if (i == Ramp.Count)
                {
                    right = white;
                }
                else
                {
                    entry = Palette.GetEntry(Ramp.GetColor(i));
                    right = new XnaHSL(entry.Color);
                }

                if (index <= 0f)
                {
                    XnaHSL hslResult = XnaHSL.Lerp(left, right, (index + 1));
                    return(hslResult);
                }
            }
            return(right);
        }
Example #12
0
        public static Color operator +(Color color, ColorVector vector)
        {
            XnaHSL hsl = new XnaHSL(color) + vector;

            return(hsl.GetColor());
        }
 public static float ValueFormula(XnaHSL hsl)
 {
     return(ValueFormula(hsl.GetColor()));
 }