Skip to content

Instantly share code, notes, and snippets.

@n-yoda
Last active July 15, 2016 16:35
Show Gist options
  • Save n-yoda/8494984 to your computer and use it in GitHub Desktop.
Save n-yoda/8494984 to your computer and use it in GitHub Desktop.
[UNITY] Generate texture from a function : UV => Color.
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