#include <math.h>
#include <maya/MFnPlugin.h>
#include <maya/MPxNode.h>
#include <maya/MString.h>
#include <maya/MTypeId.h>
#include <maya/MIOStream.h>
#include <maya/MPlug.h>
#include <maya/MDataBlock.h>
#include <maya/MDataHandle.h>
#include <maya/MArrayDataHandle.h>
#include <maya/MFnMatrixAttribute.h>
#include <maya/MFnNumericAttribute.h>
#include <maya/MFnLightDataAttribute.h>
#include <maya/MFloatPoint.h>
#include <maya/MFloatVector.h>
#include <maya/MFloatMatrix.h>
class anisotropicShaderNode :
public MPxNode
{
public:
anisotropicShaderNode();
~anisotropicShaderNode() override;
static void * creator();
private:
static void setAttribute( );
static MObject aDiffuseReflectivity;
static MObject aLightShadowFraction;
static MObject aPreShadowIntensity;
};
const MTypeId anisotropicShaderNode::id( 0x81014 );
MObject anisotropicShaderNode::aDiffuseReflectivity;
MObject anisotropicShaderNode::aColor;
MObject anisotropicShaderNode::aInTransparency;
MObject anisotropicShaderNode::aNormalCamera;
MObject anisotropicShaderNode::aLightData;
MObject anisotropicShaderNode::aLightDirection;
MObject anisotropicShaderNode::aLightIntensity;
MObject anisotropicShaderNode::aLightAmbient;
MObject anisotropicShaderNode::aLightDiffuse;
MObject anisotropicShaderNode::aLightSpecular;
MObject anisotropicShaderNode::aLightShadowFraction;
MObject anisotropicShaderNode::aPreShadowIntensity;
MObject anisotropicShaderNode::aLightBlindData;
MObject anisotropicShaderNode::aSpecularCoeff;
MObject anisotropicShaderNode::aPointCamera;
MObject anisotropicShaderNode::aSpecColor;
MObject anisotropicShaderNode::aRoughness1;
MObject anisotropicShaderNode::aRoughness2;
MObject anisotropicShaderNode::aRayDirection;
MObject anisotropicShaderNode::aAxesVector;
MObject anisotropicShaderNode::aMatrixOToW;
MObject anisotropicShaderNode::aMatrixWToC;
MObject anisotropicShaderNode::aOutColor;
MObject anisotropicShaderNode::aOutTransparency;
#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 anisotropicShaderNode::postConstructor( )
{
setMPSafe(true);
}
anisotropicShaderNode::anisotropicShaderNode()
{
}
anisotropicShaderNode::~anisotropicShaderNode()
{
}
void* anisotropicShaderNode::creator()
{
return new anisotropicShaderNode;
}
MStatus anisotropicShaderNode::initialize()
{
aMatrixOToW = mAttr.
create(
"matrixObjectToWorld",
"mow",
aMatrixWToC = mAttr.
create(
"matrixWorldToEye",
"mwc",
aDiffuseReflectivity = nAttr.
create(
"diffuseReflectivity",
"drfl",
MAKE_INPUT(nAttr);
MAKE_INPUT(nAttr);
aNormalCamera = nAttr.
createPoint(
"normalCamera",
"n" );
MAKE_INPUT(nAttr);
aLightDirection = nAttr.
createPoint(
"lightDirection",
"ld");
aLightIntensity = nAttr.
createColor(
"lightIntensity",
"li" );
aLightAmbient = nAttr.
create(
"lightAmbient",
"la",
aLightDiffuse = nAttr.
create(
"lightDiffuse",
"ldf",
aLightSpecular = nAttr.
create(
"lightSpecular",
"ls",
aLightShadowFraction = nAttr.
create(
"lightShadowFraction",
"lsf",
aPreShadowIntensity = nAttr.
create(
"preShadowIntensity",
"psi",
aLightBlindData = nAttr.
createAddr(
"lightBlindData",
"lbld");
aLightData = lAttr.
create(
"lightDataArray",
"ltd",
aLightDirection,
aLightIntensity,
aLightAmbient,
aLightDiffuse,
aLightSpecular,
aLightShadowFraction,
aPreShadowIntensity,
aLightBlindData);
false, 0.0f, 1.0f, NULL) );
aSpecularCoeff = nAttr.
create(
"specularCoeff",
"scf",
MAKE_INPUT(nAttr);
aPointCamera = nAttr.
createPoint(
"pointCamera",
"pc" );
MAKE_INPUT(nAttr);
aInTransparency = nAttr.
createColor(
"transparency",
"it" );
MAKE_INPUT(nAttr);
aRayDirection = nAttr.
createPoint(
"rayDirection",
"rd" );
MAKE_INPUT(nAttr);
aSpecColor = nAttr.
createColor(
"specularColor",
"sc" );
MAKE_INPUT(nAttr);
MAKE_INPUT(nAttr);
MAKE_INPUT(nAttr);
MAKE_OUTPUT(nAttr);
aOutTransparency = nAttr.
createColor(
"outTransparency",
"ot" );
MAKE_OUTPUT(nAttr);
setAttribute();
return MS::kSuccess;
}
void anisotropicShaderNode::setAttribute( )
{
CHECK_MSTATUS( attributeAffects( aDiffuseReflectivity, aOutColor) );
CHECK_MSTATUS( attributeAffects( aLightShadowFraction, aOutColor) );
CHECK_MSTATUS( attributeAffects( aPreShadowIntensity, aOutColor) );
CHECK_MSTATUS( attributeAffects( aInTransparency, aOutTransparency ) );
}
#ifndef MIN
#define MIN(a,b) ( a<b?a:b )
#endif
{
if ((plug == aOutColor) || (plug.
parent() == aOutColor))
{
for( int count=0; count < numLights; count++ ) {
ambientColor[0] += lightIntensity[0] * surfaceColor[0];
ambientColor[1] += lightIntensity[1] * surfaceColor[1];
ambientColor[2] += lightIntensity[2] * surfaceColor[2];
}
float cosln = lightDirection * N;
if( cosln > 0.0f ){
float cosDif = cosln * diffuseReflectivity;
diffuseColor[0] += lightIntensity[0] * cosDif * surfaceColor[0];
diffuseColor[1] += lightIntensity[1] * cosDif * surfaceColor[1];
diffuseColor[2] += lightIntensity[2] * cosDif * surfaceColor[2];
}
MFloatVector half = calcHalfVector( viewDirection, lightDirection );
if( fabs(1.0-fabs(N*ca)) <= 0.0001f ){
nA = origin - surfacePoint;
}else{
nA = ca;
}
azimuthH = N ^ azimuthH;
float cos_phai = x * azimuthH;
float sin_phai = 0.0;
if( fabs(1 - cos_phai*cos_phai) < 0.0001 ){
sin_phai = 0.0;
}else{
sin_phai = sqrtf( 1.0f - cos_phai*cos_phai );
}
double co = pow( (half * N), 4.0f );
double t = tan( acos(half*N) );
t *= -t;
double aaa = cos_phai / rough1;
double bbb = sin_phai / rough2;
t = t * ( aaa*aaa + bbb*bbb );
double D = pow( (1.0/((double)rough1*(double)rough2 * co)), t );
double aa = (2.0 * (N*half) * (N*viewDirection) ) / (viewDirection*half);
double bb = (2.0 * (N*half) * (N*lightDirection) ) / (viewDirection*half);
double cc = 1.0;
double G = 0.0;
G = MIN( aa, bb );
G = MIN( G, cc );
float s = (float) (D * G /
(double)((N*lightDirection) * (N*viewDirection)));
specularColor[0] += lightIntensity[0] * specColor[0] *
s * specularCoeff;
specularColor[1] += lightIntensity[1] * specColor[1] *
s * specularCoeff;
specularColor[2] += lightIntensity[2] * specColor[2] *
s * specularCoeff;
}
}
break;
}
}
resultColor = diffuseColor + specularColor + ambientColor;
resultColor[0] *= ( 1.0f - transparency[0] );
resultColor[1] *= ( 1.0f - transparency[1] );
resultColor[2] *= ( 1.0f - transparency[2] );
outColor = resultColor;
}
else if ((plug == aOutTransparency) || (plug.
parent() == aOutTransparency))
{
outTrans = tr;
} else
return MS::kUnknownParameter;
return MS::kSuccess;
}
{
return H;
}
{
const MString UserClassify(
"shader/surface" );
MFnPlugin plugin( obj,
"Tadashi Endo",
"4.5",
"Any");
CHECK_MSTATUS( plugin.registerNode(
"anisotropicShader", anisotropicShaderNode::id,
anisotropicShaderNode::creator,
anisotropicShaderNode::initialize,
return MS::kSuccess;
}
{
CHECK_MSTATUS( plugin.deregisterNode( anisotropicShaderNode::id ) );
return MS::kSuccess;
}