/* I took wave's lead and renamed starfield to KMTerranbump.sl -- tal@cs.caltech.edu */ /* * terranbump.sl - displacement for an Earth-like planet. * * * DESCRIPTION: * When put on a sphere, makes displacements to make Earth-like * mountains and oceans. The shader works by using a variety of fractal * turbulence and mottling techniques. * Note that there is a companion surface shader "terran". You need * to use exactly the same parameters for "terran" and "terranbump" to * get them to work well together. * * * PARAMETERS: * spectral_exp, lacunarity, octaves - control the fractal characteristics * of the bump pattern. * bump_scale - scaling of the mountains * multifractal - zero uses fBm noise, nonzero uses multifractal * dist_scale - scaling for multifractal distortion * offset - elevation offset * sea_level - obvious * * * HINTS: * The default values for the shader assume that the planet is * represented by a unit sphere. The texture space and/or parameters * to this shader will need to be altered if the size of your planet * is radically different. * For best results, use with the "terran" surface shader, and * add a cloud layer using either "planetclouds" or "venusclouds". * * * AUTHOR: Ken Musgrave. * Conversion to Shading Language and minor modifications by Larry Gritz. * * * REFERENCES: * * * HISTORY: * ???? - original texture developed by F. Ken Musgrave. * Feb 1994 - Conversion to Shading Language by L. Gritz * * last modified 1 March 1994 by lg */ #ifdef BMRT #define snoise(x) (2*(noise(x)-0.5)) #else /* This is because PRMAN's noise has less range than BMRT's */ #define snoise(x) (2.5*(noise(x)-0.5)) #endif #define DNoise(x) ((2*(point noise(x))) - point(1,1,1)) #define VLNoise(Pt,scale) (snoise(DNoise(Pt)+(scale*Pt))) #define N_OFFSET 0.7 #define VERY_SMALL 0.0001 displacement KMTerranbump (float spectral_exp = 0.5; float lacunarity = 2, octaves = 7; float bump_scale = 0.04; float multifractal = 0; float dist_scale = .2; float offset = 0; float sea_level = 0;) { float chaos; point Ptexture, tp; float l, o, a, i, weight; /* Loop variables for fBm calc */ float bumpy; /* Do all shading in shader space */ Ptexture = transform ("shader", P); if (multifractal == 0) { /* use a "standard" fBm bump function */ o = 1; l = 1; bumpy = 0; for (i = 0; i < octaves; i += 1) { bumpy += o * snoise (l * Ptexture); l *= lacunarity; o *= spectral_exp; } } else { /* use a "multifractal" fBm bump function */ /* get "distortion" vector, as used with clouds */ Ptexture += dist_scale * DNoise (Ptexture); /* compute bump vector using MfBm with displaced point */ o = spectral_exp; tp = Ptexture; weight = abs (VLNoise (tp, 1.5)); bumpy = weight * snoise (tp); for (i = 1; i < octaves && weight >= VERY_SMALL; i += 1) { tp *= lacunarity; /* get subsequent values, weighted by previous value */ weight *= o * (N_OFFSET + snoise(tp)); weight = clamp (abs(weight), 0, 1); bumpy += snoise(tp) * min (weight, spectral_exp); o *= spectral_exp; } } /* get the "height" of the bump, displacing by offset */ chaos = bumpy + offset; /* set bump for land masses (i.e., areas above "sea level") */ if (chaos > sea_level) P += (bump_scale * bumpy) * normalize(Ng); /* Recalculate the surface normal (this is where all the real magic is!) */ N = calculatenormal (P); }