/* S. Kirk Bowers */ /* Compact disc surface shader */ #include surface compact_disc ( string mapname = ""; float Ka = 0.3, Ks = 1.0, roughness = 0.005, rainbow_width = 0.03, fuzz = 0.005; ) { float layer_opac, surface_opac; color surface_color, layer_color; point D, Nf, Nl; float rainbow_dot, rainbow_opac; color rainbow_color; float tt; float hole_width = 0.1; float grooves_start = 0.03; float grooves_end = 0.75; float num_grooves = 1000; float groove_varience = 0.2; float groove_color = 0.75; float groove_intense = 0.2; Nf = faceforward(normalize(N), I); Nl = normalize(I); tt = repeat(t, num_grooves); if (mapname == "") surface_color = 0; else { D = reflect(Nl, Nf); D = transform("world", point "world" (0, 0, 0) + D); surface_color = environment(mapname, D); } surface_opac = complement(smoothstep(1 - hole_width, 1 - hole_width + fuzz, t)); layer_opac = pulse(grooves_start, grooves_end, fuzz, t) * groove_intense; layer_color = groove_color + snoise(tt)*groove_varience; surface_color = blend(surface_color, layer_color, layer_opac); rainbow_dot = normalize(dPdu) . Nl; rainbow_color = 0; rainbow_opac = 1 - abs(-rainbow_width * 2.0 - rainbow_dot) / rainbow_width; rainbow_color += color (1, 0, 0) * rainbow_opac * pulse(-rainbow_width * 3, -rainbow_width, fuzz, rainbow_dot); rainbow_opac = 1 - abs(rainbow_dot) / rainbow_width; rainbow_color += color (0, 1, 0) * rainbow_opac * pulse(-rainbow_width, rainbow_width, fuzz, rainbow_dot); rainbow_opac = 1 - abs(rainbow_width * 2.0 - rainbow_dot) / rainbow_width; rainbow_color += color (0, 0, 1) * rainbow_opac * pulse(rainbow_width, rainbow_width * 3, fuzz, rainbow_dot); Oi = surface_opac; Ci = Oi * (Ka * ambient() + Ks * (surface_color + rainbow_color + specular(Nf, -Nl, roughness))); }