public static Color Blend(this Color current, Color target, ColorBlend mode, float amount = 1) { var white = Color.white; var value = Color.cyan; Func <float, float, float> formula = null; if (mode.Matches("Balance")) { value = current; var luma = current.GetLuminance(); var otherLuma = target.GetLuminance(); var difference = (luma - otherLuma).Abs(); if (difference <= 0.3f) { value = current.Add(luma < 0.3f ? 0.5f : -0.5f); } } else if (mode.Matches("Darken")) { value = current.Min(target); } else if (mode.Matches("Multiply")) { value = current * target; } else if (mode.Matches("ColorBurn")) { var blend = current.Invert().Divide(target); value = blend.Invert(); } else if (mode.Matches("LinearBurn")) { value = current + target - white; } else if (mode.Matches("DarkerColor")) { } else if (mode.Matches("Lighten")) { value = current.Max(target); } else if (mode.Matches("Screen")) { value = white - current.Invert() * target.Invert(); } else if (mode.Matches("ColorDodge")) { value = current.Divide(target.Invert()); } else if (mode.Matches("Add") || mode.Matches("LinearDodge")) { value = current + target; } else if (mode.Matches("LighterColor")) { } else if (mode.Matches("Overlay")) { formula = (a, b) => { return(a < 0.5f ? 2 * a * b : 1 - (2 * (1 - a) * (1 - b))); }; } else if (mode.Matches("SoftLight")) { formula = (a, b) => { return(b < 0.5f ? 2 * a * b + a + a * (1 - 2 * b) : Math.Sqrt(a).ToFloat() * (2 * b - 1) + 2 * a * (1 - b)); }; } else if (mode.Matches("HardLight")) { } else if (mode.MatchesAny("VividLight", "LinearLight", "PinLight")) { ColorBlend modeA = ColorBlend.ColorBurn; ColorBlend modeB = ColorBlend.ColorDodge; if (mode.Matches("LinearLight")) { modeA = ColorBlend.LinearBurn; modeB = ColorBlend.LinearDodge; } if (mode.Matches("PinLight")) { modeA = ColorBlend.Darken; modeB = ColorBlend.Lighten; } var blendA = current.Blend(2 * target, modeA); var blendB = current.Blend(2 * (target - (white * 0.5f)), modeB); value.r = target.r < 0.5f ? blendA.r : blendB.r; value.g = target.g < 0.5f ? blendA.g : blendB.g; value.b = target.b < 0.5f ? blendA.b : blendB.b; } else if (mode.Matches("HardMix")) { var blend = current.Blend(target, ColorBlend.VividLight); value.r = blend.r < 0.5f ? 0 : 1; value.g = blend.g < 0.5f ? 0 : 1; value.b = blend.b < 0.5f ? 0 : 1; } else if (mode.Matches("Difference")) { value = (current - target).Abs(); } else if (mode.Matches("Exclusion")) { value = (current + target - 2.0f * current * target); } else if (mode.Matches("Subtract")) { value = target - current; } else if (mode.Matches("Divide")) { value = target.Divide(current); } else if (mode.Matches("Hue")) { } else if (mode.Matches("Saturation")) { } else if (mode.Matches("Color")) { } else if (mode.Matches("Luminosity")) { } if (!formula.IsNull()) { value.r = formula(current.r, target.r); value.g = formula(current.g, target.g); value.b = formula(current.b, target.b); } return(current.Lerp(value.Saturate(), amount)); }