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_pointCloudLightShape(deluxe.LightBase): typeid = 0x29f5d0a0 description = "Point cloud control light." enable = deluxe.Boolean(default=True) enableAmbientOcclusion = deluxe.Boolean(default=True) enableColorBleeding = deluxe.Boolean(default=True, ) enableReflection = deluxe.Boolean(default=True, shortname='erfl') enableReflectionOcclusion = deluxe.Boolean(default=True) enableRefraction = deluxe.Boolean( default=True, shortname='erfr', ) enableSubsurface = deluxe.Boolean(default=True, shortname='ess') ptcFile = deluxe.File(label="Point Cloud File") # __enableAmbientOcclusion = deluxe.Boolean(default=False, output=True, message=True, messagetype='lightsource') __enableColorBleeding = deluxe.Boolean(default=False, output=True, message=True, messagetype='lightsource') __enableReflection = deluxe.Boolean(default=False, output=True, message=True, messagetype='lightsource') __enableReflectionOcclusion = deluxe.Boolean(default=False, output=True, message=True, messagetype='lightsource') __enableRefraction = deluxe.Boolean(default=False, output=True, message=True, messagetype='lightsource') __enableSubsurface = deluxe.Boolean(default=False, output=True, message=True, messagetype='lightsource') __ptcFile = deluxe.String(output=True, message=True, messagetype='lightsource') # category __category = deluxe.String(default='pointcloud', message=True, messagetype='lightsource') _3delight_light_category = deluxe.String(shortname='cat', default='pointcloud', notemplate=True, norsl=True) rsl = \ """
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_projectionCollector(deluxe.Utility): typeid = 0x00370003 classification = 'utility/color' description = "Wrapper around 3Delight \"texture\" function" baseColor = deluxe.Color( default=0, help="Color before projected textures are applied.") baseAlpha = deluxe.Float( default=0, help="Alpha before projected textures are applied.") projLightSubset = deluxe.String(default="", help=""" Receive projections only from projectionLights with matching projLightSubset values. They are evaluated in alphabetical order. """) outColor = deluxe.Color(shortname="oc", output=True) outAlpha = deluxe.Float(shortname="al", output=True) rsl = """
class dl_displacement(deluxe.Displacement): typeid = 0x00320000 includes = ["displacement_utils.h"] globalScale = deluxe.Float(min=0, max=1, default=1, storage='uniform') globalOffset = deluxe.Float(softmin=-1, softmax=1, default=0, storage='uniform') useShadingNormals = deluxe.Boolean( default=False, help="""When a displacement map is used, this shader calls calculatenormal(). This causes polygonal data to appear faceted. This parameter causes the original shading normal offset to be added to the calculated normal, generally re-smoothing polygonal data.""" ) useNormalMap = deluxe.Boolean( default=False, storage='uniform', help= "If on, the normal is set by an input to the normalMap parameter, typically a texture." ) normalMap = 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. """) # per input parameters name = deluxe.String(default="input", help="Name of this displacement layer.", norsl=True) enable = deluxe.Boolean(default=True, help="Enable/disable this layer of displacement.") alpha = deluxe.Float(shortname="alpha", default=1, min=0, max=1, help="Alpha for this layer of displacement.") scale = deluxe.Float(default=1, softmin=-1, softmax=1, help="Scale this layer of displacement.") offset = deluxe.Float(default=0, softmin=-1, softmax=1, help="Offset this layer of displacement.") bumpOrDisplace = deluxe.Float( default=1, min=0, max=1, help="Only modifies the normal if 0, displaces at 1, blends between.") recalculateNormal = deluxe.Float( default=1, min=0, max=1, help="Recalculates the normal if 1, does not if 0, blends between.") amount = deluxe.Float(min=0, max=1, help="Plug utility nodes in here to displace.") lip = deluxe.Float(shortname="lip", min=0, max=1, help="it's a lip.") lipRimSharp = deluxe.Float(shortname="liprs", min=0, max=1, help="it's a lip.") inputs = deluxe.Compound([ name, enable, alpha, scale, offset, bumpOrDisplace, recalculateNormal, amount, lip, lipRimSharp ], array=True) selectedInput = deluxe.Integer(hidden=True) # notes: # need # - some kind of list representation for displacement layers # - way to add and remove layers # - way to move layers up and down # - per-input parameters must be connected to array attributes when a layer is selected template = \ r""" eval("source \"dl_dgLib.mel\";"); proc rebuildList(string $inputs) { textScrollList -edit -deselectAll inputsList; textScrollList -edit -removeAll -deselectAll inputsList; int $ix[] = dl_dgPlugArrayGetIndices($inputs); int $i; for ($i in $ix) { textScrollList -edit -append `getAttr ($inputs +"[" + $i + "].name")` inputsList; } } proc addNewInput(string $inputs) { int $new_index = dl_dgPlugArrayAddNew($inputs); string $plugName = $inputs + "[" + $new_index + "]"; setAttr -type "string" ($plugName + ".name") ("input" + ($new_index +1) ); if ($new_index>0) { int $i= getSelectedIndex($inputs); rebuildList($inputs); setSelectedIndex($inputs,$i); } } proc int getSelectedScrollIndex(string $inputs) { int $selectedScrollIndexArray[] = `textScrollList -query -selectIndexedItem inputsList`; return $selectedScrollIndexArray[0]; } proc setSelectedScrollIndex(string $inputs,int $index) { textScrollList -edit -selectIndexedItem $index inputsList; selectInput ($inputs); } proc int getSelectedIndex(string $inputs) { int $indexList[] = dl_dgPlugArrayGetIndices($inputs); int $selectedScrollIndex = getSelectedScrollIndex($inputs); if (!$selectedScrollIndex) { return -1; } $selectedScrollIndex--; return $indexList[$selectedScrollIndex]; } proc setSelectedIndex(string $inputs,int $index ) { int $scrollIndex = 1; int $indexList[] = dl_dgPlugArrayGetIndices($inputs); int $i; for ($i in $indexList) { if ($index == $i) { break; } else { $scrollIndex++; } } setSelectedScrollIndex($inputs,$scrollIndex); } proc deleteSelectedInput(string $inputs) { if (size(dl_dgPlugArrayGetIndices($inputs)) > 1) { int $i= getSelectedIndex($inputs); textScrollList -edit -deselectAll inputsList; if ($i>=0) { removeMultiInstance -b true ($inputs+"["+$i+"]"); rebuildList($inputs); } } } proc moveUp(string $inputs) { int $i= getSelectedIndex($inputs); if ($i>=0) { int $ix =dl_dgPlugArraySwapWithPrev($inputs,$i); rebuildList($inputs); setSelectedIndex($inputs,$ix); } } proc moveDown(string $inputs) { int $i= getSelectedIndex($inputs); if ($i>=0) { int $ix = dl_dgPlugArraySwapWithNext($inputs,$i); rebuildList($inputs); setSelectedIndex($inputs,$ix); } } proc selectInput (string $inputs) { int $i= getSelectedIndex($inputs); if ($i<0) { return; } AEreplaceString nameGrp ($inputs+"["+$i+"].name") ""; attrFieldSliderGrp -e -at ($inputs+"["+$i+"].alpha") alphaGrp; attrFieldSliderGrp -e -at ($inputs+"["+$i+"].scale") scaleGrp; attrFieldSliderGrp -e -at ($inputs+"["+$i+"].offset") offsetGrp; attrFieldSliderGrp -e -attribute ($inputs+"["+$i+"].bumpOrDisplace") bumpOrdisplaceGrp; attrFieldSliderGrp -e -at ($inputs+"["+$i+"].recalculateNormal") recalculateNormalGrp; attrFieldSliderGrp -e -at ($inputs+"["+$i+"].amount") amountGrp; attrFieldSliderGrp -e -at ($inputs+"["+$i+"].lip") lipGrp; attrFieldSliderGrp -e -at ($inputs+"["+$i+"].lipRimSharp") lipRimSharpGrp; } global proc AEdl_displacement_inputs_New(string $inputs) { if (!size(dl_dgPlugArrayGetIndices($inputs))) { addNewInput($inputs); } columnLayout -adj true -cal "center"; rowLayout -nc 2 -adj 1 -cw 2 80; textScrollList -sc ("selectInput \""+ $inputs + "\"") -height 150 inputsList; rebuildList($inputs); textScrollList -e -selectIndexedItem 1 inputsList; columnLayout -cal "center" ; button -label " up " -command ("moveUp \""+ $inputs + "\"") upBtn; button -label "down" -command ("moveDown \""+ $inputs + "\"") downBtn; setParent..; setParent..; button -label "Add new input" -command ("addNewInput \""+ $inputs + "\"") addBtn; button -label "Delete selected input" -command ("deleteSelectedInput \""+ $inputs + "\"") delBtn; textFieldGrp -label "Name" -cc ("rebuildList " + $inputs) nameGrp; connectControl -index 2 nameGrp ($inputs+"[0].name"); attrFieldSliderGrp -label "Alpha" -attribute ($inputs+"[0].alpha") -hideMapButton false alphaGrp; attrFieldSliderGrp -label "Scale" -attribute ($inputs+"[0].scale") -hideMapButton false scaleGrp; attrFieldSliderGrp -label "Offset" -attribute ($inputs+"[0].offset") -hideMapButton false offsetGrp; attrFieldSliderGrp -label "Bump or Displace" -attribute ($inputs+"[0].bumpOrDisplace") -hideMapButton false bumpOrdisplaceGrp; attrFieldSliderGrp -label "Recalculate Normal" -attribute ($inputs+"[0].recalculateNormal") -hideMapButton false recalculateNormalGrp; attrFieldSliderGrp -label "Amount" -attribute ($inputs+"[0].amount") -hideMapButton false amountGrp; attrFieldSliderGrp -label "Lip" -attribute ($inputs+"[0].lip") -hideMapButton false lipGrp; attrFieldSliderGrp -label "LipRimSharp" -attribute ($inputs+"[0].lipRimSharp") -hideMapButton false lipRimSharpGrp; setParent..; } global proc AEdl_displacement_inputs_Replace(string $inputs) { int $selectedIndex = getSelectedIndex($inputs); int $indexList[] = dl_dgPlugArrayGetIndices($inputs); if (!size($indexList)) { addNewInput($inputs); } rebuildList($inputs); textScrollList -e -sc ("selectInput \""+ $inputs + "\"") inputsList; button -e -command ("moveUp \""+ $inputs + "\"") upBtn; button -e -command ("moveDown \""+ $inputs + "\"") downBtn; button -e -command ("addNewInput \""+ $inputs + "\"") addBtn; button -e -command ("deleteSelectedInput \""+ $inputs + "\"") delBtn; textFieldGrp -e -cc ("rebuildList " + $inputs) nameGrp; int $i; if ($selectedIndex>=0) { $i = $selectedIndex; } else { $i = $indexList[0]; } setSelectedIndex($inputs,$i); connectControl -index 2 nameGrp ($inputs+"["+$i+"].name"); attrFieldSliderGrp -e -attribute ($inputs+"["+$i+"].alpha") alphaGrp; attrFieldSliderGrp -e -attribute ($inputs+"["+$i+"].scale") scaleGrp; attrFieldSliderGrp -e -attribute ($inputs+"["+$i+"].offset") offsetGrp; attrFieldSliderGrp -e -attribute ($inputs+"["+$i+"].bumpOrDisplace") bumpOrdisplaceGrp; attrFieldSliderGrp -e -attribute ($inputs+"["+$i+"].recalculateNormal") recalculateNormalGrp; attrFieldSliderGrp -e -attribute ($inputs+"["+$i+"].amount") amountGrp; attrFieldSliderGrp -e -attribute ($inputs+"["+$i+"].lip") lipGrp; attrFieldSliderGrp -e -attribute ($inputs+"["+$i+"].lipRimSharp") lipRimSharpGrp; } global proc AEdl_displacementTemplate(string $node) { AEswatchDisplay $node; editorTemplate -beginScrollLayout; editorTemplate -beginLayout "Displacement Attributes" -collapse 0; editorTemplate -addControl "globalScale"; editorTemplate -addControl "globalOffset"; editorTemplate -addControl "useShadingNormals"; editorTemplate -addControl "useNormalMap"; editorTemplate -addControl "normalMap"; editorTemplate -beginLayout "Inputs" -collapse 0; editorTemplate -callCustom "AEdl_displacement_inputs_New" "AEdl_displacement_inputs_Replace" "inputs"; editorTemplate -endLayout; editorTemplate -endLayout; // include/call base class/node attributes AEdependNodeTemplate $node; editorTemplate -addExtraControls; editorTemplate -endScrollLayout; } """ rsl = \ r"""
class dl_bakeLightShape(deluxe.Light): typeid = 0x00310004 description = "Light that bakes geometry to point clouds." includes = ['utils.h'] # # deluxe.Light.intensity.hidden = True # deluxe.Light.lightColor.hidden = True ptcFile = deluxe.File( default='default.ptc', label='Point Cloud File', help="""The point cloud file in which to bake geometry.""") ptcFileNoSelfOcclude = deluxe.File( default='default.ptc', label='Point Cloud (No Self) File', hidden=True, help="""The point cloud file in which to bake objects THAT DON'T OCCLUDE THEMSELVES OR EACH OTHER ( Attribute "user" "float selfOcclude" [ 0 ] ), eg groundplane.""" ) coordSys = deluxe.CoordinateSystem( default='world', label='Coordinate System', help= """The coordinate system in which points will be stored in the ptc file. Default is "world".""" ) radiusScale = deluxe.Float(shortname='rsc', default=1, softmax=3, help="Scale radius of baked points.") bakeRadiosity = deluxe.Boolean( default=False, help="""Bake radiosity at each point. Turn this on if you are doing point-based indirect lighting (color bleeding).""" ) bakeRadiosityVariable = deluxe.String( default="Ci", help= """If bakeRadiosity is on, this is the variable that is baked from surface shaders. To avoid baking camera-dependent channels such as specular and reflection, you can bake just diffuse illumination by entering 'aov_diffuse'. The aov_diffuse AOV must be enabled for this to work.""" ) bakeRaytracing = deluxe.Boolean( shortname='brt', default=False, help="""Bake raytrace points (bug-prone).""") opacityThreshold = deluxe.Float( shortname='oth', default=-1, help="Points with opacity lower than this value will not be baked.") useBoundingBoxes = deluxe.Boolean(shortname='usebbx', default=False, help="Use bounding boxes") boundBox1enable = deluxe.Boolean(shortname='bbxe1', default=False, help="Use bounding box 1") boundBox1min = deluxe.Point(shortname='bbxmn1', help="xyz minimum for bounding box 1.") boundBox1max = deluxe.Point(shortname='bbxmx1', help="xyz maximum for bounding box 1.") boundBox1buffer = deluxe.Float( shortname='bbxbf1', softmax=10, help="How much extra space to add to each side of bounding box 1.") boundBox2enable = deluxe.Boolean(shortname='bbxe2', default=False, help="Use bounding box 2") boundBox2min = deluxe.Point(shortname='bbxmn2', help="xyz minimum for bounding box 2.") boundBox2max = deluxe.Point(shortname='bbxmx2', help="xyz maximum for bounding box 2.") boundBox2buffer = deluxe.Float( shortname='bbxbf2', softmax=10, help="How much extra space to add to each side of bounding box 2.") boundBox3enable = deluxe.Boolean(shortname='bbxe3', default=False, help="Use bounding box 3") boundBox3min = deluxe.Point(shortname='bbxmn3', help="xyz minimum for bounding box 3.") boundBox3max = deluxe.Point(shortname='bbxmx3', help="xyz maximum for bounding box 3.") boundBox3buffer = deluxe.Float( shortname='bbxbf3', softmax=10, help="How much extra space to add to each side of bounding box 3.") boundBox4enable = deluxe.Boolean(shortname='bbxe4', default=False, help="Use bounding box 4") boundBox4min = deluxe.Point(shortname='bbxmn4', help="xyz minimum for bounding box 4.") boundBox4max = deluxe.Point(shortname='bbxmx4', help="xyz maximum for bounding box 4.") boundBox4buffer = deluxe.Float( shortname='bbxbf4', softmax=10, help="How much extra space to add to each side of bounding box 4.") boundBox5enable = deluxe.Boolean(shortname='bbxe5', default=False, help="Use bounding box 5") boundBox5min = deluxe.Point(shortname='bbxmn5', help="xyz minimum for bounding box 5.") boundBox5max = deluxe.Point(shortname='bbxmx5', help="xyz maximum for bounding box 5.") boundBox5buffer = deluxe.Float( shortname='bbxbf5', softmax=10, help="How much extra space to add to each side of bounding box 5.") boundingBoxes = deluxe.Group([ useBoundingBoxes, boundBox1enable, boundBox1min, boundBox1max, boundBox1buffer, boundBox2enable, boundBox2min, boundBox2max, boundBox2buffer, boundBox3enable, boundBox3min, boundBox3max, boundBox3buffer, boundBox4enable, boundBox4min, boundBox4max, boundBox4buffer, boundBox5enable, boundBox5min, boundBox5max, boundBox5buffer ]) do_bake = deluxe.Boolean(default=True, message=True, messagetype='lightsource') # category __category = deluxe.String(default='bakelight', message=True, messagetype='lightsource') _3delight_light_category = deluxe.String(default='bakelight', notemplate=True, norsl=True) 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_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_externString(deluxe.Extern): typeid = 0x00300032 inputValue = deluxe.String() outputValue = deluxe.String(output=True)
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_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'
class dl_attributeString(deluxe.AttributeNode): typeid = 0x0c30c269 description = "Generic string attribute." inputValue = deluxe.String() outputValue = deluxe.String(output=True)