/* * Icy surface/displacement shader * * Mark Fontana * Digital Lighting, SP 96 * */ /* You'll get a warning when compiling this because it does displacement */ /* as well as surface shading. */ #include "/usr/local/accad/shaders/rmannotes.sl" surface icy(float icicle_length = 0.1, icicle_freq = 6, Ks = 0.9, Kd = 0.7, Ka = 0.3, roughness= 0.9) { point NN, Nf; point V = -normalize(I); float magnitude, dist, dx, dy, dz; point PP, P_orig; float width, cutoff, fade, turb1, turb2, maxfreq = 16, f; uniform point down = (0,-1,0); PP = transform("shader", P) * icicle_freq; width = filterwidth_point(PP); cutoff = clamp(0.5 / width, 0, maxfreq); turb1 = 0; for (f = 1; f < 0.5 * cutoff; f *= 2) turb1 += abs(snoise(PP * f)) / f; fade = clamp(2 * (cutoff - f) / cutoff, 0, 1); turb1 += fade * abs(snoise(PP * f)) / f; turb2 = 0; for (f = 1; f < 0.5 * cutoff; f *= 2) turb2 += abs(snoise(N.PP * f)) / f; fade = clamp(2 * (cutoff - f) / cutoff, 0, 1); turb2 += fade * abs(snoise(PP * f)) / f; magnitude = pow(turb1, 4); NN = normalize(N); P_orig = P; if (ycomp(NN) > -0.3) P += (1-ycomp(NN)) * icicle_length * magnitude * normalize(Ng); else P += icicle_length * magnitude * normalize(Ng); P += down*turb1*turb2*3; N = calculatenormal(P); dx = abs(xcomp(P_orig)-xcomp(P)); dy = abs(ycomp(P_orig)-ycomp(P)); dz = abs(zcomp(P_orig)-zcomp(P)); dist = sqrt(dx*dx + dy*dy + dz*dz); Oi = 0.3; Nf = faceforward(normalize(N), I); Cs = color(0.85,0.9,1); Ci = Cs * (Ka * ambient() + (Kd * diffuse(normalize(N)))) + color(1,1,1) * Ks * specular(Nf, V, roughness); }