#include "rmannotes.sl" light bospot( color lightcolor = color(1.0, 1.0, 1.0); float intensity = 1.0; float spotangle = 30.0; float penumbra = 10.0; float beamdistribution= 2.0; float falloff = 1; color shadowcolor = color(0.0, 0.0, 0.0); string shadowmap = ""; float shadowblur = .01; float shadowbias = .05; float shadownsamps = 8.0; string slide = ""; float slidefov = 90; float slidebias = 0.0; output varying float __nonspecular = 0; output varying float __nonatmos = 0; ) { float unoccluded = 0.0; point from = point "shader" (0, 0, 0); vector axis = normalize(vector "shader" (0, 0, 1)); color lcolor; uniform float r1 = radians(spotangle); uniform float r2 = radians(spotangle + penumbra); uniform float cosr1 = cos(r1); uniform float cosr2 = cos(r2); point PL = transform("shader", Ps); vector A = vector "shader" (Ps - from); float atten = 1; float cosangle = normalize(vector A).axis; cosangle = clamp(cosangle, 0, 1); illuminate(from, axis, r2){ float distance = length(L); atten *= pow(cosangle, beamdistribution)/pow(distance, falloff); atten *= smoothstep(cosr2, cosr1, cosangle); if (slide != "") { uniform float width = sin(radians(slidefov)/2) * (slidebias + 1.0); float ss = (xcomp(PL)/distance) / width; float tt = (ycomp(PL)/distance) / width; ss = clamp(0.5 + 0.5*ss, 0, 1); tt = clamp(0.5 - 0.5*tt, 0, 1); point Pslide = point (ss, tt, 1); float zslide = zcomp(Pslide); lcolor = color texture (slide, xcomp(Pslide), ycomp(Pslide)); }else{ lcolor = lightcolor; } if(shadowmap != "") { unoccluded = shadow(shadowmap, Ps, "blur", shadowblur, "samples", shadownsamps, "bias", shadowbias); __nonspecular *= (1.0 - unoccluded); } Cl = mix(lcolor, shadowcolor, unoccluded); Cl *= intensity * atten; } }