/* * Beach ball displacement shader for mapping onto a sphere, * allowing variable amounts of inflation. Assumes +y axis = up * * Mark Fontana * Digital Lighting, SP 96 * */ #include "/usr/local/accad/shaders/rmannotes.sl" displacement beachball_disp(point ball_center = (0,0,0); float ball_radius = 1.0, inflatedness = 1.0, crumplyness = 0.5) { float magnitude, dist, ht_frac; point PP; float flatness = 3, width, cutoff, fade, turb, maxfreq = 10, f; /* smush ball in the y-axis as it deflates */ dist = abs(ycomp(P)-(ycomp(ball_center)-ball_radius)); ht_frac = dist/(2.0*ball_radius); /* fraction of max height */ setycomp(P, ycomp(P) - dist*0.7*ht_frac*(1-inflatedness*ht_frac*(1-inflatedness)) *(1-inflatedness) - (ball_radius*(1.0-inflatedness))); /* crumple it with some turbulence */ PP = transform("shader", P); width = filterwidth_point(PP); cutoff = clamp(0.5 / width, 0, maxfreq); turb = 0; for (f = 1; f < 0.5 * cutoff; f *= 2) turb -= abs(snoise(PP * f)) / f; fade = clamp(2 * (cutoff - f) / cutoff, 0, 1); turb -= fade * abs(snoise(PP * f)) / f; magnitude = pow(turb, flatness)*(1.0-inflatedness*inflatedness); P += crumplyness*(1-inflatedness) * magnitude * normalize(Ng); N = calculatenormal(P); }