class dl_incandescence(deluxe.ShadingComponent): typeid = 0x0030000a description = "Simple incandescence to simulate internal illumination." bakeIncomingColor = deluxe.Enum( help=""" To bake a color or float to a 2d texture using uv coordinates, plug the output from a hypershade node into the Color parameter, set this to 'As color' or 'As float' and specify a path in the Bake File parameter. To ensure that the baked color does not contribute to the beauty pass, set Intensity and/or Contribution to 0. """, default='Off', choices=['Off', 'As color', 'As float (luminance)'] ) bakeFile = deluxe.String (help=""" File to bake 2d texture to. The .bake suffix is recommended, then do tdlmake filename.bake filename.tdl. """, default="bakedColor.bake") method = deluxe.Enum(default='Uniform', choices=['Uniform', 'Facing', 'Edge', 'Light'], storage='uniform', help="Method of incandescence approximation") shape = deluxe.Float(default=1, storage='uniform', help='Shape of falloff (for "Edge" and "Facing" methods). Values above 1 falloff sooner. Values below 1 fall off later.') rsl = \ """
class dl_shadowCollector(deluxe.DiffuseBase, deluxe.ShadingComponent): typeid = 0x00300012 description = """Shading component for collecting shadows from lights. Direct shadows (affecting diff, spec and rim) go in aov_direct_shadow, whereas indirect shadows (affecting indirect lighting) go in aov_indirect_shadow. The beauty pass is not meant to be used, it's just for visualization.""" beautyModes = [ 'r=Direct, g=Indirect, b=Hemisphere Falloff', 'Direct + Indirect (white)', 'Direct (white)', 'Indirect (white)', 'For slapcomp: rgb = shadowColor * shadowOpacity, (alpha = Direct + Indirect)*shadowOpacity' ] beautyMode = deluxe.Enum(default=beautyModes[0], choices=beautyModes, storage='varying', help="What to show in the beauty. ") diffuseFalloff = deluxe.Float( shortname='dfo', default=1, help="Make shadows fade as normal points away from light.") useLightColor = deluxe.Enum( shortname='ulc', default="Direct & Indirect", storage='varying', choices=["Direct & Indirect", "Direct", "Indirect", "None"]) shadowColor = deluxe.Color(shortname='shc', default=0, help=""" Color of shadow, ONLY USED WHEN showInBty == 'rgb = shadowColor * shadowOpacity, alpha = (Direct + Indirect)*shadowOpacity' """) shadowOpacity = deluxe.Float(shortname='sho', default=1, help="Opacity/intensity of shadows.") hemispheres = deluxe.Float( default=.9, max=2, help= """How much of the hemisphere around the normal to search for direct shadows. To include self-shadowing, use 2 (search whole sphere). To not include self-shadowing, use < 1 (search less than hemisphere).""" ) hemisphereFalloff = deluxe.Float( default=0.05, max=1, help="How far from the searched hemisphere to fade direct shadows.") advanced = deluxe.Group( [shadowColor, shadowOpacity, hemispheres, hemisphereFalloff]) rsl = \ """
class dl_diffuse(deluxe.DiffuseBase, deluxe.ShadingComponent): typeid = 0x00300001 description = "Returns the result of the diffuse shading operator." includes = ["env_utils.h"] roughness = deluxe.Float(default=0, min=0, max=1, help="Values greater than 0 cause the illuminated area to be more uniformly lit and darker, and create a sharper falloff between illuminated and non-illuminated areas.") wrap = deluxe.Float(default=0, min=-1, max=1, help='Allows diffuse illumination to "wrap around" to surfaces where the normal is pointing away from the light.') diffuseIntensity = deluxe.Color(help="Multiply direct diffuse - direct lighting multiplied by this AND the \"color\" parameter.") indirectIntensity = deluxe.Color(help="Multiply indirect diffuse - indirect lighting multiplied by this AND the \"color\" parameter.") #Direct = deluxe.Group([roughness, wrap], collapse=False) #Indirect = deluxe.Group([indirectIntensity], collapse=False) translucenceIntensity = deluxe.Color(help="Multiply translucence - translucence lighting multiplied by this AND the \"color\" parameter.", default=0) modes = ['Normal', 'Thin'] mode = deluxe.Enum(default=modes[0], choices=modes, help="") focus = deluxe.Float(min=0, max=1, default=0.5, help="Translucence focus") normalAttributes = deluxe.Group([focus], collapse=False) subsurfaceWeight = deluxe.Float(shortname='ssw' ) subsurfaceIntensity = deluxe.Color(shortname='ssi') subsurfaceScale = deluxe.Float(shortname='sssc', default=0.1) subsurfaceSmooth = deluxe.Float(shortname='sssm', default=0, storage='uniform', label="Smooth") subsurfaceIndexOfRefraction = deluxe.Float(shortname='ssior', default=1.5, label='Index Of Refraction') subsurfacePtcFile = deluxe.String(default='', label='Point Cloud File', help="""(Point-Based) The point cloud file in which baked radiance is stored.""") subsurfaceModes = ['Scattering / Absortion', 'Albedo / Mean Free Path'] subsurfaceMode = deluxe.Enum(default=subsurfaceModes[0], choices=subsurfaceModes, help="") subsurfaceScattering = deluxe.Color(shortname='ssc', default=[0.5, 0.5, 0.5], label='Scattering' ) subsurfaceAbsorption = deluxe.Color(shortname='sssa', default=[0.05, 0.05, 0.05], label='Absorption' ) subsurfaceAlbedo = deluxe.Color(shortname='ssa', default=[0.3,0.3, 0.3], label='Albedo' ) subsurfaceDiffuseMeanFreePath = deluxe.Color(shortname='dmfp', default=[3, 3, 3], label='Mean Free Path' ) #subsurfaceScatteringAttributes = deluxe.Group([subsurfaceWeight, subsurfaceIntensity, subsurfaceScale, subsurfaceSmooth, subsurfaceIndexOfRefraction, subsurfaceScattering, subsurfaceAbsorption, subsurfaceAlbedo, subsurfaceDiffuseMeanFreePath, subsurfacePtcFile], collapse=False) subsurfaceScatteringAttributes = deluxe.Group([subsurfaceWeight, subsurfaceIntensity, subsurfaceScale, subsurfaceSmooth, subsurfaceIndexOfRefraction, subsurfaceMode, subsurfaceScattering, subsurfaceAbsorption, subsurfaceAlbedo, subsurfaceDiffuseMeanFreePath, subsurfacePtcFile], collapse=False) creep = deluxe.Float(shortname='cre', help="Degree to which light creeps to the front") backIllumination = deluxe.Boolean(default=True, storage='uniform', help="Calculate illumination for the back side of the object. This is the typical use and is accomplished by reversing the surface normal.") thinAttributes = deluxe.Group([creep, backIllumination], collapse=False) translucenceAttributes = deluxe.Group([translucenceIntensity, mode, normalAttributes, thinAttributes], collapse=False) bakeDistUnderSurf = deluxe.Boolean(shortname='bdus', default=False) bakeDistUnderSurfFile = deluxe.String(shortname='bdusf', default="/tmp/dist.#.bake") bakeDistUnderSurfScale = deluxe.Float(shortname='bduss', default=1) bakingAttributes = deluxe.Group([bakeDistUnderSurf, bakeDistUnderSurfFile, bakeDistUnderSurfScale]) rsl = \ """
class dl_volumeNoise(deluxe.Texture3D): typeid = 0x00300339 includes = ["volumeNoise_utils.h"] # u float frequencyIncrement = deluxe.Float(shortname="fd", default=.5, storage="uniform") threshold = deluxe.Float(shortname="th", default=0, storage="uniform") amplitude = deluxe.Float(shortname="am", default=1, storage="uniform") ratio = deluxe.Float(shortname="ra", default=.707, storage="uniform") frequencyRatio = deluxe.Float(shortname="fr", default=2, storage="uniform") depthMax = deluxe.Float(shortname="dm", default=3, storage="uniform") inflection = deluxe.Boolean(shortname="in", default=False, storage="uniform") time = deluxe.Float(shortname="ti", default=0, storage="uniform") frequency = deluxe.Float(shortname="fq", default=8) # u point scale = deluxe.Point(shortname="sc", default=1, storage="uniform") origin = deluxe.Point(shortname="or", default=0, storage="uniform") # float implode = deluxe.Float(shortname="im", default=0) # point implodeCenter = deluxe.Point(shortname="ic", default=0) # u float noiseType = deluxe.Enum(shortname="nt", default="Billow", choices=[ "Perlin Noise", "Billow", "Volume Wave", "Wispy", "SpaceTime" ], storage="uniform") # float density = deluxe.Float(shortname="de", default=1) spottyness = deluxe.Float(shortname="sp", default=.1) sizeRand = deluxe.Float(shortname="sr", default=0) randomness = deluxe.Float(shortname="rn", default=1) falloff = deluxe.Enum(shortname="fa", default="Fast", choices=["Linear", "Smooth", "Fast", "Bubble"]) # float numWaves = deluxe.Float(shortname="nw", default=5) rsl = \ """
class dl_cellNoise(deluxe.Texture3D): typeid = 0x0030013b description = "\"Worley noise\" from \"A Cellular Texture Basis Function\", SIGGRAPH '96" frequency = deluxe.Float(default=4, softmin=.1, softmax=10, storage='uniform', help="Controls the size of the cells. Higher frequencies make smaller cells.") noisetype = deluxe.Enum(default='Voronoi Euclidian',choices=['Voronoi Euclidian','Voronoi Manhattan','Simple Cellnoise'] ,storage='uniform', help="The means to measure distances to neighboring cells. Manhattan distance gives more rectangular shapes and Euclidian distance gives more spherical shapes.") jitter = deluxe.Float(default=0.75, softmin=0, softmax=1, help="Controls the distortion of the cells.") clamp = deluxe.Boolean(default=True, storage='uniform', help="Causes resulting distances to be clamped to the range 0->1") c1 = deluxe.Float(default=0.8, softmin=-2, softmax=2, help="Multiplier for the distances to the first feature.") c2 = deluxe.Float(default=-0.2, softmin=-2, softmax=2, help="Multiplier for the distance to the second feature.") voronoi = deluxe.Group([jitter, clamp, c1, c2], collapse=False) avgcolor = deluxe.Color(shortname='ac', default=1, storage='uniform', help="") colorvariation = deluxe.Float(shortname='cv', default=.5, storage='uniform', help="") simple = deluxe.Group([avgcolor, colorvariation], collapse=False) rslpost = "" rsl = \ """
class dl_curvature(deluxe.Utility): typeid = 0x0030000c description = "Simple incandescence to simulate internal illumination. " CurvatureType = deluxe.Enum(default='mean', description=""" I'm honestly not sure how these calculations are done, but 'mean' seems work best.""", choices=['gaussian', 'mean', 'ku', 'kv', 'min', 'max']) remapInMin = deluxe.Float(default=-1, shortname='inmin', description='(unclamped) minimum input value to remap curvature') remapInMax = deluxe.Float(default=1, shortname='inmax', description='(unclamped) maximum input value to remap curvature') remapOutMin = deluxe.Float(default=0, shortname='outmin', description='(unclamped) minimum output value to remap curvature') remapOutMax = deluxe.Float(default=1, shortname='outmax', description='(unclamped) maximum output value to remap curvature') outColor = deluxe.Color(output=True) outAlpha = deluxe.Float(output=True) rsl = \ """
class dl_specular(deluxe.ShadingComponent, deluxe.EnvironmentMapBase): typeid = 0x00300002 description = "The specular component simulates the reflection of light sources. Samples all incoming lights along the specular direction of the surface." includes = ["env_utils.h"] model = deluxe.Enum(default='3Delight', choices=['3Delight', 'Standard', 'Phong', 'Cook-Torrance', 'Glossy', 'Anisotropic', 'Kajiya'], storage='uniform', help="""Specular model to use. 3Delight, Standard and Phong all model traditional specularity. Cook-Torrance is for metallic surfaces, Glossy is for highly glossy surfaces, and Kajiya assumes the surface is a hair-like thin tube.""") roughness = deluxe.Float(min=0, softmax=0.2, default=0.05, help="Size or roughness of highlight") sharpness = deluxe.Float(min=0, softmax=1, default=0.2, help="(Glossy) Sharpness of highlight. 1 is infinitely sharp, 0 is very dull.") indexOfRefraction = deluxe.Float(default=0, min=0, softmax=50, help="Index of refraction of the material") uRoughness = deluxe.Float(min=0, softmax=1, default=0.2, help="(Anisotropic) Size of highlight in the U direction ") vRoughness = deluxe.Float(min=0, softmax=1, default=0.9, help="(Anisotropic) Size of highlight in the V direction ") useEnvironment = deluxe.Boolean(default=False, help="Whether to respond to traditional CG lights only or also include lighting from the environment. ") rsl = \ """
class dl_triplanar(deluxe.Utility): typeid = 0x00300335 description = "Triplanar texture projector." coordsys = deluxe.CoordinateSystem(shortname="cs", default="world", help=""" Enter a standard shading space (eg 'world', 'object') or a coordinate system shape. """) scale = deluxe.Float(shortname="sc", default=1, help="Global scale for x, y, and z projections.") blendWidth = deluxe.Float( shortname="bl", default=.5, help= "How much to blend between x, y, and z projections (0 makes hard line between them)." ) warpMode = deluxe.Enum(shortname='wm', default='Off', choices=['Off', 'Noise', 'Input']) warpNoiseAmount = deluxe.Float(shortname='wna', default=1) warpNoiseFreq = deluxe.Float(shortname='wnf', default=1) warpNoiseOffset = deluxe.Vector(shortname='wno', default=0) warpInput = deluxe.Vector(shortname='wi', default=0) warp = deluxe.Group( [warpMode, warpNoiseAmount, warpNoiseFreq, warpNoiseOffset, warpInput]) Xtex = deluxe.Image(shortname="xtx", default="", help="Texture for projection on x-axis.") Xrot = deluxe.Float(shortname="xro", default=0, softmin=-180, softmax=180, help="Rotation about x-axis of x-axis projection.") XrepeatS = deluxe.Float(shortname="xrs", default=1, help="Repetitions of s-coordinate.", softmin=-2, softmax=2) XrepeatTSameAsS = deluxe.Boolean( shortname="xrst", default=True, help= "Also use XrepeatS value for repetitions of t-coordinate (ignore XrepeatT parameter)." ) XrepeatT = deluxe.Float( shortname="xrt", default=1, help="Repetitions of t-coordinate (ignored if XrepeatTSameAsS is on).", softmin=-2, softmax=2) Xprojection = deluxe.Group( [Xtex, Xrot, XrepeatS, XrepeatTSameAsS, XrepeatT], collapse=False) Ytex = deluxe.Image( shortname="ytx", default="", help= "Texture for projection on y-axis. If blank or invalid, Xtex is used." ) Yrot = deluxe.Float(shortname="yro", default=0, softmin=-180, softmax=180, help="Rotation about y-axis of y-axis projection.") YrepeatS = deluxe.Float(shortname="yrs", default=1, help="Repetitions of s-coordinate.", softmin=-2, softmax=2) YrepeatTSameAsS = deluxe.Boolean( shortname="yrst", default=True, help= "Also use YrepeatS value for repetitions of t-coordinate (ignore YrepeatT parameter)." ) YrepeatT = deluxe.Float( shortname="yrt", default=1, help="Repetitions of t-coordinate (ignored if YrepeatTSameAsS is on).", softmin=-2, softmax=2) Yprojection = deluxe.Group( [Ytex, Yrot, YrepeatS, YrepeatTSameAsS, YrepeatT], collapse=False) Ztex = deluxe.Image( shortname="ztx", default="", help= "Texture for projection on z-axis. If blank or invalid, Xtex is used." ) Zrot = deluxe.Float(shortname="zro", default=0, softmin=-180, softmax=180, help="Rotation about z-axis of z-axis projection.") ZrepeatS = deluxe.Float(shortname="zrs", default=1, help="Repetitions of s-coordinate.", softmin=-2, softmax=2) ZrepeatTSameAsS = deluxe.Boolean( shortname="zrst", default=True, help= "Also use ZrepeatS value for repetitions of t-coordinate (ignore ZrepeatT parameter)." ) ZrepeatT = deluxe.Float( shortname="zrt", default=1, help="Repetitions of t-coordinate (ignored if ZrepeatTSameAsS is on).", softmin=-2, softmax=2) Zprojection = deluxe.Group( [Ztex, Zrot, ZrepeatS, ZrepeatTSameAsS, ZrepeatT], collapse=False) Pref = deluxe.Point(message=True, messagetype='Pref_param', storage='varying') outColor = deluxe.Color(output=True) rslpost = "" rsl = \ """
class dl_blendByNormal(deluxe.Utility): typeid = 0x00300337 description = "Blend by normal." globalCoordsys = deluxe.CoordinateSystem( shortname='gcs', label='Global Coordsys', default='world', description= "Coordsys to use if an axis' Coordsys To Use is set to Global Coordsys (default)." ) globalWarpMode = deluxe.Enum(shortname='gm', default='Off', choices=['Off', 'Noise', 'Input']) globalWarpNoiseAmount = deluxe.Float(shortname='gwna', default=1) globalWarpNoiseFreq = deluxe.Float(shortname='gwnf', default=1) globalWarpNoiseOffset = deluxe.Vector(shortname='gwno', default=0) globalWarpInput = deluxe.Vector(shortname='gwi', default=0) globalWarp = deluxe.Group([ globalWarpMode, globalWarpNoiseAmount, globalWarpNoiseFreq, globalWarpNoiseOffset, globalWarpInput ]) blendWidth = deluxe.Float(default=1) label = deluxe.String(shortname='lbl', description=""" label of this axis. """) colour = deluxe.Color(shortname='clr', description=""" See help for "direction" parm. """) coordsysToUse = deluxe.Enum( shortname='cstu', default='Global Coordsys', choices=['Global Coordsys', 'Coordsys For This Axis'], description=""" Which coordinate system to use, Global Coordsys parm or Coordsys For This Axis """) coordsysForThisAxis = deluxe.String( shortname='cs', default='world', description=""" Coordinate system of the "direction" parm. """) direction = deluxe.Vector(shortname='dir', default=(0, 1, 0), description=""" Where the normal is closest to this direction (or its reverse, see help for "orientation" parm), the corresponding "colour" parameter will have the greatest influence. """) orientation = deluxe.Enum( default='positive and negative', choices=['positive', 'positive and negative', 'negative'], description=""" Choose whether this axis affects the surface where N is aligned with the axis direction ("positive"), opposite to it ("negative"), or both ("positive and negative"). """) hemispheres = deluxe.Float( default=1, min=0, max=2, description= "How many hemispheres this axis affects, 1=half the sphere, 2=the whole sphere" ) weight = deluxe.Float(shortname='wt', default=1, description="The relative influence of this axis.") warpToUse = deluxe.Enum(shortname='wtu', default='Global', choices=['Global', 'Local']) warpMode = deluxe.Enum(shortname='wm', default='Off', choices=['Off', 'Noise', 'Input']) warpNoiseAmount = deluxe.Float(shortname='wna', default=1) warpNoiseFreq = deluxe.Float(shortname='wnf', default=1) warpNoiseOffset = deluxe.Vector(shortname='wno', default=0) warpInput = deluxe.Vector(shortname='wi', default=0) axes = deluxe.Compound([ label, colour, coordsysToUse, coordsysForThisAxis, direction, orientation, hemispheres, weight, warpToUse, warpMode, warpNoiseAmount, warpNoiseFreq, warpNoiseOffset, warpInput ], shortname='xs', array=True) outColor = deluxe.Color(output=True) element0outColor = deluxe.Color(output=True) element1outColor = deluxe.Color(output=True) element2outColor = deluxe.Color(output=True) element3outColor = deluxe.Color(output=True) element4outColor = deluxe.Color(output=True) element5outColor = deluxe.Color(output=True) element6outColor = deluxe.Color(output=True) element7outColor = deluxe.Color(output=True) element0outAlpha = deluxe.Float(output=True) element1outAlpha = deluxe.Float(output=True) element2outAlpha = deluxe.Float(output=True) element3outAlpha = deluxe.Float(output=True) element4outAlpha = deluxe.Float(output=True) element5outAlpha = deluxe.Float(output=True) element6outAlpha = deluxe.Float(output=True) element7outAlpha = deluxe.Float(output=True) # TODO: Uncomment and fix this so that when it's first # instantiated, the node has 3 elements in the axes[] array, each # in world space, each with orientation = positive and negative, with # axisVector = (1,0,0), (0,1,0), and (0,0,1), respectively. # #def postConstructor(self): # axesPlug = MPlug(self.thisMObject(), self.axes.obj) # for i in range(0, 3): # axes0Plug = axesPlug.elementByLogicalIndex(i) # axesColorPlug = axes0Plug.child(self.axisColor.obj) # axesColorPlug.setMObject(MFnStringData().create('whatever')) # # super(dl_blendByNormal, self).postConstructor() rsl = \ """ #define assingElement(type, i, val) \ if (i == 0) o_element0out##type = val; \ else if (i == 1) o_element1out##type = val; \ else if (i == 2) o_element2out##type = val; \ else if (i == 3) o_element3out##type = val; \ else if (i == 4) o_element4out##type = val; \ else if (i == 5) o_element5out##type = val; \ else if (i == 6) o_element6out##type = val; \ else if (i == 7) o_element7out##type = val; void warpV( float warpMode; float warpNoiseAmount; float warpNoiseFreq; vector warpNoiseOffset; vector warpInput; point Pp; output vector v) { if (warpMode == 1) { v += (1-2*(vector noise((Pp + warpNoiseOffset)*warpNoiseFreq)))*warpNoiseAmount; } else if (warpMode == 2) { v += warpInput; } v = normalize(v); } float weights[30]; float nAxes = arraylength(i_colour); extern normal N; uniform float i; float wtTotal = 0; for (i = 0; i < nAxes; i += 1) { string coordsys = i_coordsysToUse[i] == 0 ? i_globalCoordsys : i_coordsysForThisAxis[i]; coordsys = coordsys == "" ? "world" : coordsys; normal Nn = normalize(ntransform(coordsys, N)); extern point P; point Pp = transform(coordsys, P); vector dir = i_direction[i]; float warpMode = i_globalWarpMode; float warpNoiseAmount = i_globalWarpNoiseAmount; float warpNoiseFreq = i_globalWarpNoiseFreq; vector warpNoiseOffset = i_globalWarpNoiseOffset; vector warpInput = i_globalWarpInput; if (i_warpToUse[i] == 1) { warpMode = i_warpMode[i]; warpNoiseAmount = i_warpNoiseAmount[i]; warpNoiseOffset = i_warpNoiseOffset[i]; warpNoiseFreq = i_warpNoiseFreq[i]; warpInput = i_warpInput[i]; } warpV(warpMode, warpNoiseAmount, warpNoiseFreq, warpNoiseOffset, warpInput, Pp, dir); float dot = Nn.normalize(dir); float posWt = smoothstep(1-i_hemispheres[i], 1, dot); float negWt = smoothstep(1-i_hemispheres[i], 1, -dot); float weight = i_orientation[i] == 0 ? posWt : i_orientation[i] == 1 ? posWt + negWt : negWt; weights[i] = i_weight[i]*pow(weight, 1/max(.01, i_blendWidth)); wtTotal += weights[i]; } color clrTotal = 0; if (wtTotal > 0) { for (i = 0; i < nAxes; i += 1) { clrTotal += i_colour[i] * weights[i]/wtTotal; assingElement(Color, i, i_colour[i]*weights[i]/wtTotal); assingElement(Alpha, i, weights[i]/wtTotal); } } o_outColor = clrTotal; """ rslpost = ""
class dl_switch(deluxe.Utility): typeid = 0x00370002 description = "Switcher" dl_switch_selectInput_override_0 = deluxe.Float(shortname="sio0", default=-1, message=True, help="") dl_switch_selectInput_override_1 = deluxe.Float(shortname="sio1", default=-1, message=True, help="") dl_switch_selectInput_override_2 = deluxe.Float(shortname="sio2", default=-1, message=True, help="") dl_switch_selectInput_override_3 = deluxe.Float(shortname="sio3", default=-1, message=True, help="") dl_switch_selectInput_override_4 = deluxe.Float(shortname="sio4", default=-1, message=True, help="") dl_switch_selectInput_override_5 = deluxe.Float(shortname="sio5", default=-1, message=True, help="") dl_switch_selectInput_override_6 = deluxe.Float(shortname="sio6", default=-1, message=True, help="") dl_switch_selectInput_override_7 = deluxe.Float(shortname="sio7", default=-1, message=True, help="") dl_switch_selectInput_override_8 = deluxe.Float(shortname="sio8", default=-1, message=True, help="") dl_switch_selectInput_override_9 = deluxe.Float(shortname="sio9", default=-1, message=True, help="") colorSet1 = deluxe.Color(shortname="cs1", storage='varying', default=-1, message=True, help="") selectInput = deluxe.Enum( default='0', choices=['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], storage='uniform', help=""" The default input color and float that are assigned to outColor and outAlpha. This will be overridden by the rib attr specified in ribAttrOverride; the primvar specified in primvarOverride will override them both. """) primvarOverride = deluxe.Enum(default='None', choices=[ 'dl_switch_selectInput_override_0', 'dl_switch_selectInput_override_1', 'dl_switch_selectInput_override_2', 'dl_switch_selectInput_override_3', 'dl_switch_selectInput_override_4', 'dl_switch_selectInput_override_5', 'dl_switch_selectInput_override_6', 'dl_switch_selectInput_override_7', 'dl_switch_selectInput_override_8', 'dl_switch_selectInput_override_9', 'colorSet1[0]', 'None' ], storage='uniform', help=""" Specify the name of the primvar that will override the selectInput parameter." """) colorSet1nChoices = deluxe.Integer( shortname="cs1m", help= "How many inputs to randomly choose from when primvarOverride = 'colorSet1[0]'" ) ribAttrOverride = deluxe.String(help=""" The rib attribute that will override the selectInput parameter. For example, if you have a user rib attr called "switch_override", enter "user:switch_override". """) inputFloat0 = deluxe.Float( shortname="if0", help="This will be assigned to outAlpha if input 0 is selected.") inputFloat1 = deluxe.Float( shortname="if1", help="This will be assigned to outAlpha if input 1 is selected.") inputFloat2 = deluxe.Float( shortname="if2", help="This will be assigned to outAlpha if input 2 is selected.") inputFloat3 = deluxe.Float( shortname="if3", help="This will be assigned to outAlpha if input 3 is selected.") inputFloat4 = deluxe.Float( shortname="if4", help="This will be assigned to outAlpha if input 4 is selected.") inputFloat5 = deluxe.Float( shortname="if5", help="This will be assigned to outAlpha if input 5 is selected.") inputFloat6 = deluxe.Float( shortname="if6", help="This will be assigned to outAlpha if input 6 is selected.") inputFloat7 = deluxe.Float( shortname="if7", help="This will be assigned to outAlpha if input 7 is selected.") inputFloat8 = deluxe.Float( shortname="if8", help="This will be assigned to outAlpha if input 8 is selected.") inputFloat9 = deluxe.Float( shortname="if9", help="This will be assigned to outAlpha if input 9 is selected.") inputColor0 = deluxe.Color( shortname="ic0", help="This will be assigned to outColor if input 0 is selected.") inputColor1 = deluxe.Color( shortname="ic1", help="This will be assigned to outColor if input 1 is selected.") inputColor2 = deluxe.Color( shortname="ic2", help="This will be assigned to outColor if input 2 is selected.") inputColor3 = deluxe.Color( shortname="ic3", help="This will be assigned to outColor if input 3 is selected.") inputColor4 = deluxe.Color( shortname="ic4", help="This will be assigned to outColor if input 4 is selected.") inputColor5 = deluxe.Color( shortname="ic5", help="This will be assigned to outColor if input 5 is selected.") inputColor6 = deluxe.Color( shortname="ic6", help="This will be assigned to outColor if input 6 is selected.") inputColor7 = deluxe.Color( shortname="ic7", help="This will be assigned to outColor if input 7 is selected.") inputColor8 = deluxe.Color( shortname="ic8", help="This will be assigned to outColor if input 8 is selected.") inputColor9 = deluxe.Color( shortname="ic9", help="This will be assigned to outColor if input 9 is selected.") outColor = deluxe.Color(shortname="oc", output=True) outAlpha = deluxe.Float(shortname="oa", output=True) rslpost = "" rsl = """
class dl_blocker(deluxe.Utility): typeid = 0x00300201 includes = ["shadow_utils.h"] color = deluxe.Color(default=1, storage="varying", help="Color to tint the fake shadow.", prepare=True) intensity = deluxe.Float(default=1, storage="varying", help="Intensity of the fake shadow.", prepare=True) coordsys = deluxe.CoordinateSystem(default="", shortname="cs", label="coordinateSystem") width = deluxe.Float(storage="uniform", default=1, help="Width of the blocker's superellipse.") height = deluxe.Float(storage="uniform", default=1, help="Height of the blocker's superellipse.") wedge = deluxe.Float(storage="uniform", shortname="wg", default=0.1, help="Defines horizontal edge fuzziness.") hedge = deluxe.Float(storage="uniform", shortname="hg", default=0.1, help="Defines vertical edge fuzziness.") roundness = deluxe.Float( default=1, storage="uniform", help="""Controls how rounded the corners of the superellipse are. If this value is 0, the cross-section will be a perfect rectangle. If the value is 1, the cross-section will be a perfect circle.""" ) cutOn = deluxe.Float(shortname="con", storage="uniform", default=0.01, help="Cut-on setting from light.", notemplate=True, connectable=True) lightType = deluxe.Enum(default='Spot', choices=['Spot', 'Point', 'Distant'], help="Light type setting from light.", notemplate=True, connectable=True) blockerColor = deluxe.Color(output=True, notemplate=True, hidden=True) blockerValue = deluxe.Float(output=True, notemplate=True, hidden=True) blocker = deluxe.Compound([blockerColor, blockerValue], notemplate=True) rslprepare = \ """ extern point Ps; extern point P; extern vector L; extern float ss; extern float tt; if (i_coordsys != "") { point Pl = transform ("shader", Ps); point shadoworigin; if (i_lightType == 2) { // Parallel rays shadoworigin = point "shader" (xcomp(Pl), ycomp(Pl), i_cutOn); } else { shadoworigin = point "shader" (0,0,0); } vector sAx = normalize(vtransform(i_coordsys, "current", vector (1, 0, 0))); vector tAx = normalize(vtransform(i_coordsys, "current", vector (0, 1, 0))); point cOrg = transform(i_coordsys, "current", point (0, 0, 0)); vector soToP = Ps - shadoworigin; vector Nplane = sAx^tAx; float t = ((-Nplane).(shadoworigin-cOrg)) / (Nplane.(Ps - shadoworigin)); point Pint = shadoworigin + t*(shadoworigin-Ps); vector cOrgToPint = Pint - cOrg; point PintCs = transform(i_coordsys, Pint); float sBk = (1+PintCs[0])/2; float tBk = 1-(1+PintCs[1])/2; ss = sBk; tt = tBk; } """ rsl = \ """
class dl_blendByAxis(deluxe.Utility): typeid = 0x00300338 description = "Blend by axis." coordsys = deluxe.CoordinateSystem(shortname='cs', default='world') axis = deluxe.Enum(default='Y', choices=['X', 'Y', 'Z']) globalWarpMode = deluxe.Enum(shortname='gm', default='Off', choices=['Off', 'Noise','Input']) globalWarpNoiseAmount = deluxe.Float(shortname='gwna', default=1) globalWarpNoiseFreq = deluxe.Float(shortname='gwnf', default=1) globalWarpNoiseOffset = deluxe.Vector(shortname='gwno', default=0) globalWarpInput = deluxe.Vector(shortname='gwi', default=0) globalWarp = deluxe.Group([globalWarpMode, globalWarpNoiseAmount, globalWarpNoiseFreq, globalWarpNoiseOffset, globalWarpInput]) label = deluxe.String(shortname='lbl') colour = deluxe.Color(shortname='clr') value = deluxe.Float(default=0) blend = deluxe.Enum(default='smooth', choices=['smooth', 'linear', 'step']) warpToUse = deluxe.Enum(shortname='wtu', default='Global', choices=['Global','Local']) warpMode = deluxe.Enum(shortname='wm', default='Off', choices=['Off', 'Noise','Input']) warpNoiseAmount = deluxe.Float(shortname='wna', default=1) warpNoiseFreq = deluxe.Float(shortname='wnf', default=1) warpNoiseOffset = deluxe.Vector(shortname='wno', default=0) warpInput = deluxe.Vector(shortname='wi', default=0) entries = deluxe.Compound([label, colour, value, blend, warpToUse, warpMode, warpNoiseAmount, warpNoiseFreq, warpNoiseOffset, warpInput], array=True) outColor = deluxe.Color(output=True) element0outColor = deluxe.Color(output=True) element1outColor = deluxe.Color(output=True) element2outColor = deluxe.Color(output=True) element3outColor = deluxe.Color(output=True) element4outColor = deluxe.Color(output=True) element5outColor = deluxe.Color(output=True) element6outColor = deluxe.Color(output=True) element7outColor = deluxe.Color(output=True) element0outAlpha = deluxe.Float(output=True) element1outAlpha = deluxe.Float(output=True) element2outAlpha = deluxe.Float(output=True) element3outAlpha = deluxe.Float(output=True) element4outAlpha = deluxe.Float(output=True) element5outAlpha = deluxe.Float(output=True) element6outAlpha = deluxe.Float(output=True) element7outAlpha = deluxe.Float(output=True) # TODO: Uncomment and fix this so that when it's first # instantiated, the node has 3 elements in the axes[] array, each # in world space, each with orientation = positive and negative, with # axisVector = (1,0,0), (0,1,0), and (0,0,1), respectively. # #def postConstructor(self): # axesPlug = MPlug(self.thisMObject(), self.axes.obj) # for i in range(0, 3): # axes0Plug = axesPlug.elementByLogicalIndex(i) # axesColorPlug = axes0Plug.child(self.axisColor.obj) # axesColorPlug.setMObject(MFnStringData().create('whatever')) # # super(dl_blendByAxis, self).postConstructor() rsl = \ """ #define assingElement(type, i, val) \ if (i == 0) o_element0out##type = val; \ else if (i == 1) o_element1out##type = val; \ else if (i == 2) o_element2out##type = val; \ else if (i == 3) o_element3out##type = val; \ else if (i == 4) o_element4out##type = val; \ else if (i == 5) o_element5out##type = val; \ else if (i == 6) o_element6out##type = val; \ else if (i == 7) o_element7out##type = val; float linInterp (float start, end, val) { return clamp((val-start)/(end-start), 0, 1); } float interp (float start, end, val, mode) { float result; if (mode < .5) { result = smoothstep(start, end, val); } else if (mode < 1.5) { result = linInterp(start, end, val); } else { result = filterstep(end, val); } return result; } float nElements = arraylength(i_colour); color result = 0; if (nElements > 0) { float nextI=0; float prevI=0; float nextVal=0; float prevVal=0; color nextClr=0; color prevClr=0; float nextBnd=0; float i; string coordsys = i_coordsys == "" ? "world" : i_coordsys; extern point P; point Pcs = transform(coordsys, P); float coord = Pcs[i_axis]; point Pnoise = Pcs; Pnoise[i_axis] = 0; float warpedValues[nElements]; for (i = 0; i < nElements; i += 1) { float warpMode = i_globalWarpMode; float warpNoiseAmount = i_globalWarpNoiseAmount; float warpNoiseFreq = i_globalWarpNoiseFreq; vector warpNoiseOffset = i_globalWarpNoiseOffset; vector warpInput = i_globalWarpInput; if (i_warpToUse[i] == 1) { warpMode = i_warpMode[i]; warpNoiseAmount = i_warpNoiseAmount[i]; warpNoiseFreq = i_warpNoiseFreq[i]; warpNoiseOffset = i_warpNoiseOffset[i]; warpInput = i_warpInput[i]; } float warp = warpMode == 0 ? 0 : warpMode == 2 ? warpInput[i_axis] : warpNoiseAmount * (1-2*(float noise((Pnoise + warpNoiseOffset) * warpNoiseFreq))); warpedValues[i] = i_value[i] + warp; } float foundPrev = 0; float foundNext = 0; for (i = 0; i < nElements; i += 1) { if (warpedValues[i] > coord) { if (foundNext < .5 || warpedValues[i] < nextVal) { foundNext = 1; nextVal = warpedValues[i]; nextClr = i_colour[i]; nextBnd = i_blend[i]; nextI = i; } } else { if (foundPrev < .5 || warpedValues[i] > prevVal) { foundPrev = 1; prevVal = warpedValues[i]; prevClr = i_colour[i]; prevI = i; } } } if (foundPrev < .5) { result = nextClr; assingElement(Color, nextI, result); assingElement(Alpha, nextI, 1); } else if (foundNext < .5) { result = prevClr; assingElement(Color, prevI, result); assingElement(Alpha, prevI, 1); } else { float mixer = interp(prevVal, nextVal, coord, nextBnd); result = mix(prevClr, nextClr, mixer); assingElement(Color, nextI, nextClr * mixer); assingElement(Color, prevI, prevClr * (1-mixer)); assingElement(Alpha, nextI, mixer); assingElement(Alpha, prevI, 1-mixer); } } o_outColor = result; """ rslpost = ""
class dl_indirectLightShape(deluxe.EnvLight): typeid = 0x00310003 description = "Light that does ambient occlusion and indirect diffuse lighting." includes = [ "remap_utils.h", "component_utils.h", "physicalsky_utils.h", "env_utils.h" ] # deluxe.EnvLight.envMap.default = 'default_indirect.tdl' # envConvolveMode = deluxe.Enum( default='Use envBlur parm', label='Convolve Mode', choices=['Use envBlur parm', 'Auto (ignore envBlur parm)'], help="""Use envBlur parm = use environment() function with envBlur parm, Auto (ignore envBlur parm) = use indirectdiffuse() function which automitically blurs map.""") envBlur = deluxe.Float( min=0, softmax=1, default=0, storage='uniform', label='Blur', help= """Blur for envMap, only used when envConvolveMode = 'Use envBlur parm'.""" ) envIntensity = deluxe.Float(default=1, label='Intensity') envColor = deluxe.Color(default=1, label='Color') environmentMap = deluxe.Group( [ deluxe.EnvLight.envMethod, envIntensity, envColor, deluxe.EnvLight.envMap, deluxe.EnvLight.envSpace, envConvolveMode, envBlur, deluxe.EnvLight.physicalSky, deluxe.EnvLight.envColorCorrection ], shortname='emg', collapse=False, ) occMethod = deluxe.Enum( default='Point Cloud', choices=['None', 'Ray Tracing', 'Point Cloud'], label='Occlusion Method', help=""""Ray Tracing" uses the standard occlusion() call. "Point Cloud" uses previously baked point clouds. """) ambientOcclusion = deluxe.Group( [ occMethod, deluxe.EnvLight.occPointCloud, deluxe.EnvLight.occRayTracing, deluxe.EnvLight.occAdvanced, deluxe.EnvLight.occRemapping ], collapse=False, ) indirectMethod = deluxe.Enum( default='None', choices=['None', 'Ray Tracing', 'Point Cloud'], label='Color Bleeding Method', shortname='indm', help=""""Ray Tracing" uses the standard indirectdiffuse() call. "Point Cloud" uses previously baked point clouds. """) indirectIntensity = deluxe.Float(default=1, label='Intensity') indirectMaxDistance = deluxe.Float( shortname='idmd', softmin=0, default=1e38, storage='uniform', label='Max Distance', help= "(Ray Tracing, Point Cloud) Only consider intersections closer than this distance." ) indirectSamples = deluxe.Integer( shortname='ids', min=0, max=256, default=64, label='Samples', help="""(Ray Tracing) The number of rays to trace.""") indirectAdaptiveSampling = deluxe.Boolean( shortname='idas', default=False, label='Adaptive Sampling', help="(Ray Tracing) Enables or disables adaptive sampling.") indirectRayBias = deluxe.Float( default=0.1, min=0, softmax=2, label='Ray Bias', help= """(Ray Tracing, Point Cloud) Specifies a bias for ray's starting point to avoid potentially erroneous intersections with the emitting surface.""" ) indirectFalloffMode = deluxe.Enum( shortname="psifm", default='Linear', choices=['Exponential', 'Linear'], label='Falloff Mode', help= """(Ray Tracing, Point Cloud) Specifies the falloff curve to use.""") indirectFalloff = deluxe.Float( default=1, min=0, softmax=5, label='Falloff', help= """(Ray Tracing, Point Cloud) This shapes the falloff curve. In the exponential case the curve is exp( -falloff * hitdist ) and in the linear case it is pow(1-hitdist/maxdist, falloff).""" ) indirectPtcFile = deluxe.File( default='', label='Point Cloud File', help= """(Point Cloud) The point cloud file in which baked points with radiosity are stored.""" ) occPtcFileIsDirectory = deluxe.Boolean(default=False) indirectMaxSolidAngle = deluxe.Float( softmin=0.01, softmax=0.5, default=0.1, storage='uniform', label='Max Solid Angle', help="""(Point Cloud) This is a quality vs speed control knob.""") indirectClamp = deluxe.Boolean( default=True, label='Clamp', help= """(Point Cloud) Setting this parameter to 1 will force 3DELIGHT to account for occlusion in dense environments. The results obtained with this parameter on should look similar to what a Ray Tracing rendering would give. Enabling this parameter will slow down the Point Cloud algorithm by a factor of 2.""") indirectSampleBase = deluxe.Float( default=1, label='Sample Base', help= """(Point Cloud) Scales the amount of jittering of the start position of rays. The default is to jitter over the area of one micropolygon.""" ) indirectHitSides = deluxe.Enum( default='Both', choices=['Front', 'Back', 'Both'], label='Hit Sides', help= """(Point Cloud) Specifies which side(s) of the point cloud's samples will produce occlusion.""" ) indirectPointCloud = deluxe.Group([ indirectPtcFile, occPtcFileIsDirectory, indirectMaxSolidAngle, indirectClamp, indirectSampleBase, indirectHitSides ], label="Point Cloud") indirectRayTracing = deluxe.Group( [indirectSamples, indirectAdaptiveSampling, indirectRayBias], label="Ray Tracing", ) indirectAdvanced = deluxe.Group( [indirectMaxDistance, indirectFalloffMode, indirectFalloff], label='Advanced') colorBleeding = deluxe.Group( [ indirectMethod, indirectIntensity, indirectPointCloud, indirectRayTracing, indirectAdvanced ], collapse=False, ) __computeOcclusion = deluxe.Float(default=1, message=True, messagetype='lightsource') __occluded = deluxe.Color(default=0, output=True, message=True, storage='varying', messagetype='lightsource') __occlusionColor = deluxe.Color(default=0, output=True, message=True, messagetype='lightsource') __indirect_color = deluxe.Color(default=0, output=True, message=True, storage='varying', messagetype='lightsource') __bentnormal = deluxe.Color(default=0, output=True, message=True, storage='varying', messagetype='lightsource') # category __category = deluxe.String(default='indirect', message=True, messagetype='lightsource') _3delight_light_category = deluxe.String(default='indirect', notemplate=True, norsl=True) rsl = \ """
class dl_textureMap(deluxe.Texture2D): typeid = 0x00370001 description = "Wrapper around 3Delight \"texture\" function" textureName = deluxe.Image(storage='uniform', help="""Texture file in tdl format. Use 'N' or 'NNNN' for the frame number if using indexed sprites.""") indexedSprites = deluxe.Boolean(help="Treat the filename as a sequence indexed with spritePP.") blur = deluxe.Float(default=0, min=0, softmax=0.2, storage='uniform', help="""Specifies an additional length to be added to texture lookup region in both s and t, expressed in units of texture coordinates (range = [0..1]). A value of 1.0 would request that the entire texture be blurred in the result.""") filterType = deluxe.Enum(default='Gaussian', choices=['Box', 'Triangle', 'Gaussian'], storage='uniform', help="Specifies the reconstruction filter to use when accessing the texture map."); samples = deluxe.Integer(default=4, storage='uniform', help="(Box filter only) Number of samples.") gamma = deluxe.Float3(default=1, min=0.0001, max=3, help="Gamma correction to apply to the texture.") gammaCorrection = deluxe.Group([gamma]) spriteNumPP = deluxe.Integer(default=0, storage='uniform', message=True) coordsys = deluxe.CoordinateSystem(help=""" Coordinate system (or camera) in which to look up texture. Use a delightCoordinateSystem shape name (eg. delightCoordinateSystemShape1) or mayaCamera:cameraName (eg. "mayaCamera:persp", NOT "mayaCamera:perspShape"). """) alphaInsideUVMult = deluxe.Float(shortname="aism", default=1, help=""" Multiply the alpha by this value where the surface is inside the UV coordinates (ie. u and v are > 0 and < 1). """) alphaInsideUVOffset = deluxe.Float(shortname="aiso", default=0, help=""" Add this value to the alpha where the surface is inside the UV coordinates (ie. u and v are > 0 and < 1). """) specifyAlphaOutsideUV = deluxe.Boolean(default=False, help=""" If on, alpha will be set to alphaOutsideUV value where the surface is outside the UV coordinates (ie. u or v is > 1 or < 0).""") alphaOutsideUV = deluxe.Float(shortname="aos", default=0, help="""If specifyAlphaOutsideUV is on, this is the alpha where the surface is outside the UV coordinates (ie. u or v is > 1 or < 0).""") alphaCorrection = deluxe.Group([alphaInsideUVMult, alphaInsideUVOffset, specifyAlphaOutsideUV, alphaOutsideUV]) warpMode = deluxe.Enum(shortname='wm', default='Off', choices=['Off', 'Noise','Input']) warpNoiseAmount = deluxe.Float2(shortname='wna', default=1) warpNoiseFreq = deluxe.Float2(shortname='wnf', default=1) warpNoiseOffset = deluxe.Float2(shortname='wno', default=0) warpInput = deluxe.Float2(shortname='wi', default=0) warp = deluxe.Group([ warpMode, warpNoiseAmount, warpNoiseFreq, warpNoiseOffset, warpInput]) rsl = """
class dl_projectionLightShape(deluxe.Light): typeid = 0x00310005 includes = ["shadow_utils.h", "utils.h"] color = deluxe.Color(shortname='clr', prepare=True, storage='varying', help=""" Colour to project. Plug this into a maya File node's outColor to project a texture. """) transparency = deluxe.Color(default=0, shortname='trn', storage='varying', help=""" Transparency (1-alpha) of projected colour. Plug this into a maya File node's outTransparency to use the texture's (inverted) alpha channel. """) compositeMode = deluxe.Enum(shortname='cpmd', default='Over', choices=['Over', 'Add'], help=""" Compositing mode over previous projections. projectionLights are evaluated in alphabetical order. """) #repeatMode = deluxe.Enum(default='Blank', choices=['Blank', 'Repeat', 'Hold'], help="") projLightSubset = deluxe.String(default="", help=""" Only dl_projectionCollector nodes with matching projLightSubset values will receive projections from this light. """) # mapped shadows shadowBlur = deluxe.Float(label='Blur', shortname='bl', default=0.01, min=0, softmax=0.2, storage='uniform', help="""Amount to blur the shadow. A value of 1.0 would request that the entire texture be blurred in the result.""") shadowFilterType = deluxe.Enum(label='Filter Type', default='Gaussian', choices=['Box','Triangle','Gaussian']); shadowBias = deluxe.Float(label='Bias', shortname='bi', default=0.225, min=0, softmax=5, storage='uniform', help="Used to prevent self-shadowing. If set to 0, the global bias is used.") shadowSamples = deluxe.Integer(label='Samples', default=16, min=0, softmax=16) useSoftShadowDecay = deluxe.Boolean(default=False, help="Turns on soft shadows that decay with distance.") shadowMinimumRadius = deluxe.Float(label='Minimum Radius', shortname='mnr', default=0.001, min=0, softmax=0.2, storage='uniform') shadowMaximumRadius = deluxe.Float(label='Maximum Radius', shortname='mxr', default=0.1, min=0, softmax=0.2, storage='uniform') selfShadowReduce = deluxe.Float(default=2, min=0, softmax=5, storage='uniform') shadowDecay = deluxe.Float(label='Decay', default=0, min=0, softmax=5, storage='uniform') shadowDecayCutOn = deluxe.Float(label='Decay Cut-On', shortname='sdcon', default=10, min=0, max=1000, storage='uniform') shadowDecayCutOff = deluxe.Float(label='Decay Cut-Off', shortname='sdcoff', default=10, min=0, max=1000, storage='uniform') softShadowDecay = deluxe.Group([useSoftShadowDecay, shadowMinimumRadius, shadowMaximumRadius, selfShadowReduce, shadowDecay, shadowDecayCutOn, shadowDecayCutOff]) mappedShadows = deluxe.Group([shadowBlur, shadowFilterType, shadowBias, shadowSamples, softShadowDecay]) # output messages __compositeMode = deluxe.Float(default=0, storage='varying', output=True, message=True, messagetype='lightsource') __alpha = deluxe.Float(default=1, storage='varying', output=True, message=True, messagetype='lightsource') __projLightSubset = deluxe.String(default="", output=True, message=True, messagetype='lightsource') # category __category = deluxe.String(default='texture', message=True, messagetype='lightsource') _3delight_light_category = deluxe.String(shortname='cat', default='texture', notemplate=True, norsl=True) rslprepare = \ """ extern float ss; extern float tt; extern point Ps; point Pl = transform("shader", Ps); ss = (Pl[0] + 1)/2; tt = (Pl[1] + 1)/2; """ rsl = \ """ extern color Cl; extern vector L; extern point Ps; extern normal Ns; extern vector I; extern float __compositeMode; extern float __alpha; extern string __projLightSubset; point Pl = transform("shader", Ps); float ss = Pl[0]; float tt = Pl[1]; __compositeMode = i_compositeMode; float unshadowedAlpha = luminance(1-i_transparency); __projLightSubset = i_projLightSubset; illuminate(Ps) { extern uniform string shadowmapname; color unoccluded = color getShadowMapContribution(Ps, shadowmapname, i_shadowBlur, i_shadowFilterType, i_shadowBias, i_shadowSamples, i_useSoftShadowDecay, i_shadowMinimumRadius, i_shadowMaximumRadius, i_selfShadowReduce, i_shadowDecay, i_shadowDecayCutOn, i_shadowDecayCutOff); __alpha = unshadowedAlpha * luminance(unoccluded); Cl = i_color * unoccluded; } """ def draw(self, view, path, style, status): thisNode = self.thisMObject() fnThisNode = OpenMaya.MFnDependencyNode(thisNode) view.beginGL() glFT.glPushAttrib(OpenMayaRender.MGL_ALL_ATTRIB_BITS) # Color of main light cone ui. def dormantColor(clrNum): if status == OpenMayaUI.M3dView.kDormant: view.setDrawColor(clrNum, OpenMayaUI.M3dView.kActiveColors) dormantColor(11) # Colours: # 0 = black, 1 = mid grey, 2 = light grey, 3 = burgundy, 4 = dark blue, # 5 = mid blue, 6 = dark green, 7 = dark purple, 8 = pink, 9 = burgundy again, # 11 = burgundy again, 12 = red, 13 = green, 14 = blue, 15 = white, 16 = yellow glFT.glPushMatrix() #glFT.glScalef(iconSize, iconSize, iconSize) glFT.glBegin(OpenMayaRender.MGL_LINE_LOOP) glFT.glVertex3f(-1, 1, 0) glFT.glVertex3f(1, 1, 0) glFT.glVertex3f(1, - 1, 0) glFT.glVertex3f(-1, - 1, 0) glFT.glEnd() glFT.glBegin(OpenMayaRender.MGL_LINES) glFT.glVertex3f(-1, 1, 0) glFT.glVertex3f(1, - 1, 0) glFT.glVertex3f(1, 1, 0) glFT.glVertex3f(-1, - 1, 0) glFT.glVertex3f(0, 0, 0) glFT.glVertex3f(0, 0, - 0.7) glFT.glVertex3f(0, 0, - 0.7) glFT.glVertex3f(0, 0.04, - 0.4) glFT.glVertex3f(0, 0, 0. - 0.7) glFT.glVertex3f(0, - 0.04, - 0.4) glFT.glVertex3f(0, 0.04, - 0.4) glFT.glVertex3f(0, - 0.04, - 0.4) glFT.glVertex3f(0, 0, - 0.7) glFT.glVertex3f(0.04, 0, - 0.4) glFT.glVertex3f(0, 0, 0. - 0.7) glFT.glVertex3f(-0.04, 0, - 0.4) glFT.glVertex3f(0.04, 0, - 0.4) glFT.glVertex3f(-0.04, 0, - 0.4) glFT.glEnd() glFT.glPopMatrix() glFT.glPopAttrib() view.endGL()
class dl_layer(deluxe.ShadingCodeComponent): typeid = 0x00310010 classification = "rendernode/3delight/material:shader/surface" description = "Generic layered shader." # includes = ["blend_utils.h", "displacement_utils.h"] # Used for easy code generation replacement _codetokens = {} # Utility functions parameters (in dl_layer.h) blendLightsetsFgInputs = [deluxe.Color(longname='fg_opacity')] blendLightsetsBgInputs = [deluxe.Color(longname='bg_opacity')] blendLightsetsOutputs = [] # Input and output component compound attributes children layerComponentChildren = [] # Shading component channels, build compound attributes children and utility functions parameters channels = deluxe.ComponentData.channels for channel in channels: inmsg = 'component_%s' % channel.longname if channel.array: exec 'blendLightsetsFgInputs.append(deluxe.%s(longname="fg_%s", utility=True))' % ( channel.apitype, channel.longname) exec 'blendLightsetsBgInputs.append(deluxe.%s(longname="bg_%s", utility=True))' % ( channel.apitype, channel.longname) exec 'blendLightsetsOutputs.append(deluxe.%s(longname="%s", output=True, utility=True))' % ( channel.apitype, channel.longname) exec '%s = deluxe.%s(shortname="l%s", norsl=True)' % ( inmsg, channel.type, channel.shortname) exec 'layerComponentChildren.append(%s)' % inmsg # UTILITY FUNCTIONS utilfuncs = [] for type in ['Float', 'Color']: blendBase = 'blend%ss' % type blendFunc = '%sFunc' % blendBase blendCode = '\tcolor resultColor, resultOpacity;\n' if type == 'Float': blendCode += '\tfloat premult = mix(1, luminance(i_fga), i_premult);\n' blendCode += '\tblend(i_mode, color(i_fg) * premult, i_fga, color(i_bg), i_bga, resultColor, resultOpacity);\n' blendCode += '\treturn comp(resultColor, 0);' else: blendCode += '\tcolor premult = mix(color 1, i_fga, i_premult);\n' blendCode += '\tblend(i_mode, i_fg * premult, i_fga, i_bg, i_bga, resultColor, resultOpacity);\n' blendCode += '\treturn resultColor;' exec "%s = deluxe.Function(name='%s', type='%s', inputs=[deluxe.Float(longname='mode', storage='uniform'), deluxe.Float(longname='premult'), deluxe.%s(longname='fg'), deluxe.Color(longname='fga'), deluxe.%s(longname='bg'), deluxe.Color(longname='bga')])" % ( blendFunc, blendBase, type.lower(), type, type) exec "%s.rsl = blendCode" % blendFunc exec "utilfuncs.append(%s)" % blendFunc accumBase = 'accumulate%ss' % type accumFunc = '%sFunc' % accumBase accumCode = """\ uniform float size = arraylength(i_inputs); uniform float i; %s total = 0; for(i = 0; i < size; i+= 1) { total += i_inputs[i]; } return total; """ % type.lower() exec "%s = deluxe.Function(name='%s', type='%s', inputs=[deluxe.%s(longname='inputs', array=True)])" % ( accumFunc, accumBase, type.lower(), type) exec "%s.rsl = accumCode" % accumFunc exec "utilfuncs.append(%s)" % accumFunc copyBase = 'copy%ss' % type copyFunc = '%sFunc' % copyBase copyCode = """\ uniform float isize = arraylength(i_inputs); uniform float osize = arraylength(o_outputs); uniform float i; for(i = 0; i < isize && i < osize ; i += 1) { o_outputs[i] = i_inputs[i]; } """ exec "%s = deluxe.Function(name='%s', inputs=[deluxe.%s(longname='inputs', array=True)], outputs=[deluxe.%s(longname='outputs', array=True, output=True)])" % ( copyFunc, copyBase, type, type) exec "%s.rsl = copyCode" % copyFunc exec "utilfuncs.append(%s)" % copyFunc # blendLightsetsInputs = [ deluxe.Float(longname='mode', storage='uniform'), deluxe.Float(longname='premult') ] blendLightsetsInputs.extend(blendLightsetsFgInputs) blendLightsetsInputs.extend(blendLightsetsBgInputs) blendLightsetsFunc = deluxe.Function(name='blendLightsets', inputs=blendLightsetsInputs, outputs=blendLightsetsOutputs) for channel in filter(lambda msg: msg.array, channels): blendLightsetsFunc.rsl += '\to_%s = blend%ss(i_mode, i_premult, i_fg_%s, i_fg_opacity, i_bg_%s, i_bg_opacity);\n' % ( channel.longname, channel.apitype, channel.longname, channel.longname) utilfuncs.append(blendLightsetsFunc) puzzleAuxInputs = [] puzzleDefaults = [[1, 0, 0], [0, 1, 0], [0, 0, 1]] for i in range(0, len(puzzleDefaults)): id = i + 1 baseName = 'puzzle%d' % id exec '%s = deluxe.Color(shortname="pz%d", default=%s)' % ( baseName, id, str(puzzleDefaults[i])) exec 'puzzleAuxInputs.append(%s)' % baseName calculateAuxiliariesInputs = [ deluxe.Color(longname='opacity'), deluxe.Float(longname='premult'), deluxe.Color(longname='layerOpacities', array=True), deluxe.String(longname='layerNames', array=True) ] calculateAuxiliariesInputs.extend(puzzleAuxInputs) calculateAuxiliariesFunc = deluxe.Function( name='calculateAuxiliaries', inputs=calculateAuxiliariesInputs) calculateAuxiliariesFunc.rsl = """ extern point P; extern normal N; extern vector I; extern float u, v; extern float s, t; vector In = normalize(I); normal Nn = normalize(N); color premult = mix(color 1, i_opacity, i_premult); """ auxAOVs = filter(lambda channel: channel.auxiliary, deluxe.components.channels) for aov in auxAOVs: calculateAuxiliariesFunc.rsl += '\n\textern %s %s;\n' % (aov.rsltype, aov.longname) calculateAuxiliariesFunc.rsl += '\t%s = %s;\n' % (aov.longname, aov.code) utilfuncs.append(calculateAuxiliariesFunc) # ATTRIBUTES # displayOpacity = deluxe.Color(shortname='do', norsl=True) displayColor = deluxe.Color(shortname='dc', norsl=True) # A global opacity multiplier globalOpacity = deluxe.Color(shortname='go', default=1.0, affect=False) # Global displacement scale displacementGlobalScale = deluxe.Float(shortname='dsc', default=1.0, affect=False) # Global displacement offset displacementGlobalOffset = deluxe.Float(shortname='dof', default=0.0, affect=False) # displacementCompensateScale = deluxe.Boolean(shortname='dcs', default=False, affect=False) # # displacementUseNormalMap = deluxe.Boolean(default=False, storage='uniform', # help="If on, the normal is set by an input to the normalMap parameter, typically a texture.") # # displacementNormalMap = deluxe.Color(default=0, storage='varying', # help="""If the useNormalMap parameter is on, this sets the normal. # Typically you would input a colour texture of a worldspace normal map. # """) # Arbitrary max lightset count lightSetsCount = deluxe.Integer(shortname='lsc', norsl=True, default=1, min=1, max=16, affect=False) # Layers blend order order = deluxe.IntArray(shortname='ord', affect=False, norsl=True) actualOrder = deluxe.IntArray(shortname='aord', output=True, internal=True, norsl=True) # Layer compound attribute children # Layer name, mostly used as a label but could be used to name per layer AOVs if we decide to output them layer_name = deluxe.String(shortname='lnm', utility=True, affect=False) # blendModes = [ 'Over', 'Under', 'In', 'Out', 'Atop', 'Xor', 'Cover', 'Add', 'Subtract', 'Multiply', 'Difference', 'Lighten', 'Darken', 'Saturate', 'Desaturate', 'Illuminate', 'None' ] # From blend function in blend_utils.h, Over=0, ...Illuminate=15 layer_mode = deluxe.Enum(shortname='lmde', choices=blendModes, default=blendModes[0], utility=True, affect=False) # Blend opacity layer_opacity = deluxe.Color(shortname='lo', default=1.0, utility=True, affect=False) # layer_premult = deluxe.Float(shortname='lpm', default=1.0, utility=True, affect=False, hidden=True) # layer_blendOpacity = deluxe.Boolean(shortname='lbo', default=True, utility=True, affect=False) # When turned off, no code is generated for this layer, don't use this to dynamically turn layer on and off, use layer_opacity layer_enable = deluxe.Boolean(shortname='len', default=True, norsl=True, affect=False) # Layer input components layer_components = deluxe.ComponentData(shortname='lcmp', children=layerComponentChildren, array=True, norsl=True, affect=False) # layer_displacement_name = deluxe.String(shortname='ldn', norsl=True, affect=False) layer_displacement_enable = deluxe.Boolean(shortname='lde', default=True, norsl=True, affect=False) layer_displacement_amount = deluxe.Float(shortname='lda', default=0.0, norsl=True, utility=True, affect=False) layer_displacement_scale = deluxe.Float(shortname='ldsc', default=1.0, softmin=-1, softmax=1, norsl=True, utility=True, affect=False) layer_displacement_alpha = deluxe.Float(shortname='ldal', default=1.0, min=0, max=1, norsl=True, utility=True, affect=False) layer_displacement_offset = deluxe.Float(shortname='ldo', default=0.0, softmin=-1, softmax=1, norsl=True, utility=True, affect=False) layer_displacement_type = deluxe.Enum(shortname='ldty', choices=['Bump', 'Displace'], default='Displace', utility=True, affect=False) layer_displacement_recalcNorm = deluxe.Boolean(shortname='ldrn', default=True, norsl=True, utility=True, affect=False) layer_displacement_useShadNorm = deluxe.Boolean(shortname='ldun', default=False, norsl=True, utility=True, affect=False) layer_displacement_useNormMap = deluxe.Boolean(shortname='ldum', default=False, norsl=True, utility=True, affect=False) layer_displacement_normMap = deluxe.Color(shortname='ldnm', default=False, norsl=True, utility=True, affect=False) layer_displacement_lip = deluxe.Float(shortname='ldl', min=0, max=1, default=0.0, norsl=True, utility=True, affect=False) layer_displacement_lipRim = deluxe.Float(shortname='ldls', min=0, max=1, norsl=True, utility=True, affect=False) layer_displacement_children = [ layer_displacement_name, layer_displacement_enable, layer_displacement_amount, layer_displacement_scale, layer_displacement_alpha, layer_displacement_offset, layer_displacement_type, layer_displacement_recalcNorm, layer_displacement_useShadNorm, layer_displacement_useNormMap, layer_displacement_normMap, layer_displacement_lip, layer_displacement_lipRim, ] # layer_displacements = deluxe.Compound(layer_displacement_children, shortname='lds', array=True, utility=True, affect=False) layer_displacement_mode = deluxe.Enum(shortname='ldmo', choices=['Add', 'Over'], default='Add', utility=True, affect=False) layer_displacement_layerScale = deluxe.Float(shortname='ldlc', default=1.0, utility=True, affect=False) layer_displacement_layerOffset = deluxe.Float(shortname='ldlo', default=0.0, utility=True, affect=False) layer_displacements_order = deluxe.IntArray(shortname='ldor', affect=False, norsl=True) layer_displacements_actualOrder = deluxe.IntArray(shortname='ldao', output=True, internal=True, affect=False, norsl=True) # Layers layers = deluxe.Compound([ layer_name, layer_enable, layer_mode, layer_opacity, layer_premult, layer_blendOpacity, layer_components, layer_displacement_mode, layer_displacement_layerScale, layer_displacement_layerOffset, layer_displacements, layer_displacements_order, layer_displacements_actualOrder ], array=True, utility=True, affect=False) # primaryModes = [msg.longname for msg in channels] + [aov.longname for aov in auxAOVs] # The primary display output, should always be color unless for debugging or when someone know what he's doing... primaryMode = deluxe.Enum(shortname='pmo', choices=primaryModes, default='beauty', affect=False, norsl=True) # The primary display lightset index is used for debugging, it should stay to -1 (disabled) otherwise primaryLightSetIndex = deluxe.Integer(shortname='pls', default=-1, min=-1, max=16, affect=False, norsl=True) # premultAux = deluxe.Boolean(shortname='pma', default=True) # Values of custom float AOVs customFloat = deluxe.Float(array=True, utility=True, affect=False) # Names of custom float AOVs customFloatName = deluxe.String(array=True, utility=True, affect=False) # Values of custom color AOVs customColor = deluxe.Color(default=0, array=True, utility=True, affect=False) # Names of custom color AOVs customColorName = deluxe.String(array=True, utility=True, affect=False) # collapseComponents = deluxe.Boolean(shortname='clc', hidden=True, default=False, affect=False) collapseDisplacements = deluxe.Boolean(shortname='cld', hidden=True, default=False, affect=False) # displacement = deluxe.Float(output=True, shortname='od') # Used to initialise stupid attrFieldSliderGrp to get map button! phonyFloat = deluxe.Float(hidden=True, utility=True, affect=False) @classmethod def setCodeToken(cls, key, value): cls._codetokens[key] = value @classmethod def getCode(cls, code): result = code for key in cls._codetokens.keys(): result = result.replace(key, cls._codetokens[key]) return result @classmethod def getLine(cls, code): return '%s;\n' % cls.getCode(code) @classmethod def cleanupParamName(cls, name): cleanname = '' for c in name: if c in map(chr, range(48, 58) + range(65, 91) + range(97, 123) + [95]): cleanname += c return cleanname @classmethod def getLayerId(cls, layer): return 'layers%d' % layer.logicalIndex() @classmethod def getLayerName(cls, layer): layerName = cls.cleanupParamName( layer.child(cls.layer_name.obj).asString()) if len(layerName): return layerName return cls.getLayerId(layer) @classmethod def getLayerAttr(cls, layer): return 'layers[%d]' % layer.logicalIndex() @classmethod def setLayer(cls, layer): cls.setCodeToken('LAYERID', cls.getLayerId(layer)) cls.setCodeToken('LAYERNAME', cls.getLayerName(layer)) cls.setCodeToken('LAYERATTR', cls.getLayerAttr(layer)) @classmethod def setChannel(cls, channel, lightsetindex=None): cls.setCodeToken( 'CHANNELDECLARE', channel.rsltype + ['', '[]'][channel.array != None and channel.array]) cls.setCodeToken('CHANNELAOVTYPE', channel.rsltype) cls.setCodeToken('CHANNELNAME', channel.longname) cls.setCodeToken('CHANNELLIGHTSET', channel.getLightsetSuffix(lightsetindex)) @classmethod def setVarPrefix(cls, varprefix): cls.setCodeToken('VARPREFIX', varprefix) def isSurfaceShader(self): # HUMM VERY VERY HACKY # Using this MEL global variable (from $DELIGHT/maya/scripts/DL_translateMayaToSl.mel) to know if this node is the actual shader or just an utility try: result = [] MGlobal.executeCommand('$dl_layer_bogus = $g_final_color_plug;', result) plugnode = result[0].split('.')[0] return plugnode == MFnDependencyNode(self.thisMObject()).name() except: pass return True def isDisplacementShader(self): # HUMM VERY VERY HACKY # Using this MEL global variable (from $DELIGHT/maya/scripts/DL_translateMayaToSl.mel) to know if this node is the actual shader or just an utility result = [] MGlobal.executeCommand( 'string $dl_layer_bogus_array[]; $dl_layer_bogus_array = $g_src_plugs;', result) node, attr = result[0].split('.') return attr == 'displacement' and node == MFnDependencyNode( self.thisMObject()).name() def getPlugArray(self, plug, order=[], connectedOnly=False, checkChildren=False): # get existing idxs = MIntArray() plug.getExistingArrayAttributeIndices(idxs) # try to use order to sort existing idxs sortedIdxs = [] for idx in order: if idx in idxs: sortedIdxs.append(idx) for idx in idxs: if idx not in sortedIdxs: sortedIdxs.append(idx) plugs = [] for idx in sortedIdxs: idxplug = plug.elementByLogicalIndex(idx) if connectedOnly: incommingPlugs = MPlugArray() if checkChildren: hasConnectedChild = False for i in range(0, idxplug.numChildren()): childplug = idxplug.child(i) if childplug.connectedTo(incommingPlugs, 1, 0): hasConnectedChild = True break if not hasConnectedChild: continue else: if not idxplug.connectedTo(incommingPlugs, 1, 0): continue plugs.append(idxplug) return plugs def getLayers(self, enabled=True): thisObj = self.thisMObject() order = MFnIntArrayData(MPlug(thisObj, self.order.obj).asMObject()).array() allLayers = self.getPlugArray(MPlug(thisObj, self.layers.obj), order) layers = [] for layer in allLayers: if layer.child(self.layer_enable.obj).asBool() or not enabled: layers.append(layer) return layers def getDisplacements(self, layerPlug, enabled=True): order = MFnIntArrayData( layerPlug.child( self.layer_displacements_order.obj).asMObject()).array() allDisplacements = self.getPlugArray( layerPlug.child(self.layer_displacements.obj), order) displacements = [] for displacement in allDisplacements: if displacement.child(self.layer_displacement_enable.obj).asBool( ) or not enabled: displacements.append(displacement) return displacements # def getCustoms(self, type, allCustomParams, code=False, shaderOutput=True): customStr = '' attrName = 'custom%s' % type.capitalize() if not code: customStr += '%s[] %s[]\n' % (type, attrName) idx = 0 namePlug = MPlug(self.thisMObject(), getattr(self.__class__, '%sName' % attrName).obj) for plug in self.getPlugArray(namePlug): paramName = self.cleanupParamName(plug.asString()) if len(paramName) and paramName not in allCustomParams: if code: mult = 'opacity' if type == 'float': mult = 'luminance(%s)' % mult customStr += '%s = %s[%d] * %s;\n' % (paramName, attrName, idx, mult) elif shaderOutput: customStr += 'shader_output varying %s %s\n' % (type, paramName) allCustomParams.append(paramName) idx += 1 return customStr # Override from ShadingCodeComponent def getShadingCode(self): # shadingCode = '' # Include this class file for utility functions shadingCode += '#include "%s.h"\n' % self.__class__.__name__ thisObj = self.thisMObject() # if self.isDisplacementShader(): shadingCode += """ extern point P; extern normal N; extern normal Ng; extern point __Porig; extern normal __Norig; // save P and N for use when raytracing without displacements __Porig = P; __Norig = N; normal Nn = normalize(N); normal deltaN = Nn - normalize(Ng); point Pnew = P + Nn * displacementGlobalOffset; normal Nnew = Nn; float scaleComp = 1.0; if(displacementCompensateScale){ vector v0 = vtransform("object", vector(1, 0, 0)); vector v1 = vtransform("object", vector(0, 1, 0)); vector v2 = vtransform("object", vector(0, 0, 1)); float compensate = (length(v0) + length(v1) + length(v2)) / 3; if(compensate) scaleComp = scaleComp / compensate; } float amount = 0; """ layers = self.getLayers() for layer in reversed(layers): substractOverLayers = '' for toplayer in layers[layer.logicalIndex() + 1:]: if toplayer.child( self.layer_displacement_mode.obj).asShort() == 1: self.setLayer(toplayer) substractOverLayers += self.getCode(' - LAYERID_alpha') self.setLayer(layer) shadingCode += self.getLine( 'float LAYERID_alpha = clamp(luminance(LAYERID_layer_opacity)%s, 0, 1)' % (substractOverLayers)) for layer in layers: self.setLayer(layer) for displacement in self.getDisplacements(layer): varbase = 'LAYERID_layer_displacements%i_layer_displacement' % displacement.logicalIndex( ) shadingCode += self.getLine( 'amount = getLip(%s_lip, %s_lipRim, %s_amount)' % (varbase, varbase, varbase)) shadingCode += self.getLine( 'amount = (amount * scaleComp * %s_scale * LAYERID_layer_displacement_layerScale * displacementGlobalScale + ((%s_offset + LAYERID_layer_displacement_layerOffset) * scaleComp)) * LAYERID_alpha * clamp(%s_alpha, 0, 1)' % (varbase, varbase, varbase)) if displacement.child( self.layer_displacement_useNormMap.obj).asShort(): shadingCode += self.getLine( 'Nnew += ntransform("object", "current", normal(%s_normMap))' % (varbase)) shadingCode += self.getLine( 'getDisplacement(amount, %s_type, %s_recalcNorm, %s_useShadNorm, Pnew, normalize(Nnew), deltaN, Pnew, Nnew)' % (varbase, varbase, varbase)) shadingCode += """ P = Pnew; N = Nnew; """ else: # shadingCode += self.getLine('color resultColor, resultOpacity') # Add one cause lightset arrays are actually one based since index 0 is reserved for default lightset i.e. no lightset lightSetsCount = MPlug(thisObj, self.lightSetsCount.obj).asInt() if lightSetsCount < 1: lightSetsCount = 1 # If this node is used as an actual shader we need the AOVs isSurfaceShader = self.isSurfaceShader() if isSurfaceShader: self.setVarPrefix('') else: # If not we declare local vars self.setVarPrefix('local_') shadingCode += self.getLine('color VARPREFIXopacity = 0') for channel in self.channels: self.setChannel(channel) if channel.array: for i in range(0, lightSetsCount): self.setChannel(channel, i) shadingCode += self.getLine( 'color VARPREFIXCHANNELNAMECHANNELLIGHTSET = 0' ) else: shadingCode += self.getLine( 'color VARPREFIXCHANNELNAME = 0') # Loop into enabled layers for layer in self.getLayers(): # Get all connected components to this layer components = self.getPlugArray(layer.child( self.layer_components.obj), connectedOnly=True) self.setLayer(layer) # Mult layer opacity shadingCode += self.getLine( 'color LAYERNAME_opacity = LAYERID_layer_opacity') if not len(components): continue # Blend opacity if layer.child(self.layer_blendOpacity.obj).asBool(): shadingCode += self.getLine( 'blend(LAYERID_layer_mode, 1, LAYERNAME_opacity, 1, VARPREFIXopacity, resultColor, VARPREFIXopacity)' ) # for channel in filter(lambda msg: not msg.array, self.channels): self.setChannel(channel) componentList = [ 'LAYERID_layer_components%d_component_CHANNELNAME' % (comp.logicalIndex()) for comp in components ] shadingCode += self.getLine( 'VARPREFIXCHANNELNAME = blend%ss(LAYERID_layer_mode, LAYERID_layer_premult, %s, LAYERNAME_opacity, VARPREFIXCHANNELNAME, VARPREFIXopacity)' % (channel.apitype, string.join(componentList, ' + '))) # Blend all lightsets separatly for i in range(0, lightSetsCount): # Build blendLightsets parameter list blendFgInputs = [self.getCode('LAYERNAME_opacity')] for channel in filter(lambda msg: msg.array, self.channels): self.setChannel(channel) # Add up all components componentList = [ 'LAYERID_layer_components%d_component_CHANNELNAME[%d]' % (comp.logicalIndex(), i) for comp in components ] blendFgInputs.append( self.getCode(string.join(componentList, ' + '))) blendBgInputs = [self.getCode('VARPREFIXopacity')] blendOutputs = [] for channel in filter(lambda msg: msg.array, self.channels): self.setChannel(channel, i) blendBgInputs.append( self.getCode( 'VARPREFIXCHANNELNAMECHANNELLIGHTSET')) blendOutputs.append( self.getCode( 'VARPREFIXCHANNELNAMECHANNELLIGHTSET')) # blendParams = [ self.getCode('LAYERID_layer_mode'), self.getCode('LAYERID_layer_premult') ] + blendFgInputs + blendBgInputs + blendOutputs shadingCode += 'blendLightsets(\n\t%s);\n' % string.join( blendParams, ',\n\t') # shadingCode += self.getLine('VARPREFIXopacity *= globalOpacity') # Add (or substract) all channels to out color per light set for channel in self.channels: self.setChannel(channel) if channel.array: accum_lightsets = [] for i in range(0, lightSetsCount): self.setChannel(channel, i) shadingCode += self.getLine( 'VARPREFIXCHANNELNAMECHANNELLIGHTSET *= globalOpacity' ) accum_lightsets.append( self.getCode( 'VARPREFIXCHANNELNAMECHANNELLIGHTSET')) shadingCode += self.getLine( 'color CHANNELNAME_lightsets[] = {%s}' % string.join(accum_lightsets, ', ')) if isSurfaceShader: shadingCode += self.getLine( 'VARPREFIXCHANNELNAME = accumulateColors(CHANNELNAME_lightsets)' ) else: shadingCode += self.getLine( 'copyColors(CHANNELNAME_lightsets, outputComponent_output_CHANNELNAME)' ) else: shadingCode += self.getLine( 'VARPREFIXCHANNELNAME *= globalOpacity') if not isSurfaceShader: shadingCode += self.getLine( 'outputComponent_output_CHANNELNAME = local_CHANNELNAME' ) if isSurfaceShader: layernames = [] layeropacs = [] for layer in self.getLayers(): self.setLayer(layer) layernames.append(self.getCode('LAYERNAME')) layeropacs.append(self.getCode('LAYERNAME_opacity')) puzzleParamStr = string.join( [p.longname for p in self.puzzleAuxInputs], ', ') shadingCode += self.getLine('color layerOpacities[] = {%s}' % string.join(layeropacs, ',')) shadingCode += self.getLine('string layerNames[] = {"%s"}' % string.join(layernames, '", "')) shadingCode += self.getLine( 'calculateAuxiliaries(opacity, premultAux, layerOpacities, layerNames, %s)' % puzzleParamStr) allCustomParams = [] shadingCode += self.getCustoms('float', allCustomParams, code=True) shadingCode += self.getCustoms('color', allCustomParams, code=True) # primaryModeIdx = MPlug(thisObj, self.primaryMode.obj).asShort() primaryMode = self.primaryModes[primaryModeIdx] primaryLightSetIndex = MPlug( thisObj, self.primaryLightSetIndex.obj).asInt() if primaryLightSetIndex >= 0 and primaryMode not in [ obj.longname for obj in self.auxAOVs ]: primaryMode += '_ls%d' % primaryLightSetIndex shadingCode += self.getLine('outColor = VARPREFIX%s' % primaryMode) shadingCode += self.getLine( 'outTransparency = 1 - VARPREFIXopacity') return shadingCode # Override from ShadingCodeComponent def getShadingParameters(self): shadingParameters = '' thisObj = self.thisMObject() lightSetsCount = MPlug(thisObj, self.lightSetsCount.obj).asInt() if lightSetsCount < 1: lightSetsCount = 1 isSurfaceShader = self.isSurfaceShader() isDisplacementShader = self.isDisplacementShader() # if isDisplacementShader: for attr in self.getShadingParametersAttributes(): if not attr.output and attr.longname.startswith( 'displacement'): shadingParameters += '%s %s\n' % (attr.rsltype, attr.longname) else: shadingParameters += super(dl_layer, self).getShadingParameters() # for layer in self.getLayers(): self.setLayer(layer) shadingParameters += self.getCode( 'color LAYERATTR.layer_opacity\n') if isDisplacementShader: shadingParameters += self.getCode( 'float LAYERATTR.layer_displacement_layerScale\n') shadingParameters += self.getCode( 'float LAYERATTR.layer_displacement_layerOffset\n') else: shadingParameters += self.getCode( 'uniform float LAYERATTR.layer_mode\n') if isDisplacementShader: for displacement in self.getDisplacements(layer): displacementIndex = displacement.logicalIndex() for child in self.layer_displacement_children: if child.utility: shadingParameters += self.getCode( '%s LAYERATTR.layer_displacements[%d].%s\n' % (child.rsltype, displacementIndex, child.longname)) else: shadingParameters += self.getCode( 'float LAYERATTR.layer_premult\n') for component in self.getPlugArray(layer.child( self.layer_components.obj), connectedOnly=True): componentIndex = component.logicalIndex() shadingParameters += self.getCode( 'void%d LAYERATTR.layer_components[%d]\n' % (lightSetsCount, componentIndex)) for channel in self.channels: self.setChannel(channel) shadingParameters += self.getCode( 'CHANNELDECLARE LAYERATTR.layer_components[%d].component_CHANNELNAME\n' % componentIndex) if isSurfaceShader: shadingParameters += self.getCode( 'shader_output varying color opacity\n') for channel in self.channels: self.setChannel(channel) shadingParameters += self.getCode( 'shader_output varying CHANNELAOVTYPE CHANNELNAME\n') if channel.array: for i in range(0, lightSetsCount): self.setChannel(channel, i) shadingParameters += self.getCode( 'shader_output varying CHANNELAOVTYPE CHANNELNAMECHANNELLIGHTSET\n' ) for auxAOV in self.auxAOVs: shadingParameters += self.getCode( 'shader_output varying %s %s\n' % (auxAOV.rsltype, auxAOV.longname)) if isDisplacementShader: shadingParameters += 'shader_output varying point __Porig\n' shadingParameters += 'shader_output varying normal __Norig\n' # if not isDisplacementShader: allCustomParams = [] shadingParameters += self.getCustoms('float', allCustomParams, shaderOutput=isSurfaceShader) shadingParameters += self.getCustoms('color', allCustomParams, shaderOutput=isSurfaceShader) return shadingParameters def getInternalValueInContext(self, plug, dataHandle, ctx): if plug.attribute() == self.__class__.actualOrder.obj: layers = self.getLayers(enabled=False) order = MIntArray() for layer in layers: order.append(layer.logicalIndex()) dataHandle.setMObject(MFnIntArrayData().create(order)) return True elif plug.attribute( ) == self.__class__.layer_displacements_actualOrder.obj: displacements = self.getDisplacements(plug.parent(), enabled=False) order = MIntArray() for displacement in displacements: order.append(displacement.logicalIndex()) dataHandle.setMObject(MFnIntArrayData().create(order)) return True return super(dl_layer, self).getInternalValueInContext(plug, dataHandle, ctx) def compute(self, plug, data): if plug == self.outColor.obj: r, g, b = data.inputValue(self.displayColor.obj).asFloat3() data.outputValue(plug).set3Float(r, g, b) return data.setClean(plug) elif plug == self.outTransparency.obj: r, g, b = data.inputValue(self.displayOpacity.obj).asFloat3() data.outputValue(plug).set3Float(1.0 - r, 1.0 - g, 1.0 - b) return data.setClean(plug) return super(dl_layer, self).compute(plug, data) def postConstructor(self): # We always have at least one layer # TODO: maybe make this less systematic layerPlug = MPlug(self.thisMObject(), self.layers.obj) layer0Plug = layerPlug.elementByLogicalIndex(0) layerNamePlug = layer0Plug.child(self.layer_name.obj) layerNamePlug.setMObject(MFnStringData().create('layer0')) super(dl_layer, self).postConstructor() template = 'source dl_layer'