Code works fine - as I see it there are no problems with it. But if you have any suggestions or ways to improve it I’d gladly appreciate it.
This is not true perlin - it generates a pseudo random image and suits me perfectly, but it can’t be used for seamless procedural textures without editing NoiseRGBA function.
/*
First major release of code. Most of this is recycled.
This isn't especially clean and I know I'm doing it incorrectly - but it works well enough for initially generating perlin.
steps : power of image. 2^steps
minsteps : How many images away from the top are used. Largely untested, but should make scalability much easier.
All code is mine, but you're free to use it as you please.
PUT CODE IN JS FILE IN <StandardAssets/Scripts>
Written by Windexglow
*/
static function PerlinRGBA(steps : int, minsteps : int) : Texture2D{
var maxres : float = Mathf.Pow(2, steps); //Resolution of final image. steps8 = 256
var tex : Texture2D[] = new Texture2D[steps + 1];
steps = Mathf.Clamp(steps, minsteps, 15);
minsteps = Mathf.Clamp(steps - minsteps, 1, 14);
for (i = minsteps ; i <= steps ; ++i){
//Creates noise images, than resizes them. No need to make images we won't use, hence starting i at minsteps
tex[i] = NoiseRGBA( Mathf.Pow(2, i));
tex[i] = ResizeRGBA(tex[i], maxres, maxres);
//File.WriteAllBytes(Application.dataPath + "TexPerlinRGBA" + i + ".png", tex[i].EncodeToPNG());
}
var col = Color();
var counter : float = 0.0;
var total : float = 0.0;
var Influence : float = 1.75; //This number controls how influential smaller images are.
//Lower number == images are blended more evenly (and thus more noisy)
//higher number == low-res images are blended strongly, while higher res aren't (more cloudy, smooth)
for ( x = 0 ; x <= maxres ; ++x){
for ( y=0 ; y <= maxres ; ++y){
col = tex[minsteps].GetPixel(x,y);
counter = 1.0; //starts at 1 as we added a full color already in the line above
total = 1.0; //Same reason as above
for (i = steps ; i > minsteps ; --i){
counter = counter / Influence;
total += counter;
col = col + (tex[steps + minsteps + 1 - i].GetPixel(x,y) * counter ); //blends all images together.
}
tex[steps].SetPixel(x,y, col / total ); //We divide so values fall within 0.0 - 1.0
}
}
tex[steps] = MinMaxRGBA(tex[steps]); //Optional. This line will make all channels have at least 1 pixel at 0, and 1 pixel at 1.
//File.WriteAllBytes(Application.dataPath + "RGBAperlin" + ".png", tex[steps].EncodeToPNG());
return tex[steps];
}
static function MinMaxRGBA(tex : Texture2D) : Texture2D{
//The end result will be every channel having at least 1 pixel on zero, and 1 pixel on one.
var min = Color(1,1,1,1);
var max = Color(0,0,0,0);
for ( x = 0 ; x <= tex.width ; ++x){
for ( y=0 ; y <= tex.height ; ++y){
col = tex.GetPixel(x,y);
for (i = 0 ; i <= 3 ; ++i){
if (col[i] < min[i]){
min[i] = col[i];
}
if (col[i] > max[i]){
max[i] = col[i];
}
}
}
}
var f = Color(1,1,1,1);
for ( x = 0 ; x <= tex.width ; ++x){
for ( y=0 ; y <= tex.height ; ++y){
col = tex.GetPixel(x,y);
col = col - min;
//col.a = 1.0;
f = max - min;
f = Color ( 1 / f.r, 1 / f.g, 1 / f.b, 1/ f.a);
col = col * ( f );
tex.SetPixel(x,y, col);
}
}
//Debug.Log("min=" + min + " max="+ max);
return tex;
}
static function NoiseRGBA(size : int) : Texture2D{
//Change values to fit your taste. 0 - 1 work fine for me.
var tex = Texture2D( size , size , TextureFormat.ARGB32 , false); //no mipmaps
for ( x = 0 ; x <= size ; ++x){
for ( y=0 ; y <= size ; ++y){
tex.SetPixel(x,y, Color(Random.Range(0.0, 1.0),Random.Range(0.0, 1.0),Random.Range(0.0, 1.0), Random.Range(0.0, 1.0)));
}
}
return tex;
}
public static function ResizeRGBA(tex : Texture2D , width : int , height : int ) : Texture2D{
//BILLINEAR RESIZING. Could be made more effeciant, but than it'd be a pain to edit.
var resizedImage : Texture2D = Texture2D(width, height);
var bTemp : Texture2D = Instantiate(tex, Vector3.zero, Quaternion.identity);
var fraction_x : float;
var fraction_y : float;
var one_minus_x : float;
var one_minus_y : float;
//----
var ceil_x : int ;
var ceil_y : int;
var floor_x : int;
var floor_y : int;
//----
var c1 = Color();
var c2 = Color();
var c3 = Color();
var c4 = Color();
var red : float;
var blue : float;
var green : float;
var alpha : float;
//-----
var b1 : float;
var b2 : float;
var tempw : float = bTemp.width * 1.0;
var temph : float = width * 1.0;
var nXFactor : float = tempw / temph ;
tempw = bTemp.height * 1.0;
temph = height * 1.0;
var nYFactor : float = tempw / temph;
for (x = 0 ; x < width ; ++x){
for (y = 0 ; y < height ; ++y){
floor_x = Mathf.Floor(x * nXFactor);
floor_y = Mathf.Floor(y * nYFactor);
ceil_x = floor_x + 1;
if (x > 511 x < 513 y > 511 y < 513){
}
if (ceil_x >= bTemp.width){
ceil_x = floor_x;
}
ceil_y = floor_y + 1;
if (ceil_y >= bTemp.height){
ceil_y = floor_y;
}
fraction_x = x * nXFactor - floor_x;
fraction_y = y * nYFactor - floor_y;
one_minus_x = 1.0 - fraction_x ;
one_minus_y = 1.0 - fraction_y ;
//-----
c1 = bTemp.GetPixel(floor_x, floor_y);
c2 = bTemp.GetPixel(ceil_x, floor_y);
c3 = bTemp.GetPixel(floor_x, ceil_y);
c4 = bTemp.GetPixel(ceil_x, ceil_y);
//------
//blue
b1 = (one_minus_x * c1.b + fraction_x * c2.b);
b2 = (one_minus_x * c3.b + fraction_x * c4.b);
blue = (one_minus_y * b1 + fraction_y * b2);
//green
b1 = (one_minus_x * c1.g + fraction_x * c2.g);
b2 = (one_minus_x * c3.g + fraction_x * c4.g);
green = (one_minus_y * b1 + fraction_y * b2);
//red
b1 = (one_minus_x * c1.r + fraction_x * c2.r);
b2 = (one_minus_x * c3.r + fraction_x * c4.r);
red = (one_minus_y * b1 + fraction_y * b2);
b1 = (one_minus_x * c1.a + fraction_x * c2.a);
b2 = (one_minus_x * c3.a + fraction_x * c4.a);
alpha = (one_minus_y * b1 + fraction_y * b2);
//------
resizedImage.SetPixel(x,y, Color(red, green, blue, alpha));
}
}
// resizedImage.Apply();
Destroy (bTemp);
Destroy (tex);
return resizedImage;
}
steps = 9, minsteps = 5
http://img836.imageshack.us/img836/1210/assetsrgbaperlin.png
steps = 10, minsteps = 5. This shows off possible scalability
http://img24.imageshack.us/img24/1210/assetsrgbaperlin.png
steps = 10, ministeps = 10. This uses all steps to blend together - alpha layer (black) makes image ugly.
http://img259.imageshack.us/img259/1210/assetsrgbaperlin.png