ruchit
Hi,
I m trying to write facingRatio shader to learn Maya API, below code returns no error but not giving desired result plus lightDirection attribute is coming in output section. Tell me whats wrong in code ?? 


[shad-facing-ratio] 


Code:

#include <math.h>
#include <maya/MPxNode.h>
#include <maya/MIOStream.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnLightDataAttribute.h>
#include <maya/MFloatVector.h>
#include <maya/MFnPlugin.h>
class facingRatioNode : public MPxNode
{
    public:
                      facingRatioNode();
    virtual           ~facingRatioNode();
    virtual MStatus   compute( const MPlug&, MDataBlock& );
    virtual void      postConstructor();
    static void *     creator();
    static MStatus    initialize();
    // Id tag for use with binary file format
    static MTypeId    id;
    private:
    // Input attributes
    static MObject  aLightDirection;
    static MObject  aNormalCamera;  // Surface normal
    // Output attributes
    static MObject aOutColor;
};
MTypeId facingRatioNode::id( 0x65924 );
MObject  facingRatioNode::aLightDirection;
MObject  facingRatioNode::aNormalCamera;
MObject  facingRatioNode::aOutColor;
#define MAKE_INPUT(attr)    \
    CHECK_MSTATUS( attr.setKeyable(true) ) ;    \
    CHECK_MSTATUS( attr.setStorable(true) );    \
    CHECK_MSTATUS( attr.setReadable(true) );    \
    CHECK_MSTATUS( attr.setWritable(true) );
#define MAKE_OUTPUT(attr)   \
    CHECK_MSTATUS( attr.setKeyable(false) );    \
    CHECK_MSTATUS( attr.setStorable(false) );   \
    CHECK_MSTATUS( attr.setReadable(true) );    \
    CHECK_MSTATUS( attr.setWritable(false) );

void facingRatioNode::postConstructor( )
{
    setMPSafe(true);
}

// DESCRIPTION:
facingRatioNode::facingRatioNode()
{
}
// DESCRIPTION:
facingRatioNode::~facingRatioNode()
{
}
void * facingRatioNode::creator()
{
    return new facingRatioNode();
}
// DESCRIPTION:
MStatus facingRatioNode::initialize()
{
  MFnNumericAttribute nAttr; 
    aLightDirection = nAttr.createPoint( "lightDirection", "ld" );
    MAKE_INPUT(nAttr);
    CHECK_MSTATUS ( nAttr.setStorable(false) );
    CHECK_MSTATUS ( nAttr.setReadable(true) );
    CHECK_MSTATUS ( nAttr.setWritable(false) );
    aNormalCamera = nAttr.createPoint( "normalCamera","n");
    CHECK_MSTATUS( nAttr.setStorable( false ) );
    CHECK_MSTATUS( nAttr.setDefault( 1.0f, 1.0f, 1.0f ) );
    CHECK_MSTATUS( nAttr.setHidden( true ) );
  aOutColor = nAttr.createColor( "outColor", "oc" );
    MAKE_OUTPUT(nAttr);
  CHECK_MSTATUS( addAttribute(aNormalCamera));
  CHECK_MSTATUS( addAttribute(aLightDirection));
  CHECK_MSTATUS( addAttribute(aOutColor));

  CHECK_MSTATUS( attributeAffects(aLightDirection, aOutColor));
  CHECK_MSTATUS( attributeAffects(aNormalCamera, aOutColor));
  return MS::kSuccess;
}
MStatus facingRatioNode::compute(const MPlug& plug, MDataBlock& block) 
{
  // outColor or individual R, G, B channel, or alpha
    if ((plug != aOutColor) && (plug.parent() != aOutColor))
       return MS::kUnknownParameter;
    MFloatVector resultColor;
    // get sample surface shading parameters
    MFloatVector& surfaceNormal = block.inputValue( aNormalCamera ).asFloatVector();
    surfaceNormal.normalize();
    MFloatVector& usrDir = block.inputValue( aLightDirection ).asFloatVector();
    float dotPP = (surfaceNormal*usrDir);
    resultColor[0] = dotPP;
    resultColor[1] = dotPP;
    resultColor[2] = dotPP;
    // set ouput color attribute
    MDataHandle outColorHandle = block.outputValue( aOutColor );
    MFloatVector& outColor = outColorHandle.asFloatVector();
    outColor = resultColor;
    outColorHandle.setClean();
    return MS::kSuccess;
}

// DESCRIPTION:
MStatus initializePlugin( MObject obj )

   const MString UserClassify( "shader/surface" );
   MFnPlugin plugin( obj, "Ruchit Bhatt", "1.0", "Any");
   CHECK_MSTATUS( plugin.registerNode( "rbfacingRatio", facingRatioNode::id, 
                         facingRatioNode::creator, facingRatioNode::initialize,
                         MPxNode::kDependNode, &UserClassify ) );
   return MS::kSuccess;
}
// DESCRIPTION:
MStatus uninitializePlugin( MObject obj )
{
   MFnPlugin plugin( obj );
   CHECK_MSTATUS( plugin.deregisterNode( facingRatioNode::id ) );
   return MS::kSuccess;
}
Quote 0 0
ruchit
Attrb input/output issue solved but surfaceNormal not working..How to input surfaceNormal of object ??

rbFacingRatio.png

Code:

#include <math.h>
#include <maya/MPxNode.h>
#include <maya/MIOStream.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnLightDataAttribute.h>
#include <maya/MFloatVector.h>
#include <maya/MFnPlugin.h>
class facingRatioNode : public MPxNode
{
    public:
                      facingRatioNode();
    virtual           ~facingRatioNode();
    virtual MStatus   compute( const MPlug&, MDataBlock& );
    virtual void      postConstructor();
    static void *     creator();
    static MStatus    initialize();
    // Id tag for use with binary file format
    static MTypeId    id;
    private:
    // Input attributes
    static MObject  aLightDirection;
    static MObject  aNormalCamera;  // Surface normal
    // Output attributes
    static MObject aOutColor;
};
MTypeId facingRatioNode::id( 0x65924 );
MObject  facingRatioNode::aLightDirection;
MObject  facingRatioNode::aNormalCamera;
MObject  facingRatioNode::aOutColor;
#define MAKE_INPUT(attr)    \
    CHECK_MSTATUS( attr.setKeyable(true) ) ;    \
    CHECK_MSTATUS( attr.setStorable(true) );    \
    CHECK_MSTATUS( attr.setReadable(true) );    \
    CHECK_MSTATUS( attr.setWritable(true) );
#define MAKE_OUTPUT(attr)   \
    CHECK_MSTATUS( attr.setKeyable(false) );    \
    CHECK_MSTATUS( attr.setStorable(false) );   \
    CHECK_MSTATUS( attr.setReadable(true) );    \
    CHECK_MSTATUS( attr.setWritable(false) );

void facingRatioNode::postConstructor( )
{
    setMPSafe(true);
}

// DESCRIPTION:
facingRatioNode::facingRatioNode()
{
}
// DESCRIPTION:
facingRatioNode::~facingRatioNode()
{
}
void * facingRatioNode::creator()
{
    return new facingRatioNode();
}
// DESCRIPTION:
MStatus facingRatioNode::initialize()
{
  MFnNumericAttribute nAttr; 
    aLightDirection = nAttr.createPoint( "lightDirection", "ld" );
    MAKE_INPUT(nAttr);
    aNormalCamera = nAttr.createPoint( "normalCamera","n");
    MAKE_INPUT(nAttr);
  aOutColor = nAttr.createColor( "outColor", "oc" );
    MAKE_OUTPUT(nAttr);
  CHECK_MSTATUS( addAttribute(aNormalCamera));
  CHECK_MSTATUS( addAttribute(aLightDirection));
  CHECK_MSTATUS( addAttribute(aOutColor));

  CHECK_MSTATUS(attributeAffects(aLightDirection, aOutColor));
  CHECK_MSTATUS(attributeAffects(aNormalCamera, aOutColor));
  return MS::kSuccess;
}
MStatus facingRatioNode::compute(const MPlug& plug, MDataBlock& block) 
{
  // outColor or individual R, G, B channel, or alpha
    if ((plug != aOutColor) && (plug.parent() != aOutColor))
       return MS::kUnknownParameter;
    MFloatVector resultColor;
    // get sample surface shading parameters
    MFloatVector& surfaceNormal = block.inputValue( aNormalCamera ).asFloatVector();
    surfaceNormal.normalize();
    MFloatVector& usrDir = block.inputValue( aLightDirection ).asFloatVector();
    float dotPP = (surfaceNormal*usrDir);
    resultColor[0] = dotPP;
    resultColor[1] = dotPP;
    resultColor[2] = dotPP;
    // set ouput color attribute
    MDataHandle outColorHandle = block.outputValue( aOutColor );
    MFloatVector& outColor = outColorHandle.asFloatVector();
    outColor = resultColor;
    outColorHandle.setClean();
    return MS::kSuccess;
}

// DESCRIPTION:
MStatus initializePlugin( MObject obj )

   const MString UserClassify( "shader/surface" );
   MFnPlugin plugin( obj, "Ruchit Bhatt", "1.0", "Any");
   CHECK_MSTATUS( plugin.registerNode( "rbfacingRatio", facingRatioNode::id, 
                         facingRatioNode::creator, facingRatioNode::initialize,
                         MPxNode::kDependNode, &UserClassify ) );
   return MS::kSuccess;
}
// DESCRIPTION:
MStatus uninitializePlugin( MObject obj )
{
   MFnPlugin plugin( obj );
   CHECK_MSTATUS( plugin.deregisterNode( facingRatioNode::id ) );
   return MS::kSuccess;
}
Quote 0 0
ruchit
Done,
See this result & chck below code, if you find anything in wrong or any suggestion plz tell me. Struggling to learn API :)






Code:

#include <math.h>
#include <maya/MPxNode.h>
#include <maya/MIOStream.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnNumericData.h>
#include <maya/MFnLightDataAttribute.h>
#include <maya/MFloatVector.h>
#include <maya/MDagPath.h>
#include <maya/MGlobal.h>
#include <maya/MFnDagNode.h>
#include <maya/MPlugArray.h>
#include <maya/MFnPlugin.h>
class facingRatioNode : public MPxNode
{
    public:
                      facingRatioNode();
    virtual           ~facingRatioNode();
    virtual MStatus   compute( const MPlug&, MDataBlock& );
    virtual void      postConstructor();
    static void *     creator();
    static MStatus    initialize();
    // Id tag for use with binary file format
    static MTypeId    id;
    private:
    // Input attributes
    static MObject  aRayDirection;
    static MObject  aNormalCamera;  // Surface normal
    static MObject  aInvert;
    // Output attributes
    static MObject aOutColor; 
};
MTypeId facingRatioNode::id( 0x65924 );
MObject  facingRatioNode::aRayDirection;
MObject  facingRatioNode::aNormalCamera;
MObject  facingRatioNode::aInvert;
MObject  facingRatioNode::aOutColor;
#define MAKE_INPUT(attr)    \
    CHECK_MSTATUS( attr.setKeyable(true) ) ;    \
    CHECK_MSTATUS( attr.setStorable(true) );    \
    CHECK_MSTATUS( attr.setReadable(true) );    \
    CHECK_MSTATUS( attr.setWritable(true) );
#define MAKE_OUTPUT(attr)   \
    CHECK_MSTATUS( attr.setKeyable(false) );    \
    CHECK_MSTATUS( attr.setStorable(false) );   \
    CHECK_MSTATUS( attr.setReadable(true) );    \
    CHECK_MSTATUS( attr.setWritable(false) );

void facingRatioNode::postConstructor( )
{
    setMPSafe(true);
}

// DESCRIPTION:
facingRatioNode::facingRatioNode()
{
}
// DESCRIPTION:
facingRatioNode::~facingRatioNode()
{
}
void * facingRatioNode::creator()
{
    return new facingRatioNode();
}
// DESCRIPTION:
MStatus facingRatioNode::initialize()
{
  MFnNumericAttribute nAttr; 
    aRayDirection = nAttr.createPoint( "rayDirection", "rd" );
    MAKE_INPUT(nAttr);
    aNormalCamera = nAttr.createPoint( "normalCamera","n");
    MAKE_INPUT(nAttr);
    aInvert = nAttr.create("invert", "in", MFnNumericData::kBoolean);
    MAKE_INPUT(nAttr);
  aOutColor = nAttr.createColor( "outColor", "oc" );
    MAKE_OUTPUT(nAttr);

  CHECK_MSTATUS( addAttribute(aNormalCamera));
  CHECK_MSTATUS( addAttribute(aRayDirection));
    CHECK_MSTATUS( addAttribute(aInvert));
  CHECK_MSTATUS( addAttribute(aOutColor));

  CHECK_MSTATUS(attributeAffects(aRayDirection, aOutColor));
  CHECK_MSTATUS(attributeAffects(aNormalCamera, aOutColor));
    CHECK_MSTATUS(attributeAffects(aInvert, aOutColor));
  return MS::kSuccess;
}
MStatus facingRatioNode::compute(const MPlug& plug, MDataBlock& block) 
{
  // outColor or individual R, G, B channel, or alpha
    if ((plug != aOutColor) && (plug.parent() != aOutColor))
       return MS::kUnknownParameter;
    MFloatVector resultColor;
    // get sample surface shading parameters
    MFloatVector& surfaceNormal = block.inputValue( aNormalCamera ).asFloatVector();
    surfaceNormal.normalize();
    MFloatVector& usrDir = block.inputValue( aRayDirection ).asFloatVector();
    usrDir.normalize();
    float dotPP = (surfaceNormal*usrDir);
    if(block.inputValue(aInvert).asBool())
    {
        resultColor[0] = 1 - dotPP;
        resultColor[1] = 1 - dotPP;
        resultColor[2] = 1 - dotPP;
    }
    else
    {
        resultColor[0] =  dotPP;
        resultColor[1] =  dotPP;
        resultColor[2] =  dotPP;
    }
    // set ouput color attribute
    MDataHandle outColorHandle = block.outputValue( aOutColor );
    MFloatVector& outColor = outColorHandle.asFloatVector();
    outColor = resultColor;
    outColorHandle.setClean();
    return MS::kSuccess;
}
// DESCRIPTION:
MStatus initializePlugin( MObject obj )

   const MString UserClassify( "shader/surface" );
   MFnPlugin plugin( obj, "Ruchit Bhatt", "1.0", "Any");
   CHECK_MSTATUS( plugin.registerNode( "rbFacingRatio", facingRatioNode::id, 
                         facingRatioNode::creator, facingRatioNode::initialize,
                         MPxNode::kDependNode, &UserClassify ) );
   return MS::kSuccess;
}
// DESCRIPTION:
MStatus uninitializePlugin( MObject obj )
{
   MFnPlugin plugin( obj );
   CHECK_MSTATUS( plugin.deregisterNode( facingRatioNode::id ) );
   return MS::kSuccess;
}


Quote 0 0
pshipkov
Just making sure - you are rendering with Maya software render, correct ?
Quote 0 0
ruchit
@pshipkov
No i am not going to use this in production.. This is only for learning Maya API
Quote 0 0
pshipkov
My point was that your code will work only in Maya Software Render - no Mental Ray, VRay, Arnold, etc.
Quote 0 0
ruchit
Yeah you are right, custom MPxNode shader works only in software Render.
Quote 0 0
pshipkov
This is exactly one of the main problems Maya had since day one.
No native standardized shading language that if supported to any third party render will allow you to build once and use everywhere.
It was Maya's Software Render first, then MR, now Arnold, few years from now it will be something else.
And at the end the main thing does not get fixed.
:)
Quote 0 0

Add a Website Forum to your website.