/* * C code used to produce images appearing in: * * "Texturing and Modeling: A Procedural Approach," by David S. Ebert, ed., * F. Kenton Musgrave, Darwyn Peachey, Ken Perlin, and Steven Worley. * Academic Press, 1998. ISBN 0-12-228730-4. * * Note that this is the original C texture code, on which the Larry Gritz's * RenderMan shaders that appear in the text were based. * * Copyright 1998 F. Kenton Musgrave * All rights reserved. */ /* * "Earth" planet texture, as re-developed to illustrate process * * Called as: * texture earth earth_map 0.25 2. -.48 11. 0. 0.45 300. 2.6 0.7 20 0.75 220 170 20 0.6 4.0 * 1.125 1.2 -0.085 1 0.3 0 * (colormap "earth_map" lives in ../Colormaps) */ void Earth( Vector texture, Vector intersect, Vector *normal, Colour *colour, Colour *cmap, double spectral_exp, double lacunarity, double octaves, double bump_scale, int multifractal, double dist_scale, double offset, double sea_level, double mtn_scale, double lat_scale, double nonlinear, double purt_scale, double map_exp, double ice_caps, double depth_scale, double depth_max, double mottle_limit, double mottle_scale, double mottle_dim, double mottle_mag ) { Vector bump, distort, point; double chaos, latitude, purt; Colour color; int index; /* * Choose between fractal bump functions: * "ordinary" or multifractal fBm. */ if ( !multifractal ) /* use a "standard" fBm bump function */ bump = VecfBm(texture, spectral_exp, lacunarity, octaves ); else { /* use "multifractal" fBm bump function */ /* get "distortion" vector, as used with clouds */ distort = VecNoise( texture ); /* scale distortion vector */ SCALE( dist_scale, distort ); /* insert distortion vector */ texture = VEC_ADD( distort, texture ); /* compute bump vector using displaced point */ /* (using vector-valued multifractal) */ bump = MVfBm(texture, spectral_exp, lacunarity, octaves ); } /* get the "height" of the bump, displacing by offset */ chaos = -DOT(bump, *normal) + offset; /* set bump for land masses (areas above "sea level") */ if ( chaos > sea_level ) { chaos *= mtn_scale; sea_level *= mtn_scale; normal->x += bump_scale * bump.x; normal->y += bump_scale * bump.y; normal->z += bump_scale * bump.z; Unit(normal); } /* if there's a colormap assoc. with the texture, use it */ if( cmap ) { /* use a scaled "z" value for offset in color map */ latitude = intersect.z; /* make climate symmetric about equator */ if ( latitude < 0. ) latitude = -latitude; /* fractally purturb color map offset using "chaos" */ /* "nonlinear" scales purturbation-by-z */ /* "purt_scale" scales overall purturbation */ latitude += chaos*(nonlinear*(1.-latitude) + purt_scale); if ( map_exp ) latitude = lat_scale*pow(latitude,map_exp); else latitude *= lat_scale; if ( chaos > sea_level ) index = 1 + (int)(latitude); else index = 0; /* ocean color is in map entry 0 */ /* do oceans, adjusted for polar caps */ if ( ice_caps && latitude>ice_caps && index==0 ) index = 255; /* clamp color map offset to bounds */ if ( index > 255 ) index = 255; if ( index < 0 ) index = 0; /* set surface color to calculated color map entry */ color = cmap[index]; /* darken the "deep waters" */ if ( index == 0 ) { chaos -= sea_level; chaos *= depth_scale; chaos = MAX( chaos, -depth_max ); color.red += chaos * color.red; color.green += chaos * color.green; color.blue += chaos * color.blue; } /* else mottle the color some */ /* ("mottle_limit" ensures the poles stay white) */ else if ( index < mottle_limit ) { point = texture; SMULT(mottle_scale, point); purt = fBm( point, mottle_dim, 2., 8. ); color.red += color.red * 0.5*mottle_mag*purt; color.green += color.green * 0.175*mottle_mag*purt; color.blue += color.green * 0.5*mottle_mag*purt; if ( color.red < 0. ) color.red = 0.; if ( color.green < 0. ) color.green = 0.; if ( color.blue < 0. ) color.blue = 0.; if ( color.red > 1. ) color.red = 1.; if ( color.green > 1. ) color.green = 1.; if ( color.blue > 1. ) color.blue = 1.; } *colour = color; } } /* Earth() */