シェーディング・ノード・プラグイン

シェーディング・ノード・プラグインとは

シェーディング・ノードの種類には以下のものがある。

シェーディング・ノード・プラグインの作り方

シェーディング・ノード・プラグインに必要なメソッド

必要なものはノード・プラグインを作成する場合と変らない。

nodeName()
コンストラクター。
とりあえず空でよい。
virtual ~nodeName()
デコンストラクター。
とりあえず空でよい。
virtual MStatus compute( const MPlug& plug, MDataBlock& data )
ノードが実行する計算・処理を記述する。
static void* nodeName::creator()
ノードが作成された時にノードの実体(インスタンス)を作って返す。
static MStatus nodeName::initialize()
ノードに必要なアトリビュートの設定・登録。
MStatus initializePlugin( MObject obj )
プラグインがロードされるときに実行される。
ノードの登録などを行う。
MStatus uninitializePlugin( MObject obj )
プラグインがアンロードされるときに実行される。
ノードの登録取消などを行う。

シェーディング・ノード・プラグインに必要な定数

MTypeId id
プラグインごとにユニークなid番号
ローカルでテストする場合などは0x00000000以上、0x0007ffff以下の番号を指定する。
プラグインを公表する場合はAlias|Wavefrontからユニークな番号を取得する。

シェーディング・ノード・プラグインの例1

マテリアルを計算するプラグインの一例である。

  1. 以下のプログラムを作る。
    #include <math.h>
    #include <maya/MFnPlugin.h>
    #include <maya/MPxNode.h>
    #include <maya/MFnNumericAttribute.h>
    #include <maya/MFloatVector.h>
    
    class sample1 : public MPxNode 
    {
    public:
    	sample1();
    	virtual ~sample1();
    
    	virtual MStatus compute( const MPlug&, MDataBlock& );
    	static  void    *creator();
    	static  MStatus initialize();
    	static  MTypeId id;        // プラグインのId
    
    protected:
    	static MObject color1R,color1G,color1B,color1;
    	static MObject aNormalCameraX, aNormalCameraY, aNormalCameraZ, aNormalCamera;
    	static MObject aOutColorR, aOutColorG, aOutColorB, aOutColor;
    };
    
    MObject sample1::color1R;
    MObject sample1::color1G;
    MObject sample1::color1B;
    MObject sample1::color1;
    MObject sample1::aNormalCameraX;
    MObject sample1::aNormalCameraY;
    MObject sample1::aNormalCameraZ;
    MObject sample1::aNormalCamera;
    MObject sample1::aOutColorR;
    MObject sample1::aOutColorG;
    MObject sample1::aOutColorB;
    MObject sample1::aOutColor;
    
    sample1::sample1()
    {
    }
    
    sample1::~sample1()
    {
    }
    
    void* sample1::creator()
    {
    	return new sample1();
    }
    
    MStatus sample1::initialize()
    {
    	MFnNumericAttribute nAttr; 
    
    	color1R = nAttr.create( "color1R", "c1r", MFnNumericData::kFloat);
    	color1G = nAttr.create( "color1G", "c1g", MFnNumericData::kFloat);
    	color1B = nAttr.create( "color1B", "c1b", MFnNumericData::kFloat);
    
    	color1 = nAttr.create( "Color", "c1", color1R, color1G, color1B);
    	nAttr.setStorable(true);
    	nAttr.setUsedAsColor(true);
    	nAttr.setDefault(1.0f, 1.0f, 1.0f);
    
    	aNormalCameraX = nAttr.create( "normalCameraX", "nx", MFnNumericData::kFloat);
    	nAttr.setStorable(false);
    	nAttr.setDefault(1.0f);
    
    	aNormalCameraY = nAttr.create( "normalCameraY", "ny", MFnNumericData::kFloat);
    	nAttr.setStorable(false);
    	nAttr.setDefault(1.0f);
    
    	aNormalCameraZ = nAttr.create( "normalCameraZ", "nz", MFnNumericData::kFloat);
    	nAttr.setStorable(false);
    	nAttr.setDefault(1.0f);
    
    	aNormalCamera = nAttr.create( "normalCamera","n", aNormalCameraX, 
    						aNormalCameraY, aNormalCameraZ);
    	nAttr.setStorable(false);
    	nAttr.setHidden(true);
    
    	aOutColorR = nAttr.create( "outColorR", "ocr", MFnNumericData::kFloat);
    	aOutColorG = nAttr.create( "outColorG", "ocg", MFnNumericData::kFloat);
    	aOutColorB = nAttr.create( "outColorB", "ocb", MFnNumericData::kFloat);
    	aOutColor  = nAttr.create( "outColor",   "oc", aOutColorR, aOutColorG, aOutColorB);
    	nAttr.setStorable(false);
    	nAttr.setHidden(false);
    	nAttr.setReadable(true);
    	nAttr.setWritable(false);
    
    	addAttribute(color1R);
    	addAttribute(color1G);
    	addAttribute(color1B);
    	addAttribute(color1);
    	addAttribute(aNormalCameraX);
    	addAttribute(aNormalCameraY);
    	addAttribute(aNormalCameraZ);
    	addAttribute(aNormalCamera);
    	addAttribute(aOutColorR);
    	addAttribute(aOutColorG);
    	addAttribute(aOutColorB);
    	addAttribute(aOutColor);
    
    	attributeAffects(color1R, color1);
    	attributeAffects(color1G, color1);
    	attributeAffects(color1B, color1);
    	attributeAffects(color1,  aOutColor);
    	attributeAffects(aNormalCameraX, aOutColor);
    	attributeAffects(aNormalCameraY, aOutColor);
    	attributeAffects(aNormalCameraZ, aOutColor);
    	attributeAffects(aNormalCamera,  aOutColor);
    
    	return MS::kSuccess;
    }
    
    MTypeId sample1::id( 0x70001 );
    
    MStatus sample1::compute( const MPlug& plug, MDataBlock& block )
    {
    	int k = 0;
    	float gamma, scalar;
    
    	k |= (plug == aOutColor);
    	k |= (plug == aOutColorR);
    	k |= (plug == aOutColorG);
    	k |= (plug == aOutColorB);
    	if(!k)
    	{
    		return MS::kUnknownParameter;
    	}
    
    	MFloatVector resultColor(0.0, 0.0, 0.0);
    
    	MFloatVector& col = block.inputValue( color1 ).asFloatVector();
    	MFloatVector& surfaceNormal = block.inputValue( aNormalCamera ).asFloatVector();
    	if(surfaceNormal[0] < 0)
    	{
    		resultColor[0] = 0.0;
    		resultColor[1] = 0.0;
    		resultColor[2] = 0.0;
    	}
    	else
    	{
    		resultColor[0] = col[0];
    		resultColor[1] = col[1];
    		resultColor[2] = col[2];
    	}
    
    	MDataHandle outColorHandle = block.outputValue( aOutColor );
    	MFloatVector& outColor = outColorHandle.asFloatVector();
    	outColor = resultColor;
    	outColorHandle.setClean();
    
    	return MS::kSuccess;
    }
    
    MStatus initializePlugin( MObject obj )
    {
    	const MString UserClassify( "utility/general" );
    
    	MFnPlugin plugin( obj, "Alias|Wavefront", "1.0", "Any");
    	plugin.registerNode( "sample1", sample1::id,
    				sample1::creator,
    				sample1::initialize,
    				MPxNode::kDependNode, &UserClassify);
    
    	return MS::kSuccess;
    }
    
    MStatus uninitializePlugin( MObject obj)
    {
    	MFnPlugin plugin( obj );
    	plugin.deregisterNode( sample1::id );
    
    	return MS::kSuccess;
    }
    
    
  2. プログラムをコンパイルしMAYAにプラグインとしてロードする。
    loadPlugin sample1;
    (プラグインのパスが設定されていること)
  3. 以下のコマンドでノードを作成する。
    createNode sample1 -n sample11;
  4. 他のシェーディングノードとアトリビュートを接続してシーンに組み込む。
    connectAttr -f sample11.color lambert1.color;
  5. 適当にアトリビュートを設定する。
    setAttr sample11.c1r 1.0;
    setAttr sample11.c1g 0.2;
    setAttr sample11.c1b 0.2;
  6. レンダリングすると、このシェーダーを使っている物体はカメラからの法線ベクトルのX成分が0以下の部分が黒くなる。
    [rendered image of sample1 plugin]

参考


Prev
Home | Contents
abe@injapan.net