blog games developers documentation portfolio gallery

More in this category:

Handy Unity3D C# functions (3. create textures)

Posted on May 22, 2014, by Richard Knol

In the previous post we defined some functions for dealing with colors. Since an image is not much more that a collection of colors, let's expand our color functions to the Unity3D Texture2D.

The functions below were written for the Unity3D AssetStore package Texture2D+. It adds functions to the Unty API for converting colors to and from Hex, convert colors between RGB and HSB. And allows you to perform basic image manipulation like scale, rotate, crop, contrast, etc on Textures. Feel free to use this code, but it might be easier to just get the complete package. Here's the link to Texture2D+ in the AssetStore and here's the link to the documentation.

Create empty texture


Let's start simple by creating a new image (as a Texture2D) and give all the pixels the same color.
public static Texture2D GetEmptyTexture(int w, int h, Color color) {
Texture2D img = new Texture2D(w, h, TextureFormat.RGBA32, false);
Color[] pixels = img.GetPixels(0);
for (int i = 0; i < pixels.Length; i++) {
pixels[i] = color;
}
img.SetPixels(pixels, 0);
img.Apply();
return img;
}


Create rainbow textures


A single color is boring. Do you know the color pickers in image editors? They have these rainbow-like textures to select a color from. Typically these work by using the HSB color scheme. But since textures are 2D and HSB has 3 dimensions, the color picking images are made by setting one of the 3 dimensions H, S or B to a fixed value and letting the other 2 vary.

Here's how to do that (you also need the MakeColor() function which was discussed in the previous post):
public static Texture2D GetHSTexture(int width, int height, float brightness) {
Texture2D img = new Texture2D(width, height, TextureFormat.RGBA32, false);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color p = MakeColor(new Vector3((float)x/width, (float)y/height, brightness));
img.SetPixel(x, y, p);
}
}
img.Apply();
return img;
}
public static Texture2D GetHBTexture(int width, int height, float saturation) {
Texture2D img = new Texture2D(width, height, TextureFormat.RGBA32, false);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color p = MakeColor(new Vector3((float)x/width, saturation, (float)y/height));
img.SetPixel(x, y, p);
}
}
img.Apply();
return img;
}
public static Texture2D GetSBTexture(int width, int height, float hue) {
Texture2D img = new Texture2D(width, height, TextureFormat.RGBA32, false);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color p = MakeColor(new Vector3(hue, (float)x/width, (float)y/height));
img.SetPixel(x, y, p);
}
}
img.Apply();
return img;
}


Create color slider textures


Since the color picker texture only shows 2 dimensions (i.e. H and S or H and B), the 3rd dimension is often represented in a linear slider texture. When the user moves the cursor through the color picking texture, the slider changes dynaically. This means the slider texture needs to be made on the fly. Like so:
	public static Texture2D GetHTexture(int width, int height, float saturation, float brightness) {
Texture2D img = new Texture2D(width, height, TextureFormat.RGBA32, false);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color p = (width > height)
? MakeColor(new Vector3((float)x/width, saturation, brightness))
: MakeColor(new Vector3((float)y/height, saturation, brightness));
img.SetPixel(x, y, p);
}
}
img.Apply();
return img;
}
public static Texture2D GetSTexture(int width, int height, float hue, float brightness) {
Texture2D img = new Texture2D(width, height, TextureFormat.RGBA32, false);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color p = (width > height)
? MakeColor(new Vector3(hue, (float)x/width, brightness))
: MakeColor(new Vector3(hue, (float)y/height, brightness));
img.SetPixel(x, y, p);
}
}
img.Apply();
return img;
}
public static Texture2D GetBTexture(int width, int height, float hue, float saturation) {
Texture2D img = new Texture2D(width, height, TextureFormat.RGBA32, false);
Vector3 hsb = Converter.MakeHSB(color);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color p = (width > height)
? MakeColor(new Vector3(hue, saturation, (float)x/width))
: MakeColor(new Vector3(hue, saturation, (float)y/height));
img.SetPixel(x, y, p);
}
}
img.Apply();
return img;
}


Create alpha slider texture


To make the whole set complete, lets make a slider texture for the 4th color dimension: alpha.
public static Texture2D GetATexture(int width, int height, Color color) {
Texture2D img = new Texture2D(width, height, TextureFormat.RGBA32, false);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
Color p = color;
p.a = (width > height)
? (float)x/width
: (float)y/height;
img.SetPixel(x, y, p);
}
}
img.Apply();
return img;
}


Note that you need the MakeColor() function which was discussed in the previous post.
public static Color MakeColor(Vector3 hsb) {
return MakeColor(new Vector4(hsb.x, hsb.y, hsb.z, 1.0f));
}
public static Color MakeColor(Vector4 hsba) {
// When saturation = 0, then r, g, b represent grey value (= brightness (z)).
float r = hsba.z;
float g = hsba.z;
float b = hsba.z;
if(hsba.y > 0.0f) { // saturation > 0
// Calc sector
float secPos = (hsba.x * 360.0f) / 60.0f;
int secNr = Mathf.FloorToInt(secPos);
float secPortion = secPos - secNr;

// Calc axes p, q and t
float p = hsba.z * (1.0f - hsba.y);
float q = hsba.z * (1.0f - (hsba.y * secPortion));
float t = hsba.z * (1.0f - (hsba.y * (1.0f - secPortion)));

// Calc rgb
if(secNr == 1) {
r = q;
g = hsba.z;
b = p;
} else if(secNr == 2) {
r = p;
g = hsba.z;
b = t;
} else if(secNr == 3) {
r = p;
g = q;
b = hsba.z;
} else if(secNr == 4) {
r = t;
g = p;
b = hsba.z;
} else if(secNr == 5) {
r = hsba.z;
g = p;
b = q;
} else {
r = hsba.z;
g = t;
b = p;
}
}
return new Color(r, g, b, hsba.w);
}








follow us