12 import maya.api.OpenMaya 
as om
 
   13 import maya.api.OpenMayaRender 
as omr
 
   25     The presence of this function tells Maya that the plugin produces, and 
   26     expects to be passed, objects created using the Maya Python API 2.0. 
   33 class depthShader(om.MPxNode):
 
   35     id = om.MTypeId( 0x81002 )
 
   53         nAttr = om.MFnNumericAttribute()
 
   57         depthShader.aColorNear = nAttr.createColor(
"color", 
"c")
 
   62         nAttr.default = (0.0, 1.0, 0.0)         
 
   65         depthShader.aColorFar = nAttr.createColor(
"colorFar", 
"cf")
 
   70         nAttr.default = (0.0, 0.0, 1.0)         
 
   72         depthShader.aNear = nAttr.create(
"near", 
"n", om.MFnNumericData.kFloat)
 
   78         nAttr.setSoftMax(1000.0)
 
   80         depthShader.aFar = nAttr.create(
"far", 
"f", om.MFnNumericData.kFloat)
 
   86         nAttr.setSoftMax(1000.0)
 
   89         depthShader.aPointCamera = nAttr.createPoint(
"pointCamera", 
"p")
 
   97         depthShader.aOutColor = nAttr.createColor(
"outColor", 
"oc")
 
   99         nAttr.storable = 
False 
  100         nAttr.readable = 
True 
  101         nAttr.writable = 
False 
  103         om.MPxNode.addAttribute(depthShader.aColorNear)
 
  104         om.MPxNode.addAttribute(depthShader.aColorFar)
 
  105         om.MPxNode.addAttribute(depthShader.aNear)
 
  106         om.MPxNode.addAttribute(depthShader.aFar)
 
  107         om.MPxNode.addAttribute(depthShader.aPointCamera)
 
  108         om.MPxNode.addAttribute(depthShader.aOutColor)
 
  110         om.MPxNode.attributeAffects(depthShader.aColorNear, depthShader.aOutColor)
 
  111         om.MPxNode.attributeAffects(depthShader.aColorFar, depthShader.aOutColor)
 
  112         om.MPxNode.attributeAffects(depthShader.aNear, depthShader.aOutColor)
 
  113         om.MPxNode.attributeAffects(depthShader.aFar, depthShader.aOutColor)
 
  114         om.MPxNode.attributeAffects(depthShader.aPointCamera, depthShader.aOutColor)
 
  117         om.MPxNode.__init__(self)
 
  119     def compute(self, plug, block):
 
  121         if (plug != depthShader.aOutColor) 
and (plug.parent() != depthShader.aOutColor):
 
  125         pCamera   = block.inputValue(depthShader.aPointCamera).asFloatVector()
 
  126         cNear     = block.inputValue(depthShader.aColorNear).asFloatVector()
 
  127         cFar      = block.inputValue(depthShader.aColorFar).asFloatVector()
 
  128         nearClip  = block.inputValue(depthShader.aNear).asFloat()
 
  129         farClip   = block.inputValue(depthShader.aFar).asFloat()
 
  133         dist = farClip - nearClip
 
  135             ratio = (farClip + pCamera.z) / dist
 
  136         resultColor = cNear * ratio + cFar*(1.0 - ratio)
 
  139         outColorHandle = block.outputValue( depthShader.aOutColor )
 
  140         outColorHandle.setMFloatVector( resultColor )
 
  141         outColorHandle.setClean()
 
  143     def postConstructor(self):
 
  149 class depthShaderOverride(omr.MPxSurfaceShadingNodeOverride):
 
  152         return depthShaderOverride(obj)
 
  154     def __init__(self, obj):
 
  155         omr.MPxSurfaceShadingNodeOverride.__init__(self, obj)
 
  158         fragmentMgr = omr.MRenderer.getFragmentManager()
 
  159         if fragmentMgr != 
None:
 
  160             if not fragmentMgr.hasFragment(
"depthShaderPluginFragment"):
 
  161                 fragmentBody  = textwrap.dedent(
""" 
  162                     <fragment uiName=\"depthShaderPluginFragment\" name=\"depthShaderPluginFragment\" type=\"plumbing\" class=\"ShadeFragment\" version=\"1.0\"> 
  163                         <description><![CDATA[Depth shader fragment]]></description> 
  165                             <float name=\"depthValue\" /> 
  166                             <float3 name=\"color\" /> 
  167                             <float3 name=\"colorFar\" /> 
  168                             <float name=\"near\" /> 
  169                             <float name=\"far\" /> 
  172                             <float name=\"depthValue\" value=\"0.0\" /> 
  173                             <float3 name=\"color\" value=\"0.0,1.0,0.0\" /> 
  174                             <float3 name=\"colorFar\" value=\"0.0,0.0,1.0\" /> 
  175                             <float name=\"near\" value=\"0.0\" /> 
  176                             <float name=\"far\" value=\"2.0\" /> 
  179                             <float3 name=\"outColor\" /> 
  182                             <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.1\"> 
  183                                 <function_name val=\"depthShaderPluginFragment\" /> 
  185                                     float3 depthShaderPluginFragment(float depthValue, float3 cNear, float3 cFar, float nearClip, float farClip) \n 
  187                                         float ratio = (farClip + depthValue)/(farClip - nearClip); \n 
  188                                         return cNear*ratio + cFar*(1.0f - ratio); \n 
  192                             <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.0\"> 
  193                                 <function_name val=\"depthShaderPluginFragment\" /> 
  195                                     float3 depthShaderPluginFragment(float depthValue, float3 cNear, float3 cFar, float nearClip, float farClip) \n 
  197                                         float ratio = (farClip + depthValue)/(farClip - nearClip); \n 
  198                                         return cNear*ratio + cFar*(1.0f - ratio); \n 
  202                             <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\"> 
  203                                 <function_name val=\"depthShaderPluginFragment\" /> 
  205                                     vec3 depthShaderPluginFragment(float depthValue, vec3 cNear, vec3 cFar, float nearClip, float farClip) \n 
  207                                         float ratio = (farClip + depthValue)/(farClip - nearClip); \n 
  208                                         return cNear*ratio + cFar*(1.0f - ratio); \n 
  215                 fragmentMgr.addShadeFragmentFromBuffer(fragmentBody, 
False)
 
  217             if not fragmentMgr.hasFragment(
"depthShaderPluginInterpolantFragment"):
 
  218                 vertexFragmentBody  = textwrap.dedent(
""" 
  219                     <fragment uiName=\"depthShaderPluginInterpolantFragment\" name=\"depthShaderPluginInterpolantFragment\" type=\"interpolant\" class=\"ShadeFragment\" version=\"1.0\"> 
  220                         <description><![CDATA[Depth shader vertex fragment]]></description> 
  222                             <float3 name=\"Pm\" semantic=\"Pm\" flags=\"varyingInputParam\" /> 
  223                             <float4x4 name=\"worldViewProj\" semantic=\"worldviewprojection\" /> 
  228                             <float name=\"outDepthValue\" ^1s/> 
  231                             <implementation render=\"OGSRenderer\" language=\"Cg\" lang_version=\"2.1\"> 
  232                                 <function_name val=\"depthShaderPluginInterpolantFragment\" /> 
  234                                     float depthShaderPluginInterpolantFragment(float depthValue) \n 
  236                                         return depthValue; \n 
  239                                 <vertex_source><![CDATA[ 
  240                                     float idepthShaderPluginInterpolantFragment(float3 Pm, float4x4 worldViewProj) \n 
  242                                         float4 pCamera = mul(worldViewProj, float4(Pm, 1.0f)); \n 
  243                                         return (pCamera.z - pCamera.w*2.0f); \n 
  247                             <implementation render=\"OGSRenderer\" language=\"HLSL\" lang_version=\"11.0\"> 
  248                                 <function_name val=\"depthShaderPluginInterpolantFragment\" /> 
  250                                     float depthShaderPluginInterpolantFragment(float depthValue) \n 
  252                                         return depthValue; \n 
  255                                 <vertex_source><![CDATA[ 
  256                                     float idepthShaderPluginInterpolantFragment(float3 Pm, float4x4 worldViewProj) \n 
  258                                         float4 pCamera = mul(float4(Pm, 1.0f), worldViewProj); \n 
  259                                         return (pCamera.z - pCamera.w*2.0f); \n 
  263                             <implementation render=\"OGSRenderer\" language=\"GLSL\" lang_version=\"3.0\"> 
  264                                 <function_name val=\"depthShaderPluginInterpolantFragment\" /> 
  266                                     float depthShaderPluginInterpolantFragment(float depthValue) \n 
  268                                         return depthValue; \n 
  271                                 <vertex_source><![CDATA[ 
  272                                     float idepthShaderPluginInterpolantFragment(vec3 Pm, mat4 worldViewProj) \n 
  274                                         vec4 pCamera = worldViewProj * vec4(Pm, 1.0f); \n 
  275                                         return (pCamera.z - pCamera.w*2.0f); \n 
  283                 if omr.MRenderer.drawAPI() == omr.MRenderer.kDirectX11:
 
  284                     vertexFragmentBody = replace(vertexFragmentBody, 
"^1s", 
"semantic=\"extraDepth\" ")
 
  286                     vertexFragmentBody = replace(vertexFragmentBody, 
"^1s", 
" ")
 
  288                 fragmentMgr.addShadeFragmentFromBuffer(vertexFragmentBody, 
False)
 
  290             if not fragmentMgr.hasFragment(
"depthShaderPluginGraph"):
 
  291                 fragmentGraphBody  = textwrap.dedent(
""" 
  292                     <fragment_graph name=\"depthShaderPluginGraph\" ref=\"depthShaderPluginGraph\" class=\"FragmentGraph\" version=\"1.0\"> 
  294                                 <fragment_ref name=\"depthShaderPluginFragment\" ref=\"depthShaderPluginFragment\" /> 
  295                                 <fragment_ref name=\"depthShaderPluginInterpolantFragment\" ref=\"depthShaderPluginInterpolantFragment\" /> 
  298                             <connect from=\"depthShaderPluginInterpolantFragment.outDepthValue\" to=\"depthShaderPluginFragment.depthValue\" /> 
  301                             <float3 name=\"Pm\" ref=\"depthShaderPluginInterpolantFragment.Pm\" semantic=\"Pm\" flags=\"varyingInputParam\" /> 
  302                             <float4x4 name=\"worldViewProj\" ref=\"depthShaderPluginInterpolantFragment.worldViewProj\" semantic=\"worldviewprojection\" /> 
  303                             <float3 name=\"color\" ref=\"depthShaderPluginFragment.color\" /> 
  304                             <float3 name=\"colorFar\" ref=\"depthShaderPluginFragment.colorFar\" /> 
  305                             <float name=\"near\" ref=\"depthShaderPluginFragment.near\" /> 
  306                             <float name=\"far\" ref=\"depthShaderPluginFragment.far\" /> 
  309                             <float3 name=\"color\" value=\"0.0,1.0,0.0\" /> 
  310                             <float3 name=\"colorFar\" value=\"0.0,0.0,1.0\" /> 
  311                             <float name=\"near\" value=\"0.0\" /> 
  312                             <float name=\"far\" value=\"2.0\" /> 
  315                             <float3 name=\"outColor\" ref=\"depthShaderPluginFragment.outColor\" /> 
  317                     </fragment_graph>""")
 
  319                 fragmentMgr.addFragmentGraphFromBuffer(fragmentGraphBody)
 
  321     def supportedDrawAPIs(self):
 
  322         return omr.MRenderer.kOpenGL | omr.MRenderer.kOpenGLCoreProfile | omr.MRenderer.kDirectX11
 
  324     def fragmentName(self):
 
  325         return "depthShaderPluginGraph" 
  330 sRegistrantId = 
"depthShaderPlugin" 
  332 def initializePlugin(obj):
 
  333     plugin = om.MFnPlugin(obj, 
"Autodesk", 
"4.5", 
"Any")
 
  335         userClassify = 
"shader/surface:drawdb/shader/surface/depthShader" 
  336         plugin.registerNode(
"depthShader", depthShader.id, depthShader.creator, depthShader.initialize, om.MPxNode.kDependNode, userClassify)
 
  338         sys.stderr.write(
"Failed to register node\n")
 
  343         omr.MDrawRegistry.registerSurfaceShadingNodeOverrideCreator(
"drawdb/shader/surface/depthShader", sRegistrantId, depthShaderOverride.creator)
 
  345         sys.stderr.write(
"Failed to register override\n")
 
  348 def uninitializePlugin(obj):
 
  349     plugin = om.MFnPlugin(obj)
 
  351         plugin.deregisterNode(depthShader.id)
 
  353         sys.stderr.write(
"Failed to deregister node\n")
 
  358         omr.MDrawRegistry.deregisterSurfaceShadingNodeOverrideCreator(
"drawdb/shader/surface/depthShader", sRegistrantId)
 
  360         sys.stderr.write(
"Failed to deregister override\n")