/// <summary> /// Converts HSL color values to RGB. /// </summary> /// <returns>The RGB value.</returns> /// <param name="hue">Hue.</param> /// <param name="saturation">Saturation.</param> /// <param name="lightness">Lightness.</param> /// <param name="alpha">Alpha.</param> public static Color HslToRgb(float hue, float saturation, float lightness, float alpha) { // Achromatic if (HydraMathUtils.Approximately(saturation, 0.0f)) { return(new Color(lightness, lightness, lightness, alpha)); } float q = (lightness < 0.5f) ? lightness * (1.0f + saturation) : lightness + saturation - lightness * saturation; float p = 2.0f * lightness - q; float r = HueToChannel(p, q, hue + 1.0f / 3.0f); float g = HueToChannel(p, q, hue); float b = HueToChannel(p, q, hue - 1.0f / 3.0f); return(new Color(r, g, b, alpha)); }
/// <summary> /// Blends the two colors together. /// </summary> /// <returns>The blended color.</returns> /// <param name="baseLayer">Base layer.</param> /// <param name="topLayer">Top layer.</param> public static Color BlendNormal(Color baseLayer, Color topLayer) { if (HydraMathUtils.Approximately(topLayer.a, 0.0f)) { return(baseLayer); } if (HydraMathUtils.Approximately(baseLayer.a, 0.0f)) { return(topLayer); } float alpha = 1.0f - (1.0f - topLayer.a) * (1.0f - baseLayer.a); return(new Color(topLayer.r * topLayer.a / alpha + baseLayer.r * baseLayer.a * (1.0f - topLayer.a) / alpha, topLayer.g * topLayer.a / alpha + baseLayer.g * baseLayer.a * (1.0f - topLayer.a) / alpha, topLayer.b * topLayer.a / alpha + baseLayer.b * baseLayer.a * (1.0f - topLayer.a) / alpha, alpha)); }
/// <summary> /// Converts RGB color values to HSL. /// </summary> /// <returns>The HSL value.</returns> /// <param name="red">Red.</param> /// <param name="green">Green.</param> /// <param name="blue">Blue.</param> /// <param name="alpha">Alpha.</param> public static Vector4 RgbToHsl(float red, float green, float blue, float alpha) { float max = HydraMathUtils.Max(red, green, blue); float min = HydraMathUtils.Min(red, green, blue); float hue = (max + min) / 2.0f; float saturation; float lightness = hue; if (HydraMathUtils.Approximately(max, min)) { // achromatic hue = 0.0f; saturation = 0.0f; } else { float delta = max - min; saturation = (lightness > 0.5f) ? delta / (2.0f - max - min) : delta / (max + min); if (red >= green && red >= blue) { hue = (green - blue) / delta + (green < blue ? 6.0f : 0.0f); } else if (green >= red && green >= blue) { hue = (blue - red) / delta + 2.0f; } else { hue = (red - green) / delta + 4.0f; } hue /= 6.0f; } return(new Vector4(hue, saturation, lightness, alpha)); }
/// <summary> /// Generates the tangents. /// </summary> /// <param name="mesh">Mesh.</param> public static void RecalculateTangents(Mesh mesh) { int[] triangles = mesh.triangles; Vector3[] vertices = mesh.vertices; Vector2[] uv = mesh.uv; Vector3[] normals = mesh.normals; int triangleCount = triangles.Length; int vertexCount = vertices.Length; Array.Resize(ref s_Tan1, vertexCount); Array.Resize(ref s_Tan2, vertexCount); Array.Resize(ref s_Tangents, vertexCount); for (long index = 0; index < triangleCount; index += 3) { long i1 = triangles[index + 0]; long i2 = triangles[index + 1]; long i3 = triangles[index + 2]; Vector3 v1 = vertices[i1]; Vector3 v2 = vertices[i2]; Vector3 v3 = vertices[i3]; Vector2 w1 = uv[i1]; Vector2 w2 = uv[i2]; Vector2 w3 = uv[i3]; float x1 = v2.x - v1.x; float x2 = v3.x - v1.x; float y1 = v2.y - v1.y; float y2 = v3.y - v1.y; float z1 = v2.z - v1.z; float z2 = v3.z - v1.z; float s1 = w2.x - w1.x; float s2 = w3.x - w1.x; float t1 = w2.y - w1.y; float t2 = w3.y - w1.y; float div = s1 * t2 - s2 * t1; float r = HydraMathUtils.Approximately(div, 0.0f) ? 0.0f : 1.0f / div; Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); s_Tan1[i1] += sdir; s_Tan1[i2] += sdir; s_Tan1[i3] += sdir; s_Tan2[i1] += tdir; s_Tan2[i2] += tdir; s_Tan2[i3] += tdir; } for (long index = 0; index < vertexCount; index++) { Vector3 normal = normals[index]; Vector3 tangent = s_Tan1[index]; Vector3.OrthoNormalize(ref normal, ref tangent); s_Tangents[index].x = tangent.x; s_Tangents[index].y = tangent.y; s_Tangents[index].z = tangent.z; s_Tangents[index].w = (Vector3.Dot(Vector3.Cross(normal, tangent), s_Tan2[index]) < 0.0f) ? -1.0f : 1.0f; } mesh.tangents = s_Tangents; }