//- // ========================================================================== // Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors. All // rights reserved. // // The coded instructions, statements, computer programs, and/or related // material (collectively the "Data") in these files contain unpublished // information proprietary to Autodesk, Inc. ("Autodesk") and/or its // licensors, which is protected by U.S. and Canadian federal copyright // law and by international treaties. // // The Data is provided for use exclusively by You. You have the right // to use, modify, and incorporate this Data into other products for // purposes authorized by the Autodesk software license agreement, // without fee. // // The copyright notices in the Software and this entire statement, // including the above license grant, this restriction and the // following disclaimer, must be included in all copies of the // Software, in whole or in part, and all derivative works of // the Software, unless such copies or derivative works are solely // in the form of machine-executable object code generated by a // source language processor. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. // AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED // WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF // NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR // PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR // TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS // BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, // DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK // AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY // OR PROBABILITY OF SUCH DAMAGES. // // ========================================================================== //+ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class anisotropicShaderNode : public MPxNode { public: anisotropicShaderNode(); virtual ~anisotropicShaderNode(); virtual MStatus compute( const MPlug&, MDataBlock& ); virtual void postConstructor(); static void * creator(); static MStatus initialize(); // Id tag for use with binary file format static const MTypeId id; private: MFloatVector calcHalfVector(const MFloatVector&,const MFloatVector&) const; static void setAttribute( void ); // Input attributes static MObject aColor; // Surface color static MObject aDiffuseReflectivity; // Diffuse Reflectivity static MObject aSpecularCoeff; // Specular coefficient static MObject aSpecColor; // Specular color static MObject aInTransparency; // Transparency static MObject aLightIntensity; // Light Intensity static MObject aLightDirection; // Light direction vector static MObject aPointCamera; // Position static MObject aNormalCamera; // Surface normal static MObject aRayDirection; // Ray direction // Light data static MObject aLightAmbient; static MObject aLightDiffuse; static MObject aLightSpecular; static MObject aLightShadowFraction; static MObject aPreShadowIntensity; static MObject aLightBlindData; static MObject aLightData; // anisotropic parameter static MObject aRoughness1; static MObject aRoughness2; static MObject aAxesVector; // matrix static MObject aMatrixOToW; static MObject aMatrixWToC; // Output attributes static MObject aOutColor; static MObject aOutTransparency; }; // Static data const MTypeId anisotropicShaderNode::id( 0x81014 ); // Attributes 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() { } // creates an instance of the node void* anisotropicShaderNode::creator() { return new anisotropicShaderNode; } // initializes attribute information // call by MAYA when this plug-in was loded. // MStatus anisotropicShaderNode::initialize() { MFnNumericAttribute nAttr; MFnLightDataAttribute lAttr; MFnMatrixAttribute mAttr; aMatrixOToW = mAttr.create( "matrixObjectToWorld", "mow", MFnMatrixAttribute::kFloat ); CHECK_MSTATUS( mAttr.setStorable( false ) ); CHECK_MSTATUS( mAttr.setHidden( true ) ); aMatrixWToC = mAttr.create( "matrixWorldToEye", "mwc", MFnMatrixAttribute::kFloat ); CHECK_MSTATUS( mAttr.setStorable( false ) ); CHECK_MSTATUS( mAttr.setHidden( true ) ); aDiffuseReflectivity = nAttr.create( "diffuseReflectivity", "drfl", MFnNumericData::kFloat); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setDefault(0.8f) ); CHECK_MSTATUS( nAttr.setMin(0.0f) ); CHECK_MSTATUS( nAttr.setMax(1.0f) ); aColor = nAttr.createColor( "color", "c" ); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setDefault(0.0f, 0.58824f, 0.644f) ); aNormalCamera = nAttr.createPoint( "normalCamera", "n" ); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setHidden(true) ); aLightDirection = nAttr.createPoint( "lightDirection", "ld"); CHECK_MSTATUS ( nAttr.setStorable(false) ); CHECK_MSTATUS ( nAttr.setHidden(true) ); CHECK_MSTATUS ( nAttr.setReadable(true) ); CHECK_MSTATUS ( nAttr.setWritable(false) ); aLightIntensity = nAttr.createColor( "lightIntensity", "li" ); CHECK_MSTATUS ( nAttr.setStorable(false) ); CHECK_MSTATUS ( nAttr.setHidden(true) ); CHECK_MSTATUS ( nAttr.setReadable(true) ); CHECK_MSTATUS ( nAttr.setWritable(false) ); aLightAmbient = nAttr.create( "lightAmbient", "la", MFnNumericData::kBoolean); CHECK_MSTATUS ( nAttr.setStorable(false) ); CHECK_MSTATUS ( nAttr.setHidden(true) ); CHECK_MSTATUS ( nAttr.setReadable(true) ); CHECK_MSTATUS ( nAttr.setWritable(false) ); aLightDiffuse = nAttr.create( "lightDiffuse", "ldf", MFnNumericData::kBoolean); CHECK_MSTATUS ( nAttr.setStorable(false) ); CHECK_MSTATUS ( nAttr.setHidden(true) ); CHECK_MSTATUS ( nAttr.setReadable(true) ); CHECK_MSTATUS ( nAttr.setWritable(false) ); aLightSpecular = nAttr.create( "lightSpecular", "ls", MFnNumericData::kBoolean); CHECK_MSTATUS ( nAttr.setStorable(false) ); CHECK_MSTATUS ( nAttr.setHidden(true) ); CHECK_MSTATUS ( nAttr.setReadable(true) ); CHECK_MSTATUS ( nAttr.setWritable(false) ); aLightShadowFraction = nAttr.create( "lightShadowFraction", "lsf", MFnNumericData::kFloat); CHECK_MSTATUS ( nAttr.setStorable(false) ); CHECK_MSTATUS ( nAttr.setHidden(true) ); CHECK_MSTATUS ( nAttr.setReadable(true) ); CHECK_MSTATUS ( nAttr.setWritable(false) ); aPreShadowIntensity = nAttr.create( "preShadowIntensity", "psi", MFnNumericData::kFloat); CHECK_MSTATUS ( nAttr.setStorable(false) ); CHECK_MSTATUS ( nAttr.setHidden(true) ); CHECK_MSTATUS ( nAttr.setReadable(true) ); CHECK_MSTATUS ( nAttr.setWritable(false) ); aLightBlindData = nAttr.createAddr( "lightBlindData", "lbld"); CHECK_MSTATUS ( nAttr.setStorable(false) ); CHECK_MSTATUS ( nAttr.setHidden(true) ); CHECK_MSTATUS ( nAttr.setReadable(true) ); CHECK_MSTATUS ( nAttr.setWritable(false) ); aLightData = lAttr.create( "lightDataArray", "ltd", aLightDirection, aLightIntensity, aLightAmbient, aLightDiffuse, aLightSpecular, aLightShadowFraction, aPreShadowIntensity, aLightBlindData); CHECK_MSTATUS( lAttr.setArray(true) ); CHECK_MSTATUS( lAttr.setStorable(false) ); CHECK_MSTATUS( lAttr.setHidden(true) ); CHECK_MSTATUS( lAttr.setDefault(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, true, false, 0.0f, 1.0f, NULL) ); aSpecularCoeff = nAttr.create( "specularCoeff", "scf", MFnNumericData::kFloat); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setMin(0.0f) ); CHECK_MSTATUS( nAttr.setMax(1.0f) ); CHECK_MSTATUS( nAttr.setDefault(0.8f) ); aPointCamera = nAttr.createPoint( "pointCamera", "pc" ); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setHidden(true) ); // input transparency aInTransparency = nAttr.createColor( "transparency", "it" ); MAKE_INPUT(nAttr); // ray direction aRayDirection = nAttr.createPoint( "rayDirection", "rd" ); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setHidden(true) ); // specular color aSpecColor = nAttr.createColor( "specularColor","sc" ); CHECK_MSTATUS( nAttr.setDefault( .5, .5, .5 ) ); MAKE_INPUT(nAttr); // anisotropic parameters // aRoughness1 = nAttr.create( "roughness1", "rn1", MFnNumericData::kFloat); CHECK_MSTATUS( nAttr.setMin(0.0f) ); CHECK_MSTATUS( nAttr.setMax(1.0f) ); CHECK_MSTATUS( nAttr.setDefault(0.2f) ); aRoughness2 = nAttr.create( "roughness2", "rn2", MFnNumericData::kFloat); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setMin(0.0f) ); CHECK_MSTATUS( nAttr.setMax(1.0f) ); CHECK_MSTATUS( nAttr.setDefault(0.4f) ); aAxesVector = nAttr.createPoint( "axesVector", "av" ); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setDefault( 0.0f, 1.0f, 0.0f ) ); // output color aOutColor = nAttr.createColor( "outColor", "oc" ); MAKE_OUTPUT(nAttr); // output transparency aOutTransparency = nAttr.createColor( "outTransparency", "ot" ); MAKE_OUTPUT(nAttr); setAttribute(); return MS::kSuccess; } void anisotropicShaderNode::setAttribute( void ) { CHECK_MSTATUS( addAttribute( aDiffuseReflectivity ) ); CHECK_MSTATUS( addAttribute( aColor ) ); CHECK_MSTATUS( addAttribute( aInTransparency ) ); CHECK_MSTATUS( addAttribute( aNormalCamera ) ); // Only add the parent of the compound CHECK_MSTATUS( addAttribute( aLightData) ); CHECK_MSTATUS( addAttribute( aSpecularCoeff) ); CHECK_MSTATUS( addAttribute( aRayDirection ) ); CHECK_MSTATUS( addAttribute( aPointCamera) ); CHECK_MSTATUS( addAttribute( aSpecColor) ); CHECK_MSTATUS( addAttribute( aRoughness1) ); CHECK_MSTATUS( addAttribute( aRoughness2) ); CHECK_MSTATUS( addAttribute( aAxesVector) ); CHECK_MSTATUS( addAttribute( aMatrixOToW ) ); CHECK_MSTATUS( addAttribute( aMatrixWToC ) ); CHECK_MSTATUS( addAttribute( aOutColor) ); CHECK_MSTATUS( addAttribute( aOutTransparency ) ); CHECK_MSTATUS( attributeAffects( aDiffuseReflectivity, aOutColor) ); CHECK_MSTATUS( attributeAffects( aLightIntensity, aOutColor) ); CHECK_MSTATUS( attributeAffects( aColor, aOutColor) ); CHECK_MSTATUS( attributeAffects( aInTransparency, aOutColor ) ); CHECK_MSTATUS( attributeAffects( aNormalCamera, aOutColor) ); CHECK_MSTATUS( attributeAffects( aLightData, aOutColor) ); CHECK_MSTATUS( attributeAffects( aLightSpecular, aOutColor) ); CHECK_MSTATUS( attributeAffects( aLightAmbient, aOutColor) ); CHECK_MSTATUS( attributeAffects( aLightDirection, aOutColor) ); CHECK_MSTATUS( attributeAffects( aLightDiffuse, aOutColor) ); CHECK_MSTATUS( attributeAffects( aLightShadowFraction, aOutColor) ); CHECK_MSTATUS( attributeAffects( aPreShadowIntensity, aOutColor) ); CHECK_MSTATUS( attributeAffects( aLightBlindData, aOutColor) ); CHECK_MSTATUS( attributeAffects( aSpecularCoeff, aOutColor) ); CHECK_MSTATUS( attributeAffects( aRayDirection, aOutColor ) ); CHECK_MSTATUS( attributeAffects( aPointCamera, aOutColor) ); CHECK_MSTATUS( attributeAffects( aSpecColor, aOutColor) ); CHECK_MSTATUS( attributeAffects( aRoughness1,aOutColor) ); CHECK_MSTATUS( attributeAffects( aRoughness2, aOutColor) ); CHECK_MSTATUS( attributeAffects( aAxesVector, aOutColor) ); CHECK_MSTATUS( attributeAffects( aMatrixOToW, aOutColor) ); CHECK_MSTATUS( attributeAffects( aMatrixWToC, aOutColor) ); CHECK_MSTATUS( attributeAffects( aInTransparency, aOutTransparency ) ); } #ifndef MIN #define MIN(a,b) ( a 0.0f ){ // illuminated! // find diffuse component if( currentLight.child(aLightDiffuse).asBool()) { 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]; } // find specular component if( currentLight.child( aLightSpecular).asBool()){ MFloatVector& rayDirection = block.inputValue( aRayDirection ).asFloatVector(); MFloatVector viewDirection = -rayDirection; MFloatVector half = calcHalfVector( viewDirection, lightDirection ); // Beckmann function MFloatVector nA; if( fabs(1.0-fabs(N*ca)) <= 0.0001f ){ MFloatPoint oo( 0.0,0.0,0.0 ); MFloatPoint ow = oo * matrixOToW; MFloatPoint oc = ow * matrixWToC; MFloatVector origin( oc[0], oc[1], oc[2] ); nA = origin - surfacePoint; nA.normalize(); }else{ nA = ca; } MFloatVector x = N ^ nA; x.normalize(); MFloatVector y = N ^ x; y.normalize(); MFloatVector azimuthH = N ^ half; azimuthH = N ^ azimuthH; azimuthH.normalize(); 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; float rough1 = block.inputValue( aRoughness1 ).asFloat(); float rough2 = block.inputValue( aRoughness2 ).asFloat(); 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))); MFloatVector& specColor = block.inputValue( aSpecColor ).asFloatVector(); specularColor[0] += lightIntensity[0] * specColor[0] * s * specularCoeff; specularColor[1] += lightIntensity[1] * specColor[1] * s * specularCoeff; specularColor[2] += lightIntensity[2] * specColor[2] * s * specularCoeff; } } if( !lightData.next() ){ break; } } // result = specular + diffuse + ambient; resultColor = diffuseColor + specularColor + ambientColor; MFloatVector& transparency = block.inputValue( aInTransparency ).asFloatVector(); resultColor[0] *= ( 1.0f - transparency[0] ); resultColor[1] *= ( 1.0f - transparency[1] ); resultColor[2] *= ( 1.0f - transparency[2] ); // set ouput color attribute MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; outColorHandle.setClean(); block.setClean( plug ); } else if ((plug == aOutTransparency) || (plug.parent() == aOutTransparency)) { MFloatVector& tr = block.inputValue( aInTransparency ).asFloatVector(); // set ouput color attribute MDataHandle outTransHandle = block.outputValue( aOutTransparency ); MFloatVector& outTrans = outTransHandle.asFloatVector(); outTrans = tr; block.setClean( plug ); } else return MS::kUnknownParameter; return MS::kSuccess; } // // MFloatVector anisotropicShaderNode::calcHalfVector( const MFloatVector& view, const MFloatVector& light ) const { MFloatVector H = (light + view) / 2.0; H.normalize(); return H; } // // DESCRIPTION: /////////////////////////////////////////////////////// MStatus initializePlugin( MObject obj ) { const MString UserClassify( "shader/surface" ); MFnPlugin plugin( obj, "Tadashi Endo", "4.5", "Any"); CHECK_MSTATUS( plugin.registerNode( "anisotropicShader", anisotropicShaderNode::id, anisotropicShaderNode::creator, anisotropicShaderNode::initialize, MPxNode::kDependNode, &UserClassify ) ); return MS::kSuccess; } // // DESCRIPTION: /////////////////////////////////////////////////////// MStatus uninitializePlugin( MObject obj ) { MFnPlugin plugin( obj ); CHECK_MSTATUS( plugin.deregisterNode( anisotropicShaderNode::id ) ); return MS::kSuccess; }