Last active
July 15, 2016 16:35
-
-
Save n-yoda/8494984 to your computer and use it in GitHub Desktop.
[UNITY] Generate texture from a function : UV => Color.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using UnityEditor; | |
using System; | |
using System.IO; | |
public static class TextureGenerator | |
{ | |
static string GetNewPath(string name) | |
{ | |
string path = AssetDatabase.GetAssetPath(Selection.activeObject); | |
if (string.IsNullOrEmpty(path)) | |
{ | |
path = "Assets"; | |
} | |
else if (Path.GetExtension(path) != "") | |
{ | |
path = Path.GetDirectoryName(AssetDatabase.GetAssetPath(Selection.activeObject)); | |
} | |
return AssetDatabase.GenerateUniqueAssetPath(path + "/" + name); | |
} | |
static float[,] GenerateFilter(int size) | |
{ | |
var filter = new float[size, size]; | |
var sigma = size / 6f; | |
var a = 0.5f / Mathf.PI / sigma / sigma; | |
var b = -0.5f / sigma / sigma; | |
var sub = (size - 1) * 0.5f; | |
float sum = 0f; | |
for (int i = 0; i < size; i++) | |
{ | |
for (int j = 0; j < size; j++) | |
{ | |
// gaussian | |
// filter[i, j] = a * Mathf.Exp(b * new Vector2(i - sub, j - sub).sqrMagnitude); | |
// average | |
filter[i, j] = 1f / (size * size); | |
sum += filter[i, j]; | |
} | |
} | |
// normalize | |
float mul = 1f / sum; | |
for (int i = 0; i < size; i++) | |
for (int j = 0; j < size; j++) | |
filter[i, j] *= mul; | |
return filter; | |
} | |
public static void Generate( | |
string name, int width, int height, int smooth, Func<float, float, Color> uv2c) | |
{ | |
var around = 1f; // collect colors in this range | |
smooth = Mathf.Max(1, smooth); | |
int units = 2 + (smooth - 1) * 2; | |
var div = 1f / (smooth * smooth); | |
var unit = new Vector2(1f / width, 1f / height); | |
var offset = (around - 1) * 0.5f; | |
var sUnit = (unit / units) * around; | |
var filter = GenerateFilter(smooth); | |
var pixels = new Color[width * height]; | |
for (int x = 0; x < width; x++) | |
{ | |
for (int y = 0; y < height; y++) | |
{ | |
Vector4 avg = Vector4.zero; | |
for (int dx = 0; dx < smooth; dx++) | |
{ | |
for (int dy = 0; dy < smooth; dy++) | |
{ | |
var col = (Vector4)uv2c( | |
(x - offset) * unit.x + dx * 2 * sUnit.x + sUnit.x, | |
(y - offset) * unit.y + dy * 2 * sUnit.y + sUnit.y | |
); | |
avg += col * filter[dx, dy]; | |
} | |
} | |
pixels[x + y * width] = (Color)avg; | |
} | |
} | |
var texture = new Texture2D(width, height); | |
texture.SetPixels(pixels); | |
texture.Apply(); | |
var path = GetNewPath(name); | |
System.IO.File.WriteAllBytes(path, texture.EncodeToPNG()); | |
AssetDatabase.ImportAsset(path); | |
} | |
[MenuItem("Assets/TextureGenerator/Indicator")] | |
public static void GenerateIndicator() | |
{ | |
Generate("Indicator.png", 128, 128, 5, (u, v) => | |
{ | |
var color = Color.magenta; | |
var x = new Vector2(u - 0.5f, v - 0.5f); | |
if (0.32f < x.magnitude && x.magnitude < 0.5f) | |
color.a = (Mathf.Atan2(x.y, x.x) / Mathf.PI + 1f) * 0.45f; | |
else | |
color.a = 0; | |
return color; | |
}); | |
} | |
[MenuItem("Assets/TextureGenerator/Circle")] | |
public static void GenerateCircle() | |
{ | |
Generate("Circle.png", 200, 200, 5, (u, v) => | |
{ | |
var x = new Vector2(u - 0.5f, v - 0.5f); | |
if (x.magnitude < 0.3f) | |
return Color.black; | |
else | |
return Color.white; | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment