/// <summary> /// Creates average intensity Color32 array. /// </summary> /// <param name="colors">Source Color32 array.</param> /// <returns>Average intensity Color32 array.</returns> public static Color32[] MakeAverageIntensity(Color32[] colors) { Color32[] newColors = (Color32[])colors.Clone(); // Make each pixel grayscale based on average intensity for (int i = 0; i < colors.Length; i++) { // Get average intensity Color32 srcColor = colors[i]; int intensity = (srcColor.r + srcColor.g + srcColor.b) / 3; Color32 dstColor = new Color32((byte)intensity, (byte)intensity, (byte)intensity, srcColor.a); newColors[i] = dstColor; } return newColors; }
/// <summary> /// Applies filter to input Color32 array. /// </summary> /// <param name="colors">Source Color32 array.</param> /// <param name="width">Image width.</param> /// <param name="height">Image height.</param> /// <returns>New Color32 array with filter applied.</returns> public Color32[] ApplyFilter(Color32[] colors, int width, int height) { Color32[] newColors = (Color32[])colors.Clone(); for (int x = 0; x < width; ++x) { for (int y = 0; y < height; ++y) { int weight = 0; int r = 0, g = 0, b = 0, a = 0; int curX = -FilterWidth / 2; for (int x2 = 0; x2 < FilterWidth; ++x2) { int sampleX = curX + x; // Sample point is wrapped to avoid seams in edge-finding filters if (sampleX < 0) sampleX = width - 1; if (sampleX >= width) sampleX = 0; int curY = -FilterHeight / 2; for (int y2 = 0; y2 < FilterHeight; ++y2) { int sampleY = curY + y; // Sample point is wrapped to avoid seams in edge-finding filters if (sampleY < 0) sampleY = height - 1; if (sampleY >= height) sampleY = 0; Color32 pixel = colors[sampleY * width + sampleX]; r += MyFilter[x2, y2] * pixel.r; g += MyFilter[x2, y2] * pixel.g; b += MyFilter[x2, y2] * pixel.b; a = pixel.a; weight += MyFilter[x2, y2]; ++curY; } ++curX; } Color32 meanPixel = colors[y * width + x]; if (weight == 0) weight = 1; if (weight > 0) { if (Absolute) { r = System.Math.Abs(r); g = System.Math.Abs(g); b = System.Math.Abs(b); } r = (r / weight) + Offset; r = Clamp(r, 0, 255); g = (g / weight) + Offset; g = Clamp(g, 0, 255); b = (b / weight) + Offset; b = Clamp(b, 0, 255); meanPixel = new Color32((byte)r, (byte)g, (byte)b, (byte)a); } newColors[y * width + x] = meanPixel; } } return newColors; }
/// <summary> /// Converts bump map to normal map. /// </summary> /// <param name="colors">Source Color32 array.</param> /// <param name="strength">Normal strength.</param> /// <returns>Color32[] normal map.</returns> public static Color32[] ConvertBumpToNormals(ref Color32[] colors, int width, int height, float strength = 1) { Color32[] newColors = (Color32[])colors.Clone(); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { // Look up the heights to either side of this pixel float left = GetIntensity(ref colors, x - 1, y, width, height); float right = GetIntensity(ref colors, x + 1, y, width, height); float top = GetIntensity(ref colors, x, y - 1, width, height); float bottom = GetIntensity(ref colors, x, y + 1, width, height); // Compute gradient vectors, then cross them to get the normal Vector3 dx = new Vector3(1, 0, (right - left) * strength); Vector3 dy = new Vector3(0, 1, (bottom - top) * strength); Vector3 normal = Vector3.Cross(dx, dy); normal.Normalize(); // Store result packed for Unity byte r = (byte)((normal.x + 1.0f) * 127.5f); byte g = (byte)(255 - ((normal.y + 1.0f) * 127.5f)); newColors[y * width + x] = new Color32(g, g, g, r); //// This is a standard normal texture without Unity packing //newColors[y * width + x] = new Color32( // (byte)((normal.x + 1.0f) * 127.5f), // (byte)(255 - ((normal.y + 1.0f) * 127.5f)), // (byte)((normal.z + 1.0f) * 127.5f), // 0xff); } } return newColors; }