protected override MutableObject Mutate(MutableObject mutable) { var frequencies = ByteHistogram.GetFirstValue(mutable); var saturation = Saturation.GetFirstValue(mutable); var value = Value.GetFirstValue(mutable); var frequencyBands = new List <FrequencyBand>(); var totalSize = (float)frequencies.Sum(f => f); var currentPosition = 0f; int i = 0; foreach (var frequency in frequencies) { frequencyBands.Add(new FrequencyBand { Byte = i++, Color = ColorUtility.HsvtoRgb(currentPosition / totalSize, saturation, value), Start = currentPosition / totalSize, End = (currentPosition + frequency) / totalSize, Frequency = frequency }); currentPosition = currentPosition + frequency; } frequencyBands.Sort((a, b) => 0 - a.Frequency.CompareTo(b.Frequency)); var smoothGradient = SmoothGradient.GetFirstValue(mutable); var numberOfPoints = Keypoints.GetFirstValue(mutable); var edgeWidth = EdgeWidth.GetFirstValue(mutable); var primaryColor = PrimaryColor.GetFirstValue(mutable); var primaryImpactOnBands = PrimaryImpactOnBands.GetFirstValue(mutable); var newGradient = new ColorGradient(numberOfPoints * (smoothGradient?1:2)); frequencyBands = frequencyBands.Take(numberOfPoints).OrderBy(f => f.Start).ToList(); if (smoothGradient) { for (var k = 0; k < Mathf.Min(numberOfPoints, frequencyBands.Count); k++) { { newGradient.AddColorKey(new GradientColorKey( frequencyBands[k].Color, (frequencyBands[k].Start + frequencyBands[k].End) / 2f)); } } } else { for (var k = 1; k < Mathf.Min(numberOfPoints, frequencyBands.Count); k++) { var k1 = frequencyBands[k - 1].Color; newGradient.AddColorKey(new GradientColorKey( Color.Lerp(frequencyBands[k - 1].Color, primaryColor, primaryImpactOnBands), frequencyBands[k - 1].Start + edgeWidth / 2f)); var k2 = frequencyBands[k - 1].Color; newGradient.AddColorKey(new GradientColorKey( Color.Lerp(frequencyBands[k - 1].Color, primaryColor, primaryImpactOnBands), frequencyBands[k].Start - edgeWidth / 2f)); if (k1 != k2) { throw new Exception("What? How are these colors not matched?"); } } } HistogramGradient.SetValue(newGradient, mutable); return(mutable); }