/* This is a varient of the slide-projector light shader
From the RenderMan Companion p.373
*/
/*
* TLblocker1spotlight -- texture-map used as a light blocker for a spot
* light (1 channel version)
*
* DESCRIPTION:
* This is basically the slideprojector from the RC. The twist is that the
* 1 Channel texture map is treated as a either a positive or negative blocker.
* ie. the image is use to block the light based on the pattern of the black &
* white image.
*
* This version has the properties of a spotlight, too.
*
* HINTS:
* If the "negative" is false, then the white region will let light pass though
* and block the rest. If "negative" is true, then it will do the opposite.
*
* AUTHOR: Tal Lancaster
* tal AT renderman DOT org
*
* History:
* Created: 8/10/97
*
*/
light
TLblocker1spotlight(
float intensity = 1.0;
color lightcolor = 1;
float fieldofview=PI/32;
point from = (8, -4, 10),
to = (0,0,0),
up = point "eye" (0,1,0);
float coneangle = radians (30);
float conedeltaangle = radians (5);
float beamdistribution = 2;
float negative = 0;
string blockername = "",
shadowname = "" )
{
uniform point relT, /* normalized direction vector */
relU, /* "vertical" perspective of surface point */
relV; /* "horizontal" perspective of surface point */
uniform point A;
uniform float spread = 1/tan(fieldofview/2); /* spread of "beam" */
float Pt, /* projection of Ps on relT (distance of
surface point along light direction) */
Pu, /* projection of Ps on relU */
Pv, /* projection of Ps on relU */
sloc, tloc; /* perspected surface point */
float cosoutside = cos (coneangle);
float cosinside = cos (coneangle-conedeltaangle);
float atten;
float cosangle;
float blockerVal; /* value from texture map */
/* Initialize uniform variables for perspective */
relT = normalize(to - from);
relU = relT ^ up;
relV = normalize(relT ^ relU);
relU = relV^relT;
A = relT;
Cl = lightcolor * intensity;
illuminate(from, relT, /*atan(sqrt(2)/spread)*/coneangle) {
L = Ps - from; /* direction of light source from surf. point */
Pt = L.relT; /* coordinates of Ps along relT, relU, relV */
Pu = L.relU;
Pv = L.relV;
sloc = spread*Pu/Pt; /* perspective divide */
tloc = spread*Pv/Pt;
sloc = sloc*.5 + .5; /* correction from [-1,1] to [0,1] */
tloc = tloc*.5 + .5;
cosangle = L.A / length (L);
atten = pow (cosangle, beamdistribution)/ (L.L);
atten *= smoothstep (cosoutside, cosinside, cosangle);
Cl *= atten;
if (blockername != "") {
blockerVal = float texture(blockername, sloc,tloc);
if (negative == 1)
blockerVal = 1 - blockerVal;
Cl *= blockerVal;
}
if( shadowname != "" )
Cl *= 1-shadow(shadowname, Ps);
}
}