/* Sphere ------ This script generates a tileable texture with lots of spheres randomly placed on it. Author : Andreas Jonsson Created: April 17th, 2005 Updated: July 28th, 2005 Texture Generator version 1.1.0 */ randomizer rnd; void main() { int m = 1; image @img = @image(256*m, 256*m); int n = 0; while( n++ < 200 ) { int x = int(rnd.getNumber() * float(256*m)); int y = int(rnd.getNumber() * float(256*m)); float r = 7.5f*float(m) + rnd.getNumber()*20.0f*float(m); sphere(@img, x, y, 20.0f); } light(@img, 0.4f, 0.23f, 2.0f); img.Show(); } void sphere(image @img, int x, int y, float r) { int w = img.width; int h = img.height; if( int(r) > w or int(r) > h ) return; int cx = x; int cy = y; int sx = cx - int(r); int sy = cy - int(r); int ex = cx + int(r); int ey = cy + int(r); float fx = float(x); float fy = float(y); y = sy; while( y <= ey ) { x = sx; while( x <= ex ) { float fx = float(cx - x); float fy = float(cy - y); if( fx*fx + fy*fy <= r*r ) { // Compute height of the sphere at this location float fd2 = fx*fx + fy*fy; float fh = sqrt(r*r - fd2); // Put this height at the pixel int px = x; int py = y; if( px < 0 ) px = px + w; if( py < 0 ) py = py + h; if( px >= w ) px = px - w; if( py >= h ) py = py - h; float old = img.Alpha(px, py); if( old < fh ) { img.Pixel(px, py) = pixel(fh, fx/r, fy/r, fh/r); } } x++; } y++; } } void light(image @img, float dx, float dy, float dz) { // Normalize light vector float l = sqrt(dx*dx + dy*dy + dz*dz); dx = dx/l; dy = dy/l; dz = dz/l; int w = img.width; int h = img.height; int y = 0; while( y < h ) { int x = 0; while( x < w ) { // Get surface normal float sx = img.Red(x,y); float sy = img.Green(x,y); float sz = img.Blue(x,y); // Normalize l = sqrt(sx*sx + sy*sy + sz*sz); if( l > 0.0 ) { sx = sx/l; sy = sy/l; sz = sz/l; // Compute dot product float d = dx*sx + dy*sy + dz*sz; img.Pixel(x,y) = pixel(d,d,d); } x++; } y++; } } image @shrink2(image @img) { int w = img.width/2; int h = img.height/2; image @mip = @image(w, h); int x = 0; while( x < w ) { int y = 0; while( y < h ) { int c = 0; while( c < 3 ) { float v = img.Channel(2*x, 2*y, c) + img.Channel(2*x+1, 2*y, c) + img.Channel(2*x, 2*y+1, c) + img.Channel(2*x+1, 2*y+1, c); v = 0.25*v; mip.Channel(x,y,c) = v; c++; } mip.Alpha(x,y) = 1.0; y++; } x++; } return @mip; }