/* surface shader: brick_shiny_building creator: Nick Meshes, DePaul University description: Based on loosely screen.sl and shiny.sl Makes a surface that looks like an office building with reflective windows. Walls look plastic-like though. parameters: Ka, Kd, Ks, roughness, specularcolor - work just like the plastic shader wallcolor and windowcolor window width and height set parts between windows set as well. up - x=0, y=1, z=2, building is square in this algorithm widthoffset will be between 0 and (windowwidth + wallwidth) heightoffset will be between 0 and (windowheight + wallheight) ceiling - top where no more windows exist floor - bottom where no more windows exist */ #include "rayserver.h" #include "raytrace.h" #include "noises.h" #include "patterns.h" displacement stucco_building2( float up = 2; float ceiling = 100, floor = -100; float windowwidth = 1, wallwidth = 1; float windowheight = 1, wallheight = 1; float widthoffset = 0, heightoffset = 0; float Kr = 0.5, blur = 0; float samples = 1; /* stucco features */ float freq = 1; float Km = 0.2; float octaves = 3; float trough = -0.15, peak = 0.35; ) { float xpart, ypart, zpart; float sum = 0; point Pshad; /* Point to be shaded, in shader space */ float fwidth; /* Estimated change in P between image samples */ normal NN; /* Unit length surface normal */ float disp; /* Amount to displace */ if (up == 0){ xpart = abs(ycomp(P)); ypart = abs(zcomp(P)); zpart = abs(xcomp(P)); } else if (up == 1){ xpart = abs(zcomp(P)); ypart = abs(xcomp(P)); zpart = abs(ycomp(P)); } else{ xpart = abs(xcomp(P)); ypart = abs(ycomp(P)); zpart = abs(zcomp(P)); } xpart = mod((xpart + widthoffset), (windowwidth + wallwidth)); ypart = mod((ypart + widthoffset), (windowwidth + wallwidth)); zpart = mod((zpart + heightoffset), (windowheight + wallheight)); if (zpart <= floor) sum = 1; if (zpart >= ceiling) sum = 1; if (xpart > (windowwidth/2)) if (xpart < (wallwidth + (windowwidth/2))) sum = sum + 1; if (ypart > (windowwidth/2)) if (ypart < (wallwidth + (windowwidth/2))) sum = sum + 1; if (zpart > (windowheight/2)) if (zpart < (wallheight + (windowheight/2))) sum = sum + 1; if (sum > 0){ /* Do texture calcs in "shader" space, get approximate filter size */ Pshad = freq * transform ("shader", P); fwidth = filterwidthp(Pshad); /* Compute some fractional Brownian motion */ disp = fBm (Pshad, fwidth, 3, 2, 0.6); /* Threshold the fBm and scale it */ disp = Km * smoothstep (trough, peak, disp); /* displace in shader space units */ NN = normalize(N); P += NN * (disp / length (ntransform ("shader", NN))); N = normalize (calculatenormal(P)); } }