public static XMVector RgbToHsv(XMVector rgb) { XMVector r = XMVector.SplatX(rgb); XMVector g = XMVector.SplatY(rgb); XMVector b = XMVector.SplatZ(rgb); XMVector min = XMVector.Min(r, XMVector.Min(g, b)); XMVector v = XMVector.Max(r, XMVector.Max(g, b)); XMVector d = XMVector.Subtract(v, min); XMVector s = XMVector3.NearEqual(v, XMGlobalConstants.Zero, XMGlobalConstants.Epsilon) ? XMGlobalConstants.Zero : XMVector.Divide(d, v); if (XMVector3.Less(d, XMGlobalConstants.Epsilon)) { // Achromatic, assume H of 0 XMVector hv = XMVector.Select(v, XMGlobalConstants.Zero, XMGlobalConstants.Select1000); XMVector hva = XMVector.Select(rgb, hv, XMGlobalConstants.Select1110); return(XMVector.Select(s, hva, XMGlobalConstants.Select1011)); } else { XMVector h; if (XMVector3.Equal(r, v)) { // Red is max h = XMVector.Divide(XMVector.Subtract(g, b), d); if (XMVector3.Less(g, b)) { h = XMVector.Add(h, XMGlobalConstants.Six); } } else if (XMVector3.Equal(g, v)) { // Green is max h = XMVector.Divide(XMVector.Subtract(b, r), d); h = XMVector.Add(h, XMGlobalConstants.Two); } else { // Blue is max h = XMVector.Divide(XMVector.Subtract(r, g), d); h = XMVector.Add(h, XMGlobalConstants.Four); } h = XMVector.Divide(h, XMGlobalConstants.Six); XMVector hv = XMVector.Select(v, h, XMGlobalConstants.Select1000); XMVector hva = XMVector.Select(rgb, hv, XMGlobalConstants.Select1110); return(XMVector.Select(s, hva, XMGlobalConstants.Select1011)); } }
private static XMVector HueToClr(XMVector p, XMVector q, XMVector h) { XMVector oneSixth = XMVector.FromFloat(1.0f / 6.0f, 1.0f / 6.0f, 1.0f / 6.0f, 1.0f / 6.0f); XMVector twoThirds = XMVector.FromFloat(2.0f / 3.0f, 2.0f / 3.0f, 2.0f / 3.0f, 2.0f / 3.0f); XMVector t = h; if (XMVector3.Less(t, XMGlobalConstants.Zero)) { t = XMVector.Add(t, XMGlobalConstants.One); } if (XMVector3.Greater(t, XMGlobalConstants.One)) { t = XMVector.Subtract(t, XMGlobalConstants.One); } if (XMVector3.Less(t, oneSixth)) { // p + (q - p) * 6 * t XMVector t1 = XMVector.Subtract(q, p); XMVector t2 = XMVector.Multiply(XMGlobalConstants.Six, t); return(XMVector.MultiplyAdd(t1, t2, p)); } if (XMVector3.Less(t, XMGlobalConstants.OneHalf)) { return(q); } if (XMVector3.Less(t, twoThirds)) { // p + (q - p) * 6 * (2/3 - t) XMVector t1 = XMVector.Subtract(q, p); XMVector t2 = XMVector.Multiply(XMGlobalConstants.Six, XMVector.Subtract(twoThirds, t)); return(XMVector.MultiplyAdd(t1, t2, p)); } return(p); }
public static XMVector HslToRgb(XMVector hsl) { XMVector oneThird = XMVector.FromFloat(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f); XMVector s = XMVector.SplatY(hsl); XMVector l = XMVector.SplatZ(hsl); if (XMVector3.NearEqual(s, XMGlobalConstants.Zero, XMGlobalConstants.Epsilon)) { // Achromatic return(XMVector.Select(hsl, l, XMGlobalConstants.Select1110)); } else { XMVector h = XMVector.SplatX(hsl); XMVector q; if (XMVector3.Less(l, XMGlobalConstants.OneHalf)) { q = XMVector.Multiply(l, XMVector.Add(XMGlobalConstants.One, s)); } else { q = XMVector.Subtract(XMVector.Add(l, s), XMVector.Multiply(l, s)); } XMVector p = XMVector.Subtract(XMVector.Multiply(XMGlobalConstants.Two, l), q); XMVector r = XMColor.HueToClr(p, q, XMVector.Add(h, oneThird)); XMVector g = XMColor.HueToClr(p, q, h); XMVector b = XMColor.HueToClr(p, q, XMVector.Subtract(h, oneThird)); XMVector rg = XMVector.Select(g, r, XMGlobalConstants.Select1000); XMVector ba = XMVector.Select(hsl, b, XMGlobalConstants.Select1110); return(XMVector.Select(ba, rg, XMGlobalConstants.Select1100)); } }
public static XMVector RgbToHsl(XMVector rgb) { XMVector r = XMVector.SplatX(rgb); XMVector g = XMVector.SplatY(rgb); XMVector b = XMVector.SplatZ(rgb); XMVector min = XMVector.Min(r, XMVector.Min(g, b)); XMVector max = XMVector.Max(r, XMVector.Max(g, b)); XMVector l = XMVector.Multiply(XMVector.Add(min, max), XMGlobalConstants.OneHalf); XMVector d = XMVector.Subtract(max, min); XMVector la = XMVector.Select(rgb, l, XMGlobalConstants.Select1110); if (XMVector3.Less(d, XMGlobalConstants.Epsilon)) { // Achromatic, assume H and S of 0 return(XMVector.Select(la, XMGlobalConstants.Zero, XMGlobalConstants.Select1100)); } else { XMVector s; XMVector h; XMVector d2 = XMVector.Add(min, max); if (XMVector3.Greater(l, XMGlobalConstants.OneHalf)) { // d / (2-max-min) s = XMVector.Divide(d, XMVector.Subtract(XMGlobalConstants.Two, d2)); } else { // d / (max+min) s = XMVector.Divide(d, d2); } if (XMVector3.Equal(r, max)) { // Red is max h = XMVector.Divide(XMVector.Subtract(g, b), d); } else if (XMVector3.Equal(g, max)) { // Green is max h = XMVector.Divide(XMVector.Subtract(b, r), d); h = XMVector.Add(h, XMGlobalConstants.Two); } else { // Blue is max h = XMVector.Divide(XMVector.Subtract(r, g), d); h = XMVector.Add(h, XMGlobalConstants.Four); } h = XMVector.Divide(h, XMGlobalConstants.Six); if (XMVector3.Less(h, XMGlobalConstants.Zero)) { h = XMVector.Add(h, XMGlobalConstants.One); } XMVector lha = XMVector.Select(la, h, XMGlobalConstants.Select1100); return(XMVector.Select(s, lha, XMGlobalConstants.Select1011)); } }