/* Authors: Yuan Kui Shen cs162-ac 12940472 Raul Yoni Chu cs162-bq 12782756 /* windows.sl This shader creates a spaceship like skin texture. - This displacement shader creates grooves in the surface running in the longitudinal direction (t). - And creates windows, running along the horizontal (s) direction. - The color of the light emitted from the window is specified by "window_color", while the skin color itself is derived from the surface it covers - w_base, w_height, w_width are values of the dimensions of the windows from 0 to 1. (The windows are not rendered very clearly when used with high "freq"...antialiasing problems may occur) - "gap" defines the margin, in which the actual windows should appear, (the window is drawn with an offset of gap from w_base - maxT and minT, defines the region which windows are actually drawn this is convenient for some structures which there is a gap near the very top and bottom where there are no windows */ /* definitions for convenience borrowed from rmannotes.sl */ #define pulse(a,b,fuzz,x) (smoothstep((a)-(fuzz),(a),(x)) - \ smoothstep((b)-(fuzz),(b),(x))) #define repeat(x,freq) (mod((x) * (freq), 1.0)) #define even(x) (mod((x), 2) == 0) #define whichtile(x,freq) (floor((x) * (freq))) #define blend(a,b,x) ((a) * (1 - (x)) + (b) * (x)) displacement windows (float Ka = 1; float Kd = .5; float Ks = .5; float roughness = .1; color specularcolor = 1; float freq = 4; float Km = 0.005; color window_color = (1, 1, 1); /* white */ float w_base = 0.2; float w_height = 0.2; float w_width = 0.80; float gap = 0.025; float maxT = 0.80; float minT = 0.20; ) { color surface_color = Cs; color surface_opac = Os; color window_opac; float fuzz = 0.0025; float base_surface = 0.0; float windows_surface; float numOfWindowsPerSquare = 2; float ss = repeat(s, numOfWindowsPerSquare * freq); float tt = repeat(t, freq); /* layer 0 */ /* create a grove going in the t direction */ float col = whichtile(s, numOfWindowsPerSquare*freq); /* Make the groove at even square intervals so as to not make the design look too crowded */ if (even(col)) { windows_surface = 1 - pulse(0, 2 * gap, fuzz, ss); base_surface = max(windows_surface, base_surface); color groove_color = (0, 0, 0); window_opac = pulse(0, 2*gap, fuzz, ss); surface_color = blend(surface_color, groove_color, window_opac); } /* get the grouped rows of windows effect */ if (t < maxT && t > minT) { /* layer 1 */ windows_surface = pulse(w_base, w_base + w_height, fuzz, tt); base_surface = max(windows_surface, base_surface); /* layer 2 */ if ( tt > (w_base + gap) && tt < (w_base + w_height - gap) ) { windows_surface = 1 - pulse(0.5 - (w_width / 2), 0.5 + (w_width / 2), fuzz, ss); base_surface = min(windows_surface, base_surface); window_opac = pulse(0.5 - (w_width / 2), 0.5 + (w_width / 2), fuzz, ss); surface_color = blend(surface_color, window_color, window_opac); } } P += Km * base_surface * normalize(N); N = calculatenormal(P); /* output */ normal Nf = faceforward (normalize(N),I); Oi = surface_opac; if (surface_color != window_color) { /* for the non metalic glass portions set the texture to be shiny...similar to metal/plastic */ Ci = surface_opac * ( surface_color * (Ka*ambient() + Kd*diffuse(Nf)) + specularcolor * Ks*specular(Nf,-normalize(I),roughness)); } else { /* for the actual window use the window_color */ Ci = window_color; } }