/* Cloud ----- This script generates a tilable cloud texture, similar to the cloud filter in Adobe Photoshop. Author : Andreas Jonsson Created: June 16th, 2003 Updated: July 28th, 2005 Texture Generator version 1.1.0 */ const int startSize = 2; const int numOctaves = 7; const float amplitudeFactor = 0.5; randomizer rnd; void addRandom(image @img, float amp) { int x, y; int w = img.width; int h = img.height; x = 0; while( x < w ) { y = 0; while( y < h ) { float r = amp*(2.0*rnd.getNumber()-1.0); img.Alpha(x, y) += r; ++y; } ++x; } } void boxBlurAlpha(image @img, int bw, int bh) { int x, y; int w = img.width; int h = img.height; //-------------- // smooth x float[] line(w); y = 0; while( y < h ) { // Copy original pixels to the line buffer x = 0; while( x < w ) { line[x] = img.Alpha(x, y); ++x; } // Compute sum of first bw pixels x = 0; float sum = 0.0; while( x < bw ) { sum += line[x]; ++x; } // Set blurred pixels x = 0; while( x < w ) { img.Alpha((x+bw/2)%w, y) = sum/float(bw); sum -= line[x]; sum += line[(x+bw)%w]; ++x; } ++y; } //--------------- // smooth y line.resize(h); x = 0; while( x < w ) { // Copy original pixels to the line buffer y = 0; while( y < h ) { line[y] = img.Alpha(x,y); ++y; } // Compute sum of first bw pixels y = 0; float sum = 0.0; while( y < bh ) { sum += line[y]; ++y; } // Set blurred pixels y = 0; while( y < h ) { img.Alpha(x, (y+bh/2)%h) = sum/float(bh); sum -= line[y]; sum += line[(y+bh)%h]; ++y; } ++x; } } image @cloud(int start, int octaves, float ampMod) { image @img = @image(start, start); float amp = 1.0; addRandom(@img, amp); while( --octaves >= 0 ) { img.Resize(img.width*2, img.height*2); boxBlurAlpha(@img, 3, 3); amp *= ampMod; addRandom(@img, amp); } // blur the image one last time boxBlurAlpha(@img, 3, 3); return @img; } void normalize(image @img) { int x, y; int w = img.width; int h = img.height; // find the highest and lowest values used float hi = 0.0, lo = 1.0; y = 0; while( y < h ) { x = 0; while( x < w ) { float v = img.Alpha(x, y); if( v < lo ) lo = v; if( v > hi ) hi = v; ++x; } ++y; } // normalize the image y = 0; hi = 1.0/(hi-lo); while( y < h ) { x = 0; while( x < w ) { float v = img.Alpha(x, y); v = (v-lo)*hi; img.Alpha(x,y) = v; ++x; } ++y; } } void alpha2Color(image @img) { int x, y; int w = img.width; int h = img.height; y = 0; while( y < h ) { x = 0; while( x < w ) { float a = img.Alpha(x, y); img.Pixel(x,y) = pixel(a, a, a); ++x; } ++y; } } void main() { image @img = @cloud(startSize, numOctaves, amplitudeFactor); normalize(@img); alpha2Color(@img); img.Show(); }