public IndexedGeneratedPalette(
            SpriteRamp ramp,
            PaletteParameters parameters)
        {
            BasePalette = ramp.GetColorPalette(parameters);

            ColorValues        = ramp.ColorValues.ToArray();
            PaletteAdjustments = ramp.Adjustments.ToArray();

#if DEBUG
            System.Diagnostics.Debug.Assert(ramp.Count == ColorValues.Length, "Palette and ramp size must match");
            System.Diagnostics.Debug.Assert(ramp.Count == PaletteAdjustments.Length, "Palette and ramp size must match");
#endif

            // Saturation of the adjustment is reduced if the generated palette
            // is itself low saturation
            var rawParameters = (PaletteParameters)parameters.Clone();
            rawParameters.YellowLight = 0;
            rawParameters.BlueShadow  = 0;
            var rawPalette = ramp.GetColorPalette(rawParameters);

            AdjustmentsSaturationMultiplier = SaturationMultiplier(
                rawPalette.BaseColor, new XnaHSL(ramp.BaseColor));

            //@Debug: per color saturation adjustments

            /*AdjustmentsSaturationMultipliers = PaletteAdjustments
             *  .Select(x => 1f)
             *  .ToArray();
             * for (int i = 0; i < AdjustmentsSaturationMultipliers.Length; i++)
             * {
             *  AdjustmentsSaturationMultipliers[i] = SaturationMultiplier(
             *      rawPalette, ramp, i);
             * }*/
        }
예제 #2
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));
        }
예제 #4
0
        private void AdjustShadowAmount(Color color, GeneratedColorPalette palette, float rawAmount)
        {
            // The percent of the way between 0 and the BASE_VALUE
            float amount = rawAmount / GeneratedColorPalette.BASE_VALUE;

            // Avoid divide by 0
            if (amount <= 0)
            {
                this.ShadowAmount = 1f;
                return;
            }

            float darkestValue = GeneratedColorPalette.ValueFormula(palette.Darkest);
            float baseValue    = GeneratedColorPalette.ValueFormula(palette.BaseColor);

            // Avoid divide by 0
            if (baseValue - darkestValue == 0)
            {
                this.ShadowAmount = 0.5f;
                return;
            }
            float colorValue = GeneratedColorPalette.ValueFormula(color);
            float percent    = (colorValue - darkestValue) / (baseValue - darkestValue);

            if (amount < 0.5f)
            {
                float midPointValue = (percent / amount) / 2f;
                this.ShadowAmount = midPointValue;
            }
            else
            {
                // Avoid divide by 0
                if (amount >= 1f)
                {
                    this.ShadowAmount = 0;
                }
                else
                {
                    float midPointValue = MathHelper.Lerp(
                        1f, percent,
                        1 / (1 - (2f * amount - 1f)));
                    this.ShadowAmount = midPointValue;
                }
            }
        }
예제 #5
0
 public float GetError(GeneratedColorPalette colorPalette)
 {
     return(colorPalette.GetError(RampEntries()));
 }
예제 #6
0
 internal void SetBlackLevel(Color darkestColor)
 {
     Generator.BlackLevel = GeneratedColorPalette.ValueFormula(darkestColor);
 }