C++ API Reference
displacementShader/displacementShader.cpp
#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/MFnNumericAttribute.h>
#include <maya/MFloatVector.h>
#include <maya/MFnPlugin.h>
// DESCRIPTION:
// Produces dependency graph node DispNodeExample
// This node is an example of a displacement shader.
// The inputs for this node are input color and an input multiplier.
// The output attribute for this node is called "displacement".
// To use this shader, create a DispNodeExample node and connect its output to the "displacementShader" input of a Shading Group.
//
class DispNode : public MPxNode
{
public:
DispNode();
~DispNode() override;
MStatus compute( const MPlug&, MDataBlock& ) override;
SchedulingType schedulingType() const override { return SchedulingType::kParallel; }
static void * creator();
static MStatus initialize();
static MTypeId id;
private:
static MObject aColor;
static MObject aInputValue;
static MObject aOutColor;
static MObject aOutTransparency;
static MObject aOutDisplacement;
};
MTypeId DispNode::id( 0x81011 );
MObject DispNode::aColor;
MObject DispNode::aInputValue;
MObject DispNode::aOutColor;
MObject DispNode::aOutTransparency;
MObject DispNode::aOutDisplacement;
//
// DESCRIPTION:
DispNode::DispNode()
{
}
//
// DESCRIPTION:
DispNode::~DispNode()
{
}
//
// DESCRIPTION:
void* DispNode::creator()
{
return new DispNode();
}
//
// DESCRIPTION:
MStatus DispNode::initialize()
{
// Inputs
aColor = nAttr.createColor( "color", "c" );
CHECK_MSTATUS(nAttr.setKeyable(true));
CHECK_MSTATUS(nAttr.setStorable(true));
CHECK_MSTATUS(nAttr.setDefault(1.0f, 1.0f, 1.0f));
aInputValue = nAttr.create( "factor", "f", MFnNumericData::kFloat);
CHECK_MSTATUS(nAttr.setKeyable(true));
CHECK_MSTATUS(nAttr.setStorable(true));
CHECK_MSTATUS(nAttr.setDefault(1.0f));
// Outputs
aOutColor = nAttr.createColor( "outColor", "oc" );
CHECK_MSTATUS(nAttr.setStorable(false));
CHECK_MSTATUS(nAttr.setHidden(false));
CHECK_MSTATUS(nAttr.setReadable(true));
CHECK_MSTATUS(nAttr.setWritable(false));
aOutTransparency = nAttr.createColor( "outTransparency", "ot" );
CHECK_MSTATUS(nAttr.setStorable(false));
CHECK_MSTATUS(nAttr.setHidden(false));
CHECK_MSTATUS(nAttr.setReadable(true));
CHECK_MSTATUS(nAttr.setWritable(false));
aOutDisplacement = nAttr.create( "displacement", "od",
CHECK_MSTATUS(nAttr.setStorable(false));
CHECK_MSTATUS(nAttr.setHidden(false));
CHECK_MSTATUS(nAttr.setReadable(true));
CHECK_MSTATUS(nAttr.setWritable(false));
CHECK_MSTATUS(addAttribute(aColor));
CHECK_MSTATUS(addAttribute(aInputValue));
CHECK_MSTATUS(addAttribute(aOutColor));
CHECK_MSTATUS(addAttribute(aOutTransparency));
CHECK_MSTATUS(addAttribute(aOutDisplacement));
CHECK_MSTATUS(attributeAffects (aColor, aOutColor));
CHECK_MSTATUS(attributeAffects (aColor, aOutDisplacement));
return MS::kSuccess;
}
//
// DESCRIPTION:
MStatus DispNode::compute(
const MPlug& plug,
MDataBlock& block )
{
if ((plug == aOutColor) || (plug.parent() == aOutColor) ||
(plug == aOutDisplacement))
{
MFloatVector resultColor(0.0,0.0,0.0);
MFloatVector& InputColor = block.inputValue( aColor ).asFloatVector();
float MultValue = block.inputValue( aInputValue ).asFloat();
resultColor = InputColor;
float scalar = resultColor[0] + resultColor[1] + resultColor[2];
if (scalar != 0.0) {
scalar /= 3.0;
scalar *= MultValue;
}
// set ouput color attribute
MDataHandle outColorHandle = block.outputValue( aOutColor );
MFloatVector& outColor = outColorHandle.asFloatVector();
outColor = resultColor;
outColorHandle.setClean();
MDataHandle outDispHandle = block.outputValue( aOutDisplacement );
float& outDisp = outDispHandle.asFloat();
outDisp = scalar;
outDispHandle.setClean( );
}
else if ((plug == aOutTransparency) || (plug.parent() == aOutTransparency))
{
// set output transparency to be opaque
MFloatVector transparency(0.0,0.0,0.0);
MDataHandle outTransHandle = block.outputValue( aOutTransparency );
MFloatVector& outTrans = outTransHandle.asFloatVector();
outTrans = transparency;
outTransHandle.setClean( );
}
else
return MS::kUnknownParameter;
return MS::kSuccess;
}
//
// DESCRIPTION:
MStatus initializePlugin( MObject obj )
{
const MString UserClassify( "shader/displacement" );
MFnPlugin plugin( obj, PLUGIN_COMPANY, "4.5", "Any");
CHECK_MSTATUS( plugin.registerNode( "dispNodeExample", DispNode::id,
DispNode::creator, DispNode::initialize,
MPxNode::kDependNode, &UserClassify ) );
return MS::kSuccess;
}
//
// DESCRIPTION:
MStatus uninitializePlugin( MObject obj )
{
MFnPlugin plugin( obj );
CHECK_MSTATUS( plugin.deregisterNode( DispNode::id ) );
return MS::kSuccess;
}