/// <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; }
/// <summary> /// Creates a rotation taking normal as up. /// </summary> /// <returns>The normal.</returns> /// <param name="normal">Normal.</param> public static Matrix4x4 FromNormal(Vector3 normal) { Vector3 tangent = HydraMathUtils.Tangent(normal); return(Rotate(tangent, normal)); }
/// <summary> /// Divides the channels. /// </summary> /// <returns>The blend.</returns> /// <param name="baseLayer">Base layer.</param> /// <param name="topLayer">Top layer.</param> public static Color BlendDivide(Color baseLayer, Color topLayer) { return(new Color(HydraMathUtils.Min(baseLayer.r / topLayer.r, 1.0f), HydraMathUtils.Min(baseLayer.g / topLayer.g, 1.0f), HydraMathUtils.Min(baseLayer.b / topLayer.b, 1.0f), HydraMathUtils.Min(baseLayer.a / topLayer.a, 1.0f))); }
/// <summary> /// Returns the top layer subtracted from the base layer. /// </summary> /// <returns>The blend.</returns> /// <param name="baseLayer">Base layer.</param> /// <param name="topLayer">Top layer.</param> public static Color BlendSubtract(Color baseLayer, Color topLayer) { return(new Color(HydraMathUtils.Max(baseLayer.r - topLayer.r, 0.0f), HydraMathUtils.Max(baseLayer.g - topLayer.g, 0.0f), HydraMathUtils.Max(baseLayer.b - topLayer.b, 0.0f), HydraMathUtils.Max(baseLayer.a - topLayer.a, 0.0f))); }
/// <summary> /// Takes the magnitude of each channel once subtracted. /// </summary> /// <returns>The difference.</returns> /// <param name="baseLayer">Base layer.</param> /// <param name="topLayer">Top layer.</param> public static Color BlendDifference(Color baseLayer, Color topLayer) { return(new Color(HydraMathUtils.Abs(baseLayer.r - topLayer.r), HydraMathUtils.Abs(baseLayer.g - topLayer.g), HydraMathUtils.Abs(baseLayer.b - topLayer.b), HydraMathUtils.Abs(baseLayer.a - topLayer.a))); }
/// <summary> /// Returns the sums of the color channels. /// </summary> /// <returns>The added layers.</returns> /// <param name="baseLayer">Base layer.</param> /// <param name="topLayer">Top layer.</param> public static Color BlendAdd(Color baseLayer, Color topLayer) { return(new Color(HydraMathUtils.Min(baseLayer.r + topLayer.r, 1.0f), HydraMathUtils.Min(baseLayer.g + topLayer.g, 1.0f), HydraMathUtils.Min(baseLayer.b + topLayer.b, 1.0f), HydraMathUtils.Min(baseLayer.a + topLayer.a, 1.0f))); }
/// <summary> /// Returns the largest value in each channel. /// </summary> /// <returns>The largest channels.</returns> /// <param name="baseLayer">Base layer.</param> /// <param name="topLayer">Top layer.</param> public static Color BlendLighten(Color baseLayer, Color topLayer) { return(new Color(HydraMathUtils.Max(baseLayer.r, topLayer.r), HydraMathUtils.Max(baseLayer.g, topLayer.g), HydraMathUtils.Max(baseLayer.b, topLayer.b), HydraMathUtils.Max(baseLayer.a, topLayer.a))); }