/* * 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. */ /* * A cheesy hurricane model. * * Eye of the storm is centered on z axis. * * Called as: * texture cyclone 1 .5 0.7 0.5 0.675 4 0.7 0.3 3.5 0.025 1.5 0.25 * ("colour" is a pale yellow, not specified above) */ void Cyclone( Vector texture, Vector intersect, Colour *colour, double max_radius, double twist, double scale, double offset, double omega, double octaves, double p0, double p1, double p2, double p3, double p4, double p5 ) { double radius, dist, angle, sine, cosine, eye_weight, value; Vector point; double power, detail_height; /* rotate hit point to "cyclone space" */ radius = sqrt(intersect.x*intersect.x + intersect.y*intersect.y); if ( radius < max_radius ) { /* inside of cyclone */ /* invert distance from center */ dist = max_radius - radius; dist *= dist; dist *= dist; angle = PI + twist*TWOPI * (max_radius-dist)/max_radius; sine = sin( angle ); cosine = cos( angle ); point.x = texture.x*cosine - texture.y*sine; point.y = texture.x*sine + texture.y*cosine; point.z = texture.z; /* add "eye" of storm */ if (radius < p3*max_radius) { /* normalize */ eye_weight = (p3*max_radius-radius)/p3; eye_weight = 1.0 - eye_weight; /* invert */ eye_weight *= eye_weight; /* make nonlinear */ eye_weight *= eye_weight; } else eye_weight = 1.0; /* raise density towards center */ value = (1.0 - radius/max_radius); value *= p0 * value; } else { eye_weight = 1.0; point = texture; value = 0.0; } if ( eye_weight ) { /* "VLfBm()" is fBm built from "VLNoise()" */ value += offset + scale*VLfBm( point, omega, 2., octaves ); /* blacken the "eye" */ value *= eye_weight; } else value = 0.0; /* add fine-grain, undistorted cloud texture */ power = pow( 2., p2 ); point = texture; SCALE( power, point ); detail_height = p4*VLfBm( point, omega, 2., octaves ); if ( detail_height < 0.0 ) detail_height = - detail_height; value *= value-p5 + value*detail_height; if ( value < 0.0 || !eye_weight ) value = 0.0; if ( value > 1.0 ) value = 1.0; colour->red *= value + (1.0-value)*Background.red; colour->green *= value + (1.0-value)*Background.green; colour->blue *= value + (1.0-value)*Background.blue; } /* Cyclone() */