/* Copyrighted Pixar 1989 */ /* From the RenderMan Companion p.361 */ /* Listing 16.21 Light shader simulating sunlight through a window*/ /* * windowlight(): Cast patches of light as through a paned window. */ light windowlight( point from = point "world" ( 0, 0, -20), to = point "world" (0, 0, 0), center = point "world" (0, 0, -4), in = point "world" (0, 0, 1), up = point "world" (0, 1, 0); color lightcolor = color (1, .9, .6), darkcolor = color (.05, .2, .1); float intensity = 1, xorder = 2, /* number of panes horizontally */ yorder = 3, /* number of panes vertically */ panewidth = 6, /* horizontal size of a pane */ paneheight = 6, /* vertical size of a pane */ framewidth = 1, /* sash width between panes */ fuzz = .2;) /* transition region between pane and sash */ { uniform point in2, /* normalized in */ right, /* unit vector perpendicular to in2 and up2 */ up2, /* normalized up perpendicular to in */ corner, /* location of lower left corner of window */ path; /* direction of sunlight travel */ point PtoC, /* vector from surface point to window corner */ PtoF; /* vector from surface point to wall along path */ float offset, modulus, yfract, xfract; /* Initialize the uniform variables */ path = (from - to); in2 = normalize(in); in2 *= sign(-path.in2); right = up ^ in2; up2 = normalize(in2 ^ right); right = up2 ^ in2; corner = center - right*xorder*panewidth/2 - up2*yorder*paneheight/2; solar( -path, 0.0 ) { PtoC = corner - Ps; if (path.PtoC <= 0) { /* outdoors => full illumination */ xfract = yfract = 1; } else { /* * Make PtoF be a vector from the surface point to the wall * by adjusting the length of the reflected vector path. */ PtoF = path * (PtoC.in2)/(path.in2); /* * Calculate the vector from the corner to the intersection point, and * project it onto up2. This length is the vertical offset of the * intersection point within the window. */ offset = (PtoF - PtoC).up2; modulus = mod(offset, paneheight); if( offset > 0 && offset/paneheight < yorder ) { /* inside window */ if( modulus > (paneheight/2)) modulus = paneheight - modulus; /* symmetry in pane */ yfract = smoothstep( /* include sash fuzz */ (framewidth/2) - (fuzz/2), (framewidth/2) + (fuzz/2), modulus); } else { yfract = 0; } /* Repeat for horizontal offset */ offset = (PtoF - PtoC).right; modulus = mod(offset, panewidth); if( offset > 0 && offset/panewidth < xorder ) { if( modulus > (panewidth/2)) modulus = panewidth - modulus; xfract = smoothstep( (framewidth/2) - (fuzz/2), (framewidth/2) + (fuzz/2), modulus); } else { xfract = 0; } } Cl = intensity * mix( darkcolor, lightcolor, yfract*xfract); } }