Ejemplo n.º 1
0
        private float MinimizeError(
            PaletteGenerator generator,
            List <PaletteEntry> ramp,
            Range <float> range,
            Func <PaletteParameters, float, float> function)
        {
            const int count      = 20;
            const int iterations = 3;

            List <Tuple <float, float> > errors = null;
            int index = -1;

            for (int i = 0; i < iterations; i++)
            {
                errors = Errors(generator, ramp, range, count, function);
                float min = errors.Min(x => x.Item2);
                index = errors.FindIndex(x => x.Item2 == min);

                // Get the indices above and below the minimum value
                int step       = Math.Max(1, (int)(count * 0.3f) / 2);
                int startIndex = Math.Max(0, index - step);
                startIndex = Math.Min(count - step * 2, startIndex);
                int endIndex = startIndex + step * 2;
                range = new Range <float>(errors[startIndex].Item1, errors[endIndex].Item1);
            }
            return(errors[index].Item1);
        }
        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;
        }
Ejemplo n.º 3
0
        private List <Tuple <float, float> > Errors(
            PaletteParameters parameters,
            List <PaletteEntry> ramp,
            Range <float> range,
            int count,
            Func <PaletteGenerator, float, float> function)
        {
            PaletteGenerator  copyGenerator  = (PaletteGenerator)Clone();
            PaletteParameters copyParameters = (PaletteParameters)parameters.Clone();
            float             interval       = (range.Maximum - range.Minimum) / count;

            var errors = new List <Tuple <float, float> >();

            for (int i = 0; i <= count; i++)
            {
                float value = range.Minimum + interval * i;
                function(copyGenerator, value);

                // Kind of necessary for user facing values
                // Minimize error on blue shadow
                copyParameters.MinimizeBlueError(copyGenerator, ramp);
                // Minimize error on yellow light
                copyParameters.MinimizeYellowError(copyGenerator, ramp);

                var   palette = copyGenerator.GetPalette(copyParameters);
                float error   = palette.GetError(ramp);
                errors.Add(Tuple.Create(value, error));
            }

            return(errors);
        }
Ejemplo n.º 4
0
        internal void MinimizeBlueError(PaletteGenerator generator, List <PaletteEntry> ramp)
        {
            var range = BlueRange();
            Func <PaletteParameters, float, float> function =
                (PaletteParameters parameters, float value) => parameters.BlueShadow = value;

            float minimum = MinimizeError(generator, ramp, range, function);

            BlueShadow = minimum;
        }
Ejemplo n.º 5
0
        internal void MinimizeYellowError(PaletteGenerator generator, List <PaletteEntry> ramp)
        {
            var range = YellowRange();
            Func <PaletteParameters, float, float> function =
                (PaletteParameters parameters, float value) => parameters.YellowLight = value;

            float minimum = MinimizeError(generator, ramp, range, function);

            YellowLight = minimum;
        }
Ejemplo n.º 6
0
        internal PaletteRamp(string name, Color darkestColor)
        {
            Name                  = name;
            _BaseColorIndex       = 0;
            _Colors               = new List <Color>();
            _Adjustments          = new List <ColorVector>();
            Generator             = new PaletteGenerator();
            BlueYellowAdjustments = true;

            SetBlackLevel(darkestColor);
        }
Ejemplo n.º 7
0
        public override void CopyFrom(TactileDataContent other)
        {
            CheckSameClass(other);

            var source = (PaletteRamp)other;

            Name                  = source.Name;
            _BaseColorIndex       = source._BaseColorIndex;
            _Colors               = new List <Color>(source._Colors);
            _Adjustments          = new List <ColorVector>(source._Adjustments);
            Generator             = (PaletteGenerator)source.Generator.Clone();
            BlueYellowAdjustments = source.BlueYellowAdjustments;
        }
        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;
        }
Ejemplo n.º 10
0
        private List <Tuple <float, float> > Errors(
            PaletteGenerator generator,
            List <PaletteEntry> ramp,
            Range <float> range,
            int count,
            Func <PaletteParameters, float, float> function)
        {
            PaletteParameters copyParameters = (PaletteParameters)Clone();
            float             interval       = (range.Maximum - range.Minimum) / count;

            var errors = new List <Tuple <float, float> >();

            for (int i = 0; i <= count; i++)
            {
                float value = range.Minimum + interval * i;
                function(copyParameters, value);

                var   palette = generator.GetPalette(copyParameters);
                float error   = palette.GetError(ramp);
                errors.Add(Tuple.Create(value, error));
            }

            return(errors);
        }
Ejemplo n.º 11
0
 private PaletteGenerator(PaletteGenerator source)
 {
     CopyFrom(source);
 }