////////////////////////////////////////////////////////////////////////////// // ToonShader.cpp Maya3.0用Shaderプラグイン // 2000 11/20 Ver1.0 Shouji Fukuda // // 使用注意 // Maya3.0でしか動きません。 // lightはDirectional LightかPoint Lightを使うこと。 // ////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #include #include #include #include #include #include #include class toon : MPxNode { public : toon () ; virtual ~toon () ; virtual MStatus compute ( const MPlug&, MDataBlock& ) ; virtual void postConstructor () ; static void * creator () ; static MStatus initialize () ; static MTypeId id ; protected : static MObject aTranslucenceCoeff ; static MObject aDiffuse ; static MObject aColorR, aColorG, aColorB ; static MObject aColor ; static MObject aColorR2, aColorG2, aColorB2 ; static MObject aColor2 ; // 白熱 static MObject aIncandescenceR, aIncandescenceG, aIncandescenceB ; static MObject aIncandescence ; // 透明度 static MObject aInTransR, aInTransG, aInTransB ; static MObject aInTransparency ; // 出力色 static MObject aOutColorR, aOutColorG, aOutColorB ; static MObject aOutColor ; // 出力透明度 static MObject aOutTransR, aOutTransG, aOutTransB ; static MObject aOutTransparency; // 法線データと思われる static MObject aNormalCameraX, aNormalCameraY, aNormalCameraZ ; static MObject aNormalCamera ; // 視線ベクトル static MObject aPointCameraX, aPointCameraY, aPointCameraZ ; static MObject aPointCamera ; // 輪郭線を出すためのパラメータ static MObject aRinkaku ; // 影の濃さを調節する static MObject aShadow ; static MObject aLightDirectionX, aLightDirectionY, aLightDirectionZ ; static MObject aLightDirection ; // 光の強度 static MObject aLightIntensityR, aLightIntensityG, aLightIntensityB ; static MObject aLightIntensity ; static MObject aLightAmbient, aLightDiffuse, aLightSpecular ; static MObject aLightShadowFraction ; static MObject aPreShadowIntensity ; static MObject aLightBlindData; static MObject aLightData ; } ; ////////////////////////////////////////////////////////////////////////////// // IDを決める // Shading Nodeであると宣言 ////////////////////////////////////////////////////////////////////////////// MTypeId toon::id ( 0x31003 ) ; void toon::postConstructor () { setMPSafe(true); } ////////////////////////////////////////////////////////////////////////////// // 変数宣言 ////////////////////////////////////////////////////////////////////////////// MObject toon::aTranslucenceCoeff ; MObject toon::aDiffuse ; MObject toon::aInTransparency ; MObject toon::aInTransR ; MObject toon::aInTransG ; MObject toon::aInTransB ; MObject toon::aColor ; MObject toon::aColorR ; MObject toon::aColorG ; MObject toon::aColorB ; MObject toon::aColorR2 ; MObject toon::aColorG2 ; MObject toon::aColorB2 ; MObject toon::aColor2 ; MObject toon::aIncandescence ; MObject toon::aIncandescenceR ; MObject toon::aIncandescenceG ; MObject toon::aIncandescenceB ; MObject toon::aOutColor ; MObject toon::aOutColorR ; MObject toon::aOutColorG ; MObject toon::aOutColorB; MObject toon::aOutTransparency ; MObject toon::aOutTransR ; MObject toon::aOutTransG ; MObject toon::aOutTransB ; MObject toon::aNormalCamera ; MObject toon::aNormalCameraX ; MObject toon::aNormalCameraY ; MObject toon::aNormalCameraZ ; MObject toon::aPointCameraX ; MObject toon::aPointCameraY ; MObject toon::aPointCameraZ ; MObject toon::aPointCamera ; MObject toon::aRinkaku ; MObject toon::aShadow ; MObject toon::aLightData ; MObject toon::aLightDirection ; MObject toon::aLightDirectionX ; MObject toon::aLightDirectionY ; MObject toon::aLightDirectionZ ; MObject toon::aLightIntensity ; MObject toon::aLightIntensityR ; MObject toon::aLightIntensityG ; MObject toon::aLightIntensityB ; MObject toon::aLightAmbient ; MObject toon::aLightDiffuse ; MObject toon::aLightSpecular ; MObject toon::aLightShadowFraction ; MObject toon::aPreShadowIntensity ; MObject toon::aLightBlindData ; toon::toon () { } toon::~toon () { } void* toon::creator() { return new toon () ; } MStatus toon::initialize() { MFnNumericAttribute nAttr; MFnLightDataAttribute lAttr; aTranslucenceCoeff = nAttr.create( "translucenceCoeff", "tc", MFnNumericData::kFloat); nAttr.setStorable(true); nAttr.setDefault(0.0f); aDiffuse = nAttr.create( "diffuse", "drfl", MFnNumericData::kFloat); nAttr.setStorable(true); nAttr.setMin(0.0f); nAttr.setMax(1.0f); nAttr.setDefault(0.5f); aColorR = nAttr.create( "colorR", "cr",MFnNumericData::kFloat); nAttr.setStorable(true); nAttr.setDefault(0.0f); aColorG = nAttr.create( "colorG", "cg",MFnNumericData::kFloat); nAttr.setStorable(true); nAttr.setDefault(1.0f); aColorB = nAttr.create( "colorB", "cb",MFnNumericData::kFloat); nAttr.setStorable(true); nAttr.setDefault(0.0f); aColor = nAttr.create( "color", "c", aColorR, aColorG, aColorB); nAttr.setStorable(true); nAttr.setDefault(0.0f, 1.0f, 0.0f); nAttr.setUsedAsColor(true); aColorR2 = nAttr.create ( "colorR2", "cr2", MFnNumericData::kFloat ) ; nAttr.setStorable(true); nAttr.setDefault(0.0f); aColorG2 = nAttr.create( "colorG2", "cg2",MFnNumericData::kFloat ) ; nAttr.setStorable(true); nAttr.setDefault(0.5f); aColorB2 = nAttr.create( "colorB2", "cb2",MFnNumericData::kFloat ) ; nAttr.setStorable(true); nAttr.setDefault(0.0f); aColor2 = nAttr.create( "color2", "c2", aColorR2, aColorG2, aColorB2 ); nAttr.setStorable(true); nAttr.setDefault(0.0f, 0.5f, 0.0f); nAttr.setUsedAsColor(true); aIncandescenceR = nAttr.create( "incandescenceR", "ir", MFnNumericData::kFloat); nAttr.setStorable(true); nAttr.setDefault(0.0f); aIncandescenceG = nAttr.create( "incandescenceG", "ig", MFnNumericData::kFloat); nAttr.setStorable(true); nAttr.setDefault(0.0f); aIncandescenceB = nAttr.create( "incandescenceB", "ib", MFnNumericData::kFloat); nAttr.setStorable(true); nAttr.setDefault(0.0f); aIncandescence = nAttr.create( "incandescence","ic", aIncandescenceR, aIncandescenceG, aIncandescenceB); nAttr.setStorable(true); nAttr.setDefault(0.0f, 0.0f, 0.0f); nAttr.setUsedAsColor(true); aInTransR = nAttr.create( "transparencyR", "itr",MFnNumericData::kFloat); nAttr.setStorable(true); aInTransG = nAttr.create( "transparencyG", "itg",MFnNumericData::kFloat); nAttr.setStorable(true); aInTransB = nAttr.create( "transparencyB", "itb",MFnNumericData::kFloat); nAttr.setStorable(true); aInTransparency = nAttr.create( "Transparency", "it", aInTransR,aInTransG,aInTransB); nAttr.setStorable(true); nAttr.setDefault(0.0f, 0.0f, 0.0f); nAttr.setUsedAsColor(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.setHidden(false); nAttr.setReadable(true); nAttr.setWritable(false); aOutTransR = nAttr.create( "outTransparencyR","otr", MFnNumericData::kFloat); aOutTransG = nAttr.create( "outTransparencyG","otg", MFnNumericData::kFloat); aOutTransB = nAttr.create( "outTransparencyB","otb", MFnNumericData::kFloat); aOutTransparency = nAttr.create( "outTransparency","ot", aOutTransR,aOutTransG,aOutTransB); nAttr.setHidden(false); nAttr.setReadable(true); nAttr.setWritable(false); 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.setDefault(1.0f, 1.0f, 1.0f); nAttr.setHidden(true); aPointCameraX = nAttr.create( "pointCameraX", "px", MFnNumericData::kFloat); nAttr.setStorable(false); nAttr.setDefault(1.0f); aPointCameraY = nAttr.create( "pointCameraY", "py", MFnNumericData::kFloat); nAttr.setStorable(false); nAttr.setDefault(1.0f); aPointCameraZ = nAttr.create( "pointCameraZ", "pz", MFnNumericData::kFloat); nAttr.setStorable(false); nAttr.setDefault(1.0f); aPointCamera = nAttr.create( "pointCamera","p", aPointCameraX, aPointCameraY, aPointCameraZ); nAttr.setStorable(false); nAttr.setHidden(true); //輪郭線 aRinkaku = nAttr.create ( "rinkaku", "rin", MFnNumericData::kFloat ) ; nAttr.setStorable(true); nAttr.setMin(-0.2f); nAttr.setMax(1.0f); nAttr.setDefault(0.3f); aShadow = nAttr.create ( "shadow", "sha", MFnNumericData::kFloat ) ; nAttr.setStorable(true); nAttr.setMin(0.0f); nAttr.setMax(1.0f); nAttr.setDefault(0.5f); aLightDirectionX = nAttr.create( "lightDirectionX", "ldx", MFnNumericData::kFloat); nAttr.setStorable(false); nAttr.setHidden(true); nAttr.setReadable(false); nAttr.setDefault(1.0f); aLightDirectionY = nAttr.create( "lightDirectionY", "ldy", MFnNumericData::kFloat); nAttr.setStorable(false); nAttr.setHidden(true); nAttr.setReadable(false); nAttr.setDefault(1.0f); aLightDirectionZ = nAttr.create( "lightDirectionZ", "ldz", MFnNumericData::kFloat); nAttr.setStorable(false); nAttr.setHidden(true); nAttr.setReadable(false); nAttr.setDefault(1.0f); aLightDirection = nAttr.create( "lightDirection", "ld", aLightDirectionX, aLightDirectionY, aLightDirectionZ); nAttr.setStorable(false); nAttr.setHidden(true); nAttr.setReadable(false); nAttr.setDefault(1.0f, 1.0f, 1.0f); aLightIntensityR = nAttr.create( "lightIntensityR", "lir", MFnNumericData::kFloat); nAttr.setStorable(false); nAttr.setHidden(true); nAttr.setReadable(false); nAttr.setDefault(1.0f); aLightIntensityG = nAttr.create( "lightIntensityG", "lig", MFnNumericData::kFloat); nAttr.setStorable(false); nAttr.setHidden(true); nAttr.setReadable(false); nAttr.setDefault(1.0f); aLightIntensityB = nAttr.create( "lightIntensityB", "lib", MFnNumericData::kFloat); nAttr.setStorable(false); nAttr.setHidden(true); nAttr.setReadable(false); nAttr.setDefault(1.0f); aLightIntensity = nAttr.create( "lightIntensity", "li", aLightIntensityR, aLightIntensityG, aLightIntensityB); nAttr.setStorable(false); nAttr.setHidden(true); nAttr.setReadable(false); nAttr.setDefault(1.0f, 1.0f, 1.0f); aLightAmbient = nAttr.create( "lightAmbient", "la", MFnNumericData::kBoolean); nAttr.setStorable(false); nAttr.setHidden(true); nAttr.setReadable(false); nAttr.setDefault(true); aLightDiffuse = nAttr.create( "lightDiffuse", "ldf", MFnNumericData::kBoolean); nAttr.setStorable(false); nAttr.setHidden(true); nAttr.setReadable(false); nAttr.setDefault(true); aLightSpecular = nAttr.create( "lightSpecular", "ls", MFnNumericData::kBoolean); nAttr.setStorable(false); nAttr.setHidden(true); nAttr.setReadable(false); nAttr.setDefault(false); aLightShadowFraction = nAttr.create( "lightShadowFraction", "lsf", MFnNumericData::kFloat); nAttr.setStorable(false); nAttr.setReadable(true); nAttr.setWritable(true); nAttr.setDefault(1.0f); aPreShadowIntensity = nAttr.create( "preShadowIntensity", "psi", MFnNumericData::kFloat); nAttr.setStorable(false); nAttr.setHidden(true); nAttr.setReadable(false); nAttr.setDefault(1.0f); aLightBlindData = nAttr.create( "lightBlindData", "lbld", MFnNumericData::kLong); nAttr.setStorable(false); nAttr.setHidden(true); nAttr.setReadable(false); nAttr.setDefault(0); aLightData = lAttr.create( "lightDataArray", "ltd", aLightDirection, aLightIntensity, aLightAmbient, aLightDiffuse, aLightSpecular, aLightShadowFraction, aPreShadowIntensity, aLightBlindData); lAttr.setArray(true); lAttr.setStorable(false); lAttr.setHidden(true); lAttr.setDefault(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, true, true, false, 1.0f, 1.0f, 0); addAttribute(aTranslucenceCoeff); addAttribute(aDiffuse); addAttribute(aColorR); addAttribute(aColorG); addAttribute(aColorB); addAttribute(aColor); addAttribute ( aColorR2 ) ; addAttribute ( aColorG2 ) ; addAttribute ( aColorB2 ) ; addAttribute ( aColor2 ) ; addAttribute(aIncandescenceR); addAttribute(aIncandescenceG); addAttribute(aIncandescenceB); addAttribute(aIncandescence); addAttribute(aInTransR); addAttribute(aInTransG); addAttribute(aInTransB); addAttribute(aInTransparency); addAttribute(aOutColorR); addAttribute(aOutColorG); addAttribute(aOutColorB); addAttribute(aOutColor); addAttribute(aOutTransR); addAttribute(aOutTransG); addAttribute(aOutTransB); addAttribute(aOutTransparency); addAttribute(aNormalCameraX); addAttribute(aNormalCameraY); addAttribute(aNormalCameraZ); addAttribute(aNormalCamera); addAttribute(aPointCameraX); addAttribute(aPointCameraY); addAttribute(aPointCameraZ); addAttribute(aPointCamera); addAttribute ( aRinkaku ) ; addAttribute ( aShadow ) ; addAttribute(aLightDirectionX); addAttribute(aLightDirectionY); addAttribute(aLightDirectionZ); addAttribute(aLightDirection); addAttribute(aLightIntensityR); addAttribute(aLightIntensityG); addAttribute(aLightIntensityB); addAttribute(aLightIntensity); addAttribute(aLightAmbient); addAttribute(aLightDiffuse); addAttribute(aLightSpecular); addAttribute(aLightShadowFraction); addAttribute(aPreShadowIntensity); addAttribute ( aLightBlindData ) ; addAttribute(aLightData); attributeAffects (aTranslucenceCoeff, aOutColor); attributeAffects (aDiffuse, aOutColor); attributeAffects (aColorR, aOutColor); attributeAffects (aColorG, aOutColor); attributeAffects (aColorB, aOutColor); attributeAffects (aColor, aOutColor); attributeAffects ( aColorR2, aOutColor ) ; attributeAffects ( aColorG2, aOutColor ) ; attributeAffects ( aColorB2, aOutColor ) ; attributeAffects ( aColor2, aOutColor ) ; attributeAffects (aInTransR, aOutTransparency); attributeAffects (aInTransG, aOutTransparency); attributeAffects (aInTransB, aOutTransparency); attributeAffects (aInTransparency, aOutTransparency); attributeAffects (aInTransparency, aOutColor); attributeAffects (aIncandescenceR, aOutColor); attributeAffects (aIncandescenceG, aOutColor); attributeAffects (aIncandescenceB, aOutColor); attributeAffects (aIncandescence, aOutColor); attributeAffects (aLightIntensityR, aOutColor); attributeAffects (aLightIntensityB, aOutColor); attributeAffects (aLightIntensityG, aOutColor); attributeAffects (aLightIntensity, aOutColor); attributeAffects (aNormalCameraX, aOutColor); attributeAffects (aNormalCameraY, aOutColor); attributeAffects (aNormalCameraZ, aOutColor); attributeAffects (aNormalCamera, aOutColor); attributeAffects (aPointCameraX, aOutColor); attributeAffects (aPointCameraY, aOutColor); attributeAffects (aPointCameraZ, aOutColor); attributeAffects (aPointCamera, aOutColor); attributeAffects ( aRinkaku, aOutColor ) ; attributeAffects ( aShadow, aOutColor ) ; attributeAffects (aLightDirectionX, aOutColor); attributeAffects (aLightDirectionY, aOutColor); attributeAffects (aLightDirectionZ, aOutColor); attributeAffects (aLightDirection, aOutColor); attributeAffects (aLightAmbient, aOutColor); attributeAffects (aLightSpecular, aOutColor); attributeAffects (aLightDiffuse, aOutColor); attributeAffects (aLightShadowFraction, aOutColor); attributeAffects (aPreShadowIntensity, aOutColor); attributeAffects ( aLightBlindData, aOutColor ) ; attributeAffects (aLightData, aOutColor); return MS::kSuccess; } MStatus toon::compute( const MPlug& plug, MDataBlock& block ) { if( plug == aOutColor || plug == aOutColorR || plug == aOutColorG || plug == aOutColorB || plug == aOutTransparency || plug == aOutTransR || plug == aOutTransG || plug == aOutTransB ) { MFloatVector resultColor(0.0,0.0,0.0); MFloatVector& surfaceNormal = block.inputValue( aNormalCamera ).asFloatVector(); MFloatVector& surfaceColor = block.inputValue( aColor ).asFloatVector(); MFloatVector& surfaceColor2 = block.inputValue ( aColor2 ).asFloatVector () ; MFloatVector& incandescence = block.inputValue( aIncandescence ).asFloatVector(); MFloatVector& viewVector = block.inputValue( aPointCamera ).asFloatVector(); float& rin = block.inputValue ( aRinkaku ).asFloat () ; float& sha = block.inputValue ( aShadow ).asFloat () ; float diffuse = block.inputValue( aDiffuse ).asFloat(); float translucenceCoeff = block.inputValue( aTranslucenceCoeff ).asFloat(); float nor = block.inputValue( aNormalCameraZ ).asFloat(); // Normalize the view vector double d = sqrt((viewVector[0] * viewVector[0]) + (viewVector[1] * viewVector[1]) + (viewVector[2] * viewVector[2])); if (d != (double)0.0) { viewVector[0] /= d; viewVector[1] /= d; viewVector[2] /= d; } viewVector[0] *= -1 ; viewVector[1] *= -1 ; viewVector[2] *= -1 ; // 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(); // find diffuse component if( currentLight.child(aLightDiffuse).asBool() ) { MFloatVector& lightDirection = currentLight.child(aLightDirection).asFloatVector(); float cosln = lightDirection * surfaceNormal; float sign = surfaceNormal * viewVector ; if( cosln > diffuse ) { resultColor[0] += surfaceColor[0] ; resultColor[1] += surfaceColor[1] ; resultColor[2] += surfaceColor[2] ; } else { resultColor[0] += surfaceColor2[0] ; resultColor[1] += surfaceColor2[1] ; resultColor[2] += surfaceColor2[2] ; } if ( lightIntensity [0] < 1.0 ) { resultColor[0] *= sha ; resultColor[1] *= sha ; resultColor[2] *= sha ; } //輪郭線を決める if ( sign > 0.0 && sign < rin ) { resultColor[0] = 0.0 ; resultColor[1] = 0.0 ; resultColor[2] = 0.0 ; } } if( !lightData.next() ) break; } resultColor[0] += incandescence[0] ; resultColor[1] += incandescence[1] ; resultColor[2] += incandescence[2] ; // set ouput color attribute MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; outColorHandle.setClean(); MFloatVector& transparency = block.inputValue( aInTransparency ).asFloatVector(); // set ouput transparency MDataHandle outTransHandle = block.outputValue( aOutTransparency ); MFloatVector& outTrans = outTransHandle.asFloatVector(); outTrans = transparency; outTransHandle.setClean(); } else return MS::kUnknownParameter; return MS::kSuccess; } ////////////////////////////////////////////////////////////////////////////// // プラグインのチェックを付けたときにそれを起動する ////////////////////////////////////////////////////////////////////////////// MStatus initializePlugin( MObject obj ) { const MString UserClassify( "shader/surface" ); MString command( "if( `window -exists createRenderNodeWindow` ) {refreshCreateRenderNodeWindow(\"" ); MFnPlugin plugin( obj, "Shouji Fukuda", "1.0", "3.0"); plugin.registerNode( "toonShader", toon::id, toon::creator, toon::initialize, MPxNode::kDependNode, &UserClassify ); command += UserClassify; command += "\");}\n"; MGlobal::executeCommand(command); return MS::kSuccess; } ////////////////////////////////////////////////////////////////////////////// // プラグインのチェックを外したときにそれをclearする ////////////////////////////////////////////////////////////////////////////// MStatus uninitializePlugin( MObject obj ) { const MString UserClassify( "shader/surface" ); MString command( "if( `window -exists createRenderNodeWindow` ) {refreshCreateRenderNodeWindow(\"" ); MFnPlugin plugin( obj ); plugin.deregisterNode( toon::id ); command += UserClassify; command += "\");}\n"; MGlobal::executeCommand(command); return MS::kSuccess; } ////////////////////////////////////////////////////////////////////////////// // EOF ToonShader.cpp //////////////////////////////////////////////////////////////////////////////