class Planet{ boolean isDone = false; int noiseSeed; float terrainSharpness = 0.5; color oceanA, oceanB, landA, landB; color cloud, atmosphere; float scale; float radius, atmosphereThickness; float hazeMax, hazeOuter, hazeInner, terrainContrast, cloudContrast; float bumpDepth, specularSize, specularMax; float terrainScale, textureScale, cloudScale, dryness; float ambient; // the vector of the infalling light float[] light = { -0.577,-0.577,0.577 }; float[] specular; //----------- Planet(){ noiseSeed = 5; //dryness = 0.5; terrainScale = 0.02; textureScale = 0.1; cloudScale = 0.05; cloudContrast = 0.8; terrainContrast = 0.7; //bumpDepth = 0.0; specularSize = 0.1; specularMax = 0.99; radius = 80; hazeOuter = 5; hazeInner = 20; hazeMax = 0.75; ambient = 0.1; cloud = color(255); atmosphere = color(255,255,255); oceanA = color( 0x787878 ); oceanB = color( 50, 50,255); landA = color( 64,128, 0); landB = color( 0x787878 ); noiseSeed(noiseSeed); calculateSpecular(); noiseDetail(8,0.5); } //----------- // A planet "lives" in a square that is 200*200 pixels // higher resolution images simply means sampling at fractional pixels Planet(int randomSeed){ randomSeed(randomSeed); noiseSeed = (int) random(100); //dryness = random(0,1); terrainScale = pow(0.05,random(1,3)); textureScale = pow(0.5,random(1,2)); cloudScale = pow(0.2,random(1,3)); cloudContrast = random(0,1); terrainContrast = random(0,1); //bumpDepth = 0.1; specularSize = 0.01; specularMax = 0.2; radius = 85; hazeOuter = random(5,10); hazeInner = random(5,30); hazeMax = random(0.9,1); ambient = 0.1; cloud = color(255); atmosphere = deviateColor( color(255-32), 32 ); oceanA = randomColor(); oceanB = deviateColor( oceanA, 64 ); landA = randomColor(); landB = deviateColor( landA, 64 ); noiseSeed(noiseSeed); noiseDetail(8,0.5); calculateSpecular(); light = normalizedVector(1,-1,2); } //----------- float[] normalizedVector(float x, float y, float z){ float d = mag(x,y,z); return new float[]{ x/d, y/d, z/d }; } //----------- void calculateSpecular(){ specular = new float[3]; specular[0] = light[0]/2; specular[1] = light[1]/2; specular[2] = (light[2]+1)/2; float magnitude = mag(specular[0], specular[1], specular[2]); specular[0] = specular[0] / magnitude; specular[1] = specular[1] / magnitude; specular[2] = specular[2] / magnitude; } //----------- void render(int[] pixelArray, int w, int h, int supersample, color background){ float pixelWidth = 200.0/w; for( int i=0 ; i0){ for( int si=0 ; si0) ? pow(0.5,atmThick/hazeOuter) : pow(0.5,-atmThick/hazeInner); float lightning = ambient + (1-ambient) * incidentAngleShading(x,y,z); return lerpColor( background, atmosphere, density*hazeMax*lightning); } //----------------------------- color addCloud(float x, float y, float z, color background){ float cloudiness = contrast( perlin(x,y,z,cloudScale), cloudContrast); float shading = ambient + (1-ambient) * incidentAngleShading(x,y,z); return lerpColor( background, cloud, cloudiness*sq(shading) ); } //----------------------------- color addSpecular(float x, float y, float z, color background){ float specularValue = (x*specular[0] + y*specular[1] + z*specular[2]) / radius; specularValue = addBump(x,y,z,terrainScale,specularValue); if(specularValue<1-specularSize) return background; float specularBlend = (specularValue-(1-specularSize))/specularSize; return lerpColor( background, color(255), specularMax*specularBlend ); } //----------------------------- color terrainColor(float x, float y, float z){ float shading = ambient + (1-ambient) * incidentAngleShading(x,y,z); return lerpColor( color(0), texture(x,y,z), shading); } //----------------------------- float addBump(float x, float y, float z, float bumpScale, float incidentAngle){ float bump = bumpDepth * (perlin(x,y,z,bumpScale) - 0.5); return constrain( incidentAngle+bump, 0, 1); } //----------------------------- float incidentAngleShading(float x, float y, float z){ float incidentAngle = (x*light[0] + y*light[1] + z*light[2]) / radius; return constrain( incidentAngle, 0, 1); } //----------------------------- color texture(float x, float y, float z){ float terrainBlend = contrast( perlin(x+4711,y,z,terrainScale), terrainContrast ); float textureBlend = perlin(x,y,z,textureScale); color c1 = lerpColor(oceanA, oceanB, textureBlend); color c2 = lerpColor(landA, landB, textureBlend); return lerpColor(c1, c2, terrainBlend); } //----------------------------- // Increases the contrast by bezier interpolation float contrast(float x, float contrast){ for(float i=0 ; i0.5+c/2) return 1; else return (x-(0.5-c/2))/c; } //----------------------------- float perlin(float x, float y, float z, float s){ return noise(s*x+10,s*y+20,s*z+30); } }