divert(-1) # ############ This is the M4 File and is okay to edit ############################## # # to get VIM to act like this is an .sl file, try # # :source $VIM/syntax/cpp.vim # divert /**************************************************************************/ /**************************************************************************/ /*** DO NOT EDIT THE .SL FILE FOR THIS SHADER *****************************/ /*** INSTEAD EDIT THE .SLM4 FILE WHICH GENERATES THE .SL FILE *************/ /**************************************************************************/ /**************************************************************************/ /* * To do: accomodate negative widths. twosided/onesided cards. */ /* ** $Id: softbox.slm4,v 1.1.1.1 2002/02/10 02:36:02 tal Exp $ ** ** Derived from softbox3 v1.2 - Author Bjorke for all ** ** Full RCS log in .slm4 file divert(-1) ** ** $Log: softbox.slm4,v $ ** Revision 1.1.1.1 2002/02/10 02:36:02 tal ** RenderMan Repository ** ** Revision 1.1 2001/04/21 21:50:06 lg ** *** empty log message *** ** ** ** divert** ** */ #define BOOL float #define ENUM float #define SHAD_BOX_FILT 0 #define SHAD_GAUSSIAN_FILT 1 #define TEX_GAUSSIAN_FILT 0 #define TEX_BOX_FILT 1 #define TEX_RADIAL_FILT 2 #define TEX_DISK_FILT 3 #define HALFSIZE #define OBEY_THIS "Reflectivity" #define CLASSIC 0 #define SPHERICAL 1 #define CUBEFACE 0 #define LATLONG 1 divert(-1) /*****************************************************************/ /*** M4 DECLARATIONS *********************************************/ /*****************************************************************/ define(M4_SOFTBOX_DECLARE,`string boxCoord$1 = ""; color boxColor$1 = color (1,1,1), /* multiplied by lightcolor&intensity */ boxOpacity$1 = color (1,1,1); float boxWidth$1 = 1, boxWEdge$1 = -0.1, boxHeight$1 = 1, boxHEdge$1 = -0.1, boxRoundness$1 = 0; string boxTex$1 = ""; float boxFilter$1 = TEX_GAUSSIAN_FILT, boxTexStr$1 = 1, boxTexBlur$1 = 0;') define(M4_DO_SOFTBOX,`if (boxCoord$1 != "") { softbox_contrib2(Ps,rv, boxCoord$1,boxTex$1,boxTexStr$1, (boxTexBlur$1+materiaBlur),boxFilter$1, boxWidth$1,boxHeight$1,boxWEdge$1,boxHEdge$1, boxRoundness$1,boxColor$1,boxOpacity$1,decayRate, thisDist,thisColor,thisOpac); sortedDist[boxCt] = thisDist; sortedColor[boxCt] = thisColor; sortedOpac[boxCt] = thisOpac; boxCt += 1; }') define(M4_SHAD_DECLARE,`string shadowname$1 = ""; ENUM shadowfilt$1 = SHAD_BOX_FILT; float shadowblur$1 = 0.01, shadowbias$1 = 0, shadowsamples$1 = 16;') define(M4_DO_SHAD,`if (shadowname$1 != "") { shadowed = sbShadow(shadowname$1,Ps,shadowfilt$1, shadowblur$1,shadowsamples$1,shadowbias$1); fullShad = max(fullShad,shadowed); }') define(REALLY_FAR,1000000.0) divert /**************************************************************************/ /* Superellipse soft clipping - straight out of "uberlight" ***/ /* Input: ***/ /* - point Q on the x-y plane ***/ /* - the equations of two superellipses (with major/minor axes given ***/ /* by a,b and A,B for the inner and outer ellipses, respectively) ***/ /* Returns: ***/ /* - 0 if Q was inside the inner ellipse ***/ /* - 1 if Q was outside the outer ellipse ***/ /* - smoothly varying from 0 to 1 in between ***/ /**************************************************************************/ /* this is the identical function used by sqLight etc */ float clipSuperellipse ( point Q; /* Test point on the x-y plane */ uniform float a, b; /* Inner superellipse */ uniform float A, B; /* Outer superellipse */ uniform float roundness; /* Same roundness for both ellipses */ ) { varying float result; varying float x = abs(xcomp(Q)), y = abs(ycomp(Q)); if (roundness < 1.0e-6) { /* Simpler case of a square */ result = 1 - (1-smoothstep(a,A,x)) * (1-smoothstep(b,B,y)); } else { /* more-difficult rounded corner case */ varying float re = 2/roundness; /* roundness exponent */ varying float q = a * b * pow (pow(b*x, re) + pow(a*y, re), -1/re); varying float r = A * B * pow (pow(B*x, re) + pow(A*y, re), -1/re); result = smoothstep (q, r, 1); } return result; } /*****************************************************************/ /*** Given info on a softbox, ************************************/ /*****************************************************************/ void softbox_contrib2( varying point surfPt; varying vector reflVect; uniform string boxCoords; uniform string boxTexture; uniform float boxTexStr, boxTexBlur, boxFilter, boxWidth, boxHeight, boxWEdge, boxHEdge, boxRoundness; uniform color boxColor, boxOpac; uniform float decayExp; output float theDist; output color theColor; output color theOpac; ) { uniform string filtTypes[4] = {"gaussian","box","radial-bspline","disk"}; uniform string theFilterName = filtTypes[clamp(boxFilter,0,3)]; varying float contrib; varying color ct = 1; varying float ot = 1; /* Get the surface position */ varying point Pb1 = transform (boxCoords, surfPt); varying vector Vlight = vtransform (boxCoords, reflVect); varying float zv = zcomp(Vlight); varying point Pplane = Pb1 - Vlight*(zcomp(Pb1)/zcomp(Vlight)); #ifdef HALFSIZE uniform float bw2 = boxWidth/2; uniform float bh2 = boxHeight/2; #else #define bw2 boxWidth #define bh2 boxHeight #endif uniform float we = max(boxWEdge,-bw2); uniform float he = max(boxHEdge,-bh2); uniform float bW = bw2+we; uniform float bH = bh2+he; uniform float iW = min(bW,bw2); uniform float iH = min(bH,bh2); uniform float oW = max(bW,bw2); uniform float oH = max(bH,bh2); if (sign(zcomp(Pb1)) == sign(zcomp(Vlight))) { contrib = 0; } else if (abs(zv) < 0.0001) { contrib = 0; } else { contrib = 1 - clipSuperellipse (Pplane, iW, iH, oW,oH, boxRoundness); if (boxTexture != "") { uniform float nChans; textureinfo(boxTexture,"channels",nChans); varying float theS = (oW+xcomp(Pplane))/(oW*2); varying float theT = (oH-ycomp(Pplane))/(oH*2); theS = min(2,max(-1,theS)); theT = min(2,max(-1,theT)); if (nChans>1) { ct = texture(boxTexture,theS,theT, "filter", theFilterName, "blur", boxTexBlur); if (boxTexStr != 1) { ct = (ct*boxTexStr)+(1-boxTexStr); } } if ((nChans==1)||(nChans>3)) { uniform float alphaChan; if (nChans==1) { alphaChan = 0; } else { alphaChan = 3; } ot = float texture(boxTexture[alphaChan],theS,theT, "filter", theFilterName, "blur", boxTexBlur); } } } #pragma nolint varying point ppC = transform(boxCoords,"world",Pplane); varying point spw = transform("world",surfPt); varying float pDist = length(ppC - spw); /* in "world" coords */ theDist = pDist; theOpac = contrib * boxOpac * ot; theColor = contrib * ct * boxColor / pow(pDist,decayExp); /* premultiplied!!!!! */ } /**************************************************/ /*** SHADOW ***************************************/ /**************************************************/ float sbShadow( uniform string theName; varying point thePoint; uniform ENUM theFilt; uniform float theBlur, theSamples, theBias; ) { uniform string filtTypes[2] = {"box", "gaussian"}; uniform string theFilterName = filtTypes[clamp(theFilt,0,1)]; varying float inShadow = shadow (theName, thePoint, "filter", theFilterName, "blur", theBlur, "samples", theSamples, "bias", theBias); return(inShadow); } /*****************************************************************/ /*** MAIN SHADER *************************************************/ /*****************************************************************/ light softboxes( string Comment = ""; #ifdef BMRT string Tcl = ""; string NodeName = ""; #else /* !BMRT -- slc compiler doesn't like these definitions */ string Tcl = "[addL]"; string NodeName = "$OBJNAME"; #endif /* BMRT */ float intensity = 1; color lightcolor = color (1,1,1); float decayRate = 0; float meterDistance = 1; string meterSpace = ""; float edgeRolloff = 0, edgeAngle = 90, edgeExp = 1; M4_SOFTBOX_DECLARE(1) M4_SOFTBOX_DECLARE(2) M4_SOFTBOX_DECLARE(3) M4_SOFTBOX_DECLARE(4) uniform string envTexName = ""; uniform float EnvType = CLASSIC; uniform float MapType = CUBEFACE; uniform float envTexIntensity = 1; uniform float envTexBlur = 0; uniform float envTexStr = 1; uniform float envTexFilter = 0; uniform string envReflSpace = ""; color shadowcolor = 0; float shadowintensity = 1; M4_SHAD_DECLARE() M4_SHAD_DECLARE(b) M4_SHAD_DECLARE(c) M4_SHAD_DECLARE(d) BOOL NonDiffuse = 1; BOOL NonSpecular = 0; BOOL ObeyMateria = 0; BOOL UseMateriaBlur = 0; output varying float __nondiffuse = 1; output varying float __nonspecular = 0; string __category = "reflection"; output varying float __inShadow = 0; ) { uniform string rcsInfo = "$Id: softbox.slm4,v 1.1.1.1 2002/02/10 02:36:02 tal Exp $"; uniform string filtTypes[4] = {"gaussian","box","radial-bspline","disk"}; uniform string theFilterName = filtTypes[clamp(envTexFilter,0,3)]; normal Nf = faceforward(normalize(N),I); vector rv = reflect(I,Nf); uniform float edgeLimVal = cos(radians(90-clamp(edgeAngle,0,90))); uniform string theEnvSpace; if (envReflSpace == "") { theEnvSpace = "shader"; } else { theEnvSpace = envReflSpace; } uniform float adjMeterDistance; if (meterSpace == "") { adjMeterDistance = meterDistance; } else { uniform point metP = transform(meterSpace,"shader",point (0,0,0)); adjMeterDistance = length(metP) + meterDistance; } uniform float adjIntensity = pow(adjMeterDistance,decayRate)*intensity; varying float fullShad = 0; uniform float materiaRefl = 1; uniform float materiaBlur = 0; Cl = 0; __nondiffuse = NonDiffuse; __nonspecular = NonSpecular; if (ObeyMateria > 0) { if (surface("Reflectivity",materiaRefl) == 0) { if (surface("abReflectivity",materiaRefl) == 0) { if (surface("reflectivity",materiaRefl) == 0) { if (surface("Kr",materiaRefl) == 0) { materiaRefl = 0; } } } } } if (UseMateriaBlur > 0) { if (surface("ReflectionMapBlur",materiaBlur) == 0) { if (surface("abReflectionMapBlur",materiaBlur) == 0) { if (surface("reflectionMapBlur",materiaBlur) == 0) { materiaBlur = 0; } } } } solar() { if (materiaRefl != 0) { uniform float boxCt=0; varying float thisDist; varying color thisOpac; varying color thisColor; varying float sortedDist[4]; varying color sortedOpac[4]; varying color sortedColor[4]; M4_DO_SOFTBOX(1) M4_DO_SOFTBOX(2) M4_DO_SOFTBOX(3) M4_DO_SOFTBOX(4) if (envTexName != "") { #pragma nolint varying vector Rs = normalize (vtransform (theEnvSpace, normalize(-L))); if (EnvType == SPHERICAL) { #pragma nolint varying point PShd = transform (theEnvSpace, Ps); varying float pl = vector(PShd).vector(PShd); varying float pdotv = -vector(PShd).Rs; Rs = vector( PShd + (pdotv + sqrt (abs (1 - pl + ((pdotv)*(pdotv)))))*Rs ); } if( MapType == LATLONG ) { /* latlong */ Rs = vector (-zcomp (Rs), xcomp (Rs), ycomp (Rs)); } Cl = color environment (envTexName, Rs, "filter", theFilterName, "blur", (envTexBlur+materiaBlur)); if (envTexStr != 1) { Cl = (Cl*envTexStr)+(1-envTexStr); } Cl *= envTexIntensity; } if (boxCt > 0) { uniform float i, j, k; for(k=0; k<(boxCt-1); k+=1) { j = 0; for(i=1; isortedDist[j]) { /* farthest first */ thisDist = sortedDist[j]; thisOpac = sortedOpac[j]; thisColor = sortedColor[j]; sortedDist[j] = sortedDist[i]; sortedOpac[j] = sortedOpac[i]; sortedColor[j] = sortedColor[i]; sortedDist[i] = thisDist; sortedOpac[i] = thisOpac; sortedColor[i] = thisColor; } j = j+1; } } color ttc; for(k=0; k 0) { float q; q = In.Nn/edgeLimVal; q = 1 - clamp(edgeRolloff*pow(clamp(abs(q),0,1),1/max(edgeExp,0.001)),0,1); Cl = mix(color(0,0,0),Cl,q); } varying float shadowed; M4_DO_SHAD() M4_DO_SHAD(b) M4_DO_SHAD(c) M4_DO_SHAD(d) __inShadow = fullShad; } } if (materiaRefl > 0) { Cl *= (lightcolor * adjIntensity * materiaRefl); Cl = mix(Cl, (shadowcolor*shadowintensity*adjIntensity), fullShad); } else { Cl = 0; } } /*************************************************/ /***************************************** eof ***/ /*************************************************/