//- // ========================================================================== // 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 // // DESCRIPTION: /////////////////////////////////////////////////////// class BackNode : public MPxNode { public: BackNode(); virtual ~BackNode(); 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: static MObject aTranslucenceCoeff; static MObject aDiffuseReflectivity; static MObject aColor; static MObject aBackColor; static MObject aBoost; static MObject aIncandescence; static MObject aOutColor; static MObject aPointCamera; static MObject aNormalCamera; static MObject aLightDirection; static MObject aLightIntensity; static MObject aPower; static MObject aSpecularity; static MObject aThreshold; // for backfill percentage static MObject aLightAmbient; static MObject aLightDiffuse; static MObject aLightSpecular; static MObject aLightShadowFraction; static MObject aPreShadowIntensity; static MObject aLightBlindData; static MObject aLightData; }; MTypeId BackNode::id( 0x81003 ); MObject BackNode::aTranslucenceCoeff; MObject BackNode::aBackColor; MObject BackNode::aBoost; MObject BackNode::aDiffuseReflectivity; MObject BackNode::aColor; MObject BackNode::aIncandescence; MObject BackNode::aOutColor; MObject BackNode::aPointCamera; MObject BackNode::aNormalCamera; MObject BackNode::aLightData; MObject BackNode::aLightDirection; MObject BackNode::aLightIntensity; MObject BackNode::aLightAmbient; MObject BackNode::aLightDiffuse; MObject BackNode::aLightSpecular; MObject BackNode::aThreshold; MObject BackNode::aLightShadowFraction; MObject BackNode::aPreShadowIntensity; MObject BackNode::aLightBlindData; MObject BackNode::aPower; MObject BackNode::aSpecularity; #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 BackNode::postConstructor( ) { setMPSafe(true); } // // DESCRIPTION: /////////////////////////////////////////////////////// BackNode::BackNode() { } // // DESCRIPTION: /////////////////////////////////////////////////////// BackNode::~BackNode() { } // // DESCRIPTION: /////////////////////////////////////////////////////// void * BackNode::creator() { return new BackNode(); } // // DESCRIPTION: /////////////////////////////////////////////////////// MStatus BackNode::initialize() { MFnNumericAttribute nAttr; MFnLightDataAttribute lAttr; aColor = nAttr.createColor( "color", "c" ); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setDefault(0.0f, 0.58824f, 0.644f) ); aBackColor = nAttr.createColor( "backColor", "bc" ); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setDefault(1.0f, 1.0f, 1.0f) ); aThreshold = nAttr.create( "threshold", "thr", MFnNumericData::kFloat); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setDefault(0.2f) ); CHECK_MSTATUS( nAttr.setMin(0.0f) ); CHECK_MSTATUS( nAttr.setMax(1.0f) ); aBoost = nAttr.create( "boost", "boo", MFnNumericData::kFloat); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setDefault(2.0f) ); CHECK_MSTATUS( nAttr.setMin(0.0f) ); CHECK_MSTATUS( nAttr.setMax(5.0f) ); aIncandescence = nAttr.createColor( "incandescence","ic" ); MAKE_INPUT(nAttr); aTranslucenceCoeff = nAttr.create("translucenceCoeff", "tc", MFnNumericData::kFloat); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setMin(0.0f) ); CHECK_MSTATUS( nAttr.setMax(1.0f) ); aDiffuseReflectivity = nAttr.create("diffuseReflectivity", "drfl", MFnNumericData::kFloat); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setMin(0.0f) ); CHECK_MSTATUS( nAttr.setMax(1.0f) ); CHECK_MSTATUS( nAttr.setDefault(0.8f) ); aOutColor = nAttr.createColor( "outColor", "oc" ); MAKE_OUTPUT(nAttr); aPointCamera = nAttr.createPoint( "pointCamera", "pc" ); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setDefault(1.0f, 1.0f, 1.0f) ); CHECK_MSTATUS( nAttr.setHidden(true) ); aPower = nAttr.create( "power", "pow", MFnNumericData::kFloat); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setMin(0.0f) ); CHECK_MSTATUS( nAttr.setMax(200.0f) ); CHECK_MSTATUS( nAttr.setDefault(10.0f) ); aSpecularity = nAttr.create( "specularity", "spc", MFnNumericData::kFloat); MAKE_INPUT(nAttr); CHECK_MSTATUS( nAttr.setMin(0.0f) ); CHECK_MSTATUS( nAttr.setMax(1.0f) ); CHECK_MSTATUS( nAttr.setDefault(0.5f) ); aNormalCamera = nAttr.createColor( "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) ); CHECK_MSTATUS( nAttr.setDefault(1.0f, 1.0f, 1.0f) ); 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) ); CHECK_MSTATUS( addAttribute(aTranslucenceCoeff) ); CHECK_MSTATUS( addAttribute(aDiffuseReflectivity) ); CHECK_MSTATUS( addAttribute(aColor) ); CHECK_MSTATUS( addAttribute(aIncandescence) ); CHECK_MSTATUS( addAttribute(aPointCamera) ); CHECK_MSTATUS( addAttribute(aNormalCamera) ); // Only add the parent of the compound CHECK_MSTATUS( addAttribute(aLightData) ); CHECK_MSTATUS( addAttribute(aPower) ); CHECK_MSTATUS( addAttribute(aSpecularity) ); CHECK_MSTATUS( addAttribute(aOutColor) ); CHECK_MSTATUS( addAttribute(aBackColor) ); CHECK_MSTATUS( addAttribute(aThreshold) ); CHECK_MSTATUS( addAttribute(aBoost) ); CHECK_MSTATUS( attributeAffects (aTranslucenceCoeff, aOutColor) ); CHECK_MSTATUS( attributeAffects (aDiffuseReflectivity, aOutColor) ); CHECK_MSTATUS( attributeAffects (aLightIntensity, aOutColor) ); CHECK_MSTATUS( attributeAffects (aIncandescence, aOutColor) ); CHECK_MSTATUS( attributeAffects (aPointCamera, aOutColor) ); CHECK_MSTATUS( attributeAffects (aNormalCamera, aOutColor) ); CHECK_MSTATUS( attributeAffects (aLightData, aOutColor) ); CHECK_MSTATUS( attributeAffects (aLightAmbient, aOutColor) ); CHECK_MSTATUS( attributeAffects (aLightSpecular, aOutColor) ); CHECK_MSTATUS( attributeAffects (aLightDiffuse, aOutColor) ); CHECK_MSTATUS( attributeAffects (aLightDirection, aOutColor) ); CHECK_MSTATUS( attributeAffects (aLightShadowFraction, aOutColor) ); CHECK_MSTATUS( attributeAffects (aPreShadowIntensity, aOutColor) ); CHECK_MSTATUS( attributeAffects (aLightBlindData, aOutColor) ); CHECK_MSTATUS( attributeAffects (aPower, aOutColor) ); CHECK_MSTATUS( attributeAffects (aSpecularity, aOutColor) ); CHECK_MSTATUS( attributeAffects (aColor, aOutColor) ); CHECK_MSTATUS( attributeAffects (aBackColor, aOutColor) ); CHECK_MSTATUS( attributeAffects (aThreshold, aOutColor) ); CHECK_MSTATUS( attributeAffects (aBoost, aOutColor) ); return MS::kSuccess; } // // DESCRIPTION: /////////////////////////////////////////////////////// MStatus BackNode::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(0.0,0.0,0.0); // get sample surface shading parameters MFloatVector& surfaceNormal = block.inputValue( aNormalCamera ).asFloatVector(); MFloatVector& cameraPosition = block.inputValue( aPointCamera ).asFloatVector(); MFloatVector& surfaceColor = block.inputValue( aColor ).asFloatVector(); MFloatVector& incandescence = block.inputValue( aIncandescence ).asFloatVector(); float diffuseReflectivity = block.inputValue( aDiffuseReflectivity ).asFloat(); // float translucenceCoeff = block.inputValue( aTranslucenceCoeff ).asFloat(); float threshold = block.inputValue( aThreshold ).asFloat(); MFloatVector& BackLightColor = block.inputValue( aBackColor ).asFloatVector(); float Boost = block.inputValue( aBoost ).asFloat(); // Phong shading attributes float power = block.inputValue( aPower ).asFloat(); float spec = block.inputValue( aSpecularity ).asFloat(); float specularR, specularG, specularB; float diffuseR, diffuseG, diffuseB; float BackR, BackG, BackB; diffuseR = diffuseG = diffuseB = specularR = specularG = specularB = 0.0; BackR = BackG = BackB = 0.0; // get light list MArrayDataHandle lightData = block.inputArrayValue( aLightData ); int numLights = lightData.elementCount(); // iterate through light list and get ambient/diffuse values for( int count=1; count <= numLights; count++ ) { MDataHandle currentLight = lightData.inputValue(); MFloatVector& lightIntensity = currentLight.child(aLightIntensity).asFloatVector(); // float lightShadowF = currentLight.child(aLightShadowFraction).asFloat(); // find ambient component if( currentLight.child(aLightAmbient).asBool() ) { diffuseR += lightIntensity[0]; diffuseG += lightIntensity[1]; diffuseB += lightIntensity[2]; } // find diffuse and specular component if( currentLight.child(aLightDiffuse).asBool() ) { MFloatVector& lightDirection = currentLight.child(aLightDirection).asFloatVector(); float cosln = lightDirection * surfaceNormal; if( cosln > 0.0f ) // calculate only if facing light { diffuseR += lightIntensity[0] * ( cosln * diffuseReflectivity ); diffuseG += lightIntensity[1] * ( cosln * diffuseReflectivity ); diffuseB += lightIntensity[2] * ( cosln * diffuseReflectivity ); } if (((cosln > 0.0) && (cosln <= threshold)) || (cosln <= 0.0)) { float interp; if (threshold != 0.0) { interp = ((1.0f / (-1 - threshold)) * cosln) + (threshold / (threshold + 1)); } else { interp = fabsf(cosln); } BackR += (BackLightColor[0] * interp); BackG += (BackLightColor[1] * interp); BackB += (BackLightColor[2] * interp); } cameraPosition.normalize(); if( cosln > 0.0f ) // calculate only if facing light { float RV = ( ( (2*surfaceNormal) * cosln ) - lightDirection ) * cameraPosition; if( RV < 0.0 ) RV = -RV; if ( power < 0 ) power = -power; float s = spec * powf( RV, power ); specularR += lightIntensity[0] * s; specularG += lightIntensity[1] * s; specularB += lightIntensity[2] * s; } } if( !lightData.next() ) break; } // factor incident light with surface color and add incandescence resultColor[0] = ( diffuseR * surfaceColor[0] ) + specularR + incandescence[0] + (BackR * Boost); resultColor[1] = ( diffuseG * surfaceColor[1] ) + specularG + incandescence[1] + (BackG * Boost); resultColor[2] = ( diffuseB * surfaceColor[2] ) + specularB + incandescence[2] + (BackB * Boost); // 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, PLUGIN_COMPANY, "4.5", "Any"); CHECK_MSTATUS( plugin.registerNode( "backFillShader", BackNode::id, BackNode::creator, BackNode::initialize, MPxNode::kDependNode, &UserClassify ) ); return MS::kSuccess; } // // DESCRIPTION: /////////////////////////////////////////////////////// MStatus uninitializePlugin( MObject obj ) { MFnPlugin plugin( obj ); CHECK_MSTATUS( plugin.deregisterNode( BackNode::id ) ); return MS::kSuccess; }