MStatus hwUnlitShader::compute( const MPlug& plug, MDataBlock& block ) { bool k = false; k |= (plug==outColor); k |= (plug==outColorR); k |= (plug==outColorG); k |= (plug==outColorB); if( !k ) return MS::kUnknownParameter; // Always return black for now. MFloatVector resultColor(0.0,0.0,0.0); // set ouput color attribute MDataHandle outColorHandle = block.outputValue( outColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; outColorHandle.setClean(); return MS::kSuccess; }
// // DESCRIPTION: /////////////////////////////////////////////////////// MStatus MixtureNode::compute(const MPlug& plug, MDataBlock& block ) { if ((plug != aOutColor) && (plug.parent() != aOutColor)) return MS::kUnknownParameter; MFloatVector color1 = block.inputValue( aColor1 ).asFloatVector(); MFloatVector color2 = block.inputValue( aColor2 ).asFloatVector(); MFloatVector mask1 = block.inputValue( aAlphaInput1 ).asFloatVector(); MFloatVector mask2 = block.inputValue( aAlphaInput2 ).asFloatVector(); // Mask1 applied to color1, mask2 applied to color2 color1[0] *= mask1[0]; color1[1] *= mask1[1]; color1[2] *= mask1[2]; color2[0] *= mask2[0]; color2[1] *= mask2[1]; color2[2] *= mask2[2]; // set ouput color attribute MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = color1 + color2; outColorHandle.setClean(); return MS::kSuccess; }
// // This function gets called by Maya to evaluate the texture. // MStatus noise3::compute(const MPlug& plug, MDataBlock& block) { // outColor or individial R, G, B channel, or alpha if((plug != aOutColor) && (plug.parent() != aOutColor) && (plug != aOutAlpha)) return MS::kUnknownParameter; MFloatVector resultColor; MFloatVector & col1 = block.inputValue(aColor1).asFloatVector(); MFloatVector & col2 = block.inputValue(aColor2).asFloatVector(); float3 & worldPos = block.inputValue( aPointWorld ).asFloat3(); MFloatMatrix& mat = block.inputValue( aPlaceMat ).asFloatMatrix(); float& sc = block.inputValue( aScale ).asFloat(); float& bi = block.inputValue( aBias ).asFloat(); MFloatPoint solidPos(worldPos[0], worldPos[1], worldPos[2]); solidPos *= mat; // Convert into solid space float val = fabsf( pnoise3( solidPos ) * sc + bi ); if (val < 0.) val = 0.; if (val > 1.) val = 1.; resultColor = col1 * val + col2*(1-val); // Set output color attribute MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; outColorHandle.setClean(); MDataHandle outAlphaHandle = block.outputValue( aOutAlpha ); float& outAlpha = outAlphaHandle.asFloat(); outAlpha = val; outAlphaHandle.setClean(); return MS::kSuccess; }
// This function gets called by Maya to evaluate the texture. // See "Writing a shading node plug-in" in the documentation // for more information. // // CAVEAT: This part of the HW shader plug-in is meant to allow // seamless transition from HW to SW rendering. // Unfortunately, as of 4.0.1 it's somewhat flaky. // Meanwhile, it is recommended to build two shading networks // in parallel (one for SW, one for HW) and use MEL scripts // to switch from one to the other. // MStatus hwRefractReflectShader_NV20::compute( const MPlug& plug, MDataBlock& block ) { // Get color and lightModel from the input block. // Get UV coordinates from the input block. bool k = false; k |= (plug==outColor); k |= (plug==outColorR); k |= (plug==outColorG); k |= (plug==outColorB); if( !k ) return MS::kUnknownParameter; MFloatVector resultColor(0.0,0.0,0.0); // set ouput color attribute MDataHandle outColorHandle = block.outputValue( outColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; outColorHandle.setClean(); return MS::kSuccess; }
MStatus CheckerNode::compute( const MPlug& plug, MDataBlock& block ) { // outColor or individial R, G, B channel, or alpha if((plug != aOutColor) && (plug.parent() != aOutColor) && (plug != aOutAlpha)) return MS::kUnknownParameter; MFloatVector resultColor; float2 & uv = block.inputValue( aUVCoord ).asFloat2(); float2 & bias = block.inputValue( aBias ).asFloat2(); int count = 0; if (uv[0] - floorf(uv[0]) < bias[0]) count++; if (uv[1] - floorf(uv[1]) < bias[1]) count++; if (count & 1) resultColor = block.inputValue( aColor2 ).asFloatVector(); else resultColor = block.inputValue( aColor1 ).asFloatVector(); // Set ouput color attribute MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; outColorHandle.setClean(); // Set ouput alpha attribute MDataHandle outAlphaHandle = block.outputValue( aOutAlpha ); float& outAlpha = outAlphaHandle.asFloat(); outAlpha = (count & 1) ? 1.f : 0.f; outAlphaHandle.setClean(); return MS::kSuccess; }
// Compute takes two parameters: plug and data. // - Plug is the the data value that needs to be recomputed // - Data provides handles to all of the nodes attributes, only these // handles should be used when performing computations. // MStatus asMicrofacet_brdf::compute( const MPlug& plug, MDataBlock& block ) { // The plug parameter will allow us to determine which output attribute // needs to be calculated. // if( plug == aOutColor || plug == aOutTransparency || plug.parent() == aOutColor || plug.parent() == aOutTransparency ) { MStatus status; MFloatVector resultColor( 0.0, 0.0, 0.0 ); // Get surface shading parameters from input block // MFloatVector& surfaceNormal = block.inputValue( aNormalCamera, &status ).asFloatVector(); CHECK_MSTATUS( status ); MFloatVector& surfaceColor = block.inputValue( aColor, &status ).asFloatVector(); CHECK_MSTATUS( status ); MFloatVector& incandescence = block.inputValue( aIncandescence, &status ).asFloatVector(); CHECK_MSTATUS( status ); float diffuseReflectivity = block.inputValue( aDiffuseReflectivity, &status ).asFloat(); CHECK_MSTATUS( status ); // float translucenceCoeff = block.inputValue( aTranslucenceCoeff, // &status ).asFloat(); // CHECK_MSTATUS( status ); // Get light list // MArrayDataHandle lightData = block.inputArrayValue( aLightData, &status ); CHECK_MSTATUS( status ); int numLights = lightData.elementCount( &status ); CHECK_MSTATUS( status ); // Calculate the effect of the lights in the scene on the color // // Iterate through light list and get ambient/diffuse values // for( int count=1; count <= numLights; count++ ) { // Get the current light out of the array // MDataHandle currentLight = lightData.inputValue( &status ); CHECK_MSTATUS( status ); // Get the intensity of that light // MFloatVector& lightIntensity = currentLight.child( aLightIntensity ).asFloatVector(); // Find ambient component // if ( currentLight.child( aLightAmbient ).asBool() ) { resultColor += lightIntensity; } // Find diffuse component // if ( currentLight.child( aLightDiffuse ).asBool() ) { MFloatVector& lightDirection = currentLight.child( aLightDirection ).asFloatVector(); float cosln = lightDirection * surfaceNormal; if ( cosln > 0.0f ) { resultColor += lightIntensity * ( cosln * diffuseReflectivity ); } } // Advance to the next light. // if ( count < numLights ) { status = lightData.next(); CHECK_MSTATUS( status ); } } // Factor incident light with surface color and add incandescence // resultColor[0] = resultColor[0] * surfaceColor[0] + incandescence[0]; resultColor[1] = resultColor[1] * surfaceColor[1] + incandescence[1]; resultColor[2] = resultColor[2] * surfaceColor[2] + incandescence[2]; // Set ouput color attribute // if ( plug == aOutColor || plug.parent() == aOutColor ) { // Get the handle to the attribute // MDataHandle outColorHandle = block.outputValue( aOutColor, &status ); CHECK_MSTATUS( status ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; // Set the output value outColorHandle.setClean(); // Mark the output value as clean } // Set ouput transparency // if ( plug == aOutTransparency || plug.parent() == aOutTransparency ) { MFloatVector& transparency = block.inputValue( aInTransparency, &status ).asFloatVector(); CHECK_MSTATUS( status ); // Get the handle to the attribute // MDataHandle outTransHandle = block.outputValue( aOutTransparency, &status ); CHECK_MSTATUS( status ); MFloatVector& outTrans = outTransHandle.asFloatVector(); outTrans = transparency; // Set the output value outTransHandle.setClean(); // Mark the output value as clean } } else { return( MS::kUnknownParameter ); // We got an unexpected plug } return( MS::kSuccess ); }
// // DESCRIPTION: /////////////////////////////////////////////////////// MStatus PhongNode::compute( const MPlug& plug, MDataBlock& block ) { 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(); // use for raytracing api enhancement below MFloatVector point = cameraPosition; MFloatVector normal = surfaceNormal; MFloatVector& surfaceColor = block.inputValue( aColor ).asFloatVector(); MFloatVector& incandescence = block.inputValue( aIncandescence ).asFloatVector(); float diffuseReflectivity = block.inputValue( aDiffuseReflectivity ).asFloat(); // float translucenceCoeff = block.inputValue( aTranslucenceCoeff ).asFloat(); // User-defined Reflection Color Gain float reflectGain = block.inputValue( aReflectGain ).asFloat(); // Phong shading attributes float power = block.inputValue( aPower ).asFloat(); float spec = block.inputValue( aSpecularity ).asFloat(); float specularR, specularG, specularB; float diffuseR, diffuseG, diffuseB; diffuseR = diffuseG = diffuseB = specularR = specularG = specularB = 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(); // Find the blind data void*& blindData = currentLight.child( aLightBlindData ).asAddr(); // find ambient component if( currentLight.child(aLightAmbient).asBool() ) { diffuseR += lightIntensity[0]; diffuseG += lightIntensity[1]; diffuseB += lightIntensity[2]; } MFloatVector& lightDirection = currentLight.child(aLightDirection).asFloatVector(); if ( blindData == NULL ) { // find diffuse and specular component if( currentLight.child(aLightDiffuse).asBool() ) { 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 ); } CHECK_MSTATUS( cameraPosition.normalize() ); if( cosln > 0.0f ) // calculate only if facing light { float RV = ( ( (2*surfaceNormal) * cosln ) - lightDirection ) * cameraPosition; if( RV > 0.0 ) RV = 0.0; 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; } } } else { float cosln = MRenderUtil::diffuseReflectance( blindData, lightDirection, point, surfaceNormal, true ); if( cosln > 0.0f ) // calculate only if facing light { diffuseR += lightIntensity[0] * ( cosln * diffuseReflectivity ); diffuseG += lightIntensity[1] * ( cosln * diffuseReflectivity ); diffuseB += lightIntensity[2] * ( cosln * diffuseReflectivity ); } CHECK_MSTATUS ( cameraPosition.normalize() ); if ( currentLight.child(aLightSpecular).asBool() ) { MFloatVector specLightDirection = lightDirection; MDataHandle directionH = block.inputValue( aRayDirection ); MFloatVector direction = directionH.asFloatVector(); float lightAttenuation = 1.0; specLightDirection = MRenderUtil::maximumSpecularReflection( blindData, lightDirection, point, surfaceNormal, direction ); lightAttenuation = MRenderUtil::lightAttenuation( blindData, point, surfaceNormal, false ); // Are we facing the light if ( specLightDirection * surfaceNormal > 0.0f ) { float power2 = block.inputValue( aPower ).asFloat(); MFloatVector rv = 2 * surfaceNormal * ( surfaceNormal * direction ) - direction; float s = spec * powf( rv * specLightDirection, power2 ); specularR += lightIntensity[0] * s * lightAttenuation; specularG += lightIntensity[1] * s * lightAttenuation; specularB += lightIntensity[2] * s * lightAttenuation; } } } if( !lightData.next() ) break; } // factor incident light with surface color and add incandescence resultColor[0] = ( diffuseR * surfaceColor[0] ) + specularR + incandescence[0]; resultColor[1] = ( diffuseG * surfaceColor[1] ) + specularG + incandescence[1]; resultColor[2] = ( diffuseB * surfaceColor[2] ) + specularB + incandescence[2]; // add the reflection color if (reflectGain > 0.0) { MStatus status; // required attributes for using raytracer // origin, direction, sampler, depth, and object id. // MDataHandle originH = block.inputValue( aRayOrigin, &status); MFloatVector origin = originH.asFloatVector(); MDataHandle directionH = block.inputValue( aRayDirection, &status); MFloatVector direction = directionH.asFloatVector(); MDataHandle samplerH = block.inputValue( aRaySampler, &status); void*& samplerPtr = samplerH.asAddr(); MDataHandle depthH = block.inputValue( aRayDepth, &status); short depth = depthH.asShort(); MDataHandle objH = block.inputValue( aObjectId, &status); void*& objId = objH.asAddr(); MFloatVector reflectColor; MFloatVector reflectTransparency; MFloatVector& triangleNormal = block.inputValue( aTriangleNormalCamera ).asFloatVector(); // compute reflected ray MFloatVector l = -direction; float dot = l * normal; if( dot < 0.0 ) dot = -dot; MFloatVector refVector = 2 * normal * dot - l; // reflection ray float dotRef = refVector * triangleNormal; if( dotRef < 0.0 ) { const float s = 0.01f; MFloatVector mVec = refVector - dotRef * triangleNormal; mVec.normalize(); refVector = mVec + s * triangleNormal; } CHECK_MSTATUS ( refVector.normalize() ); status = MRenderUtil::raytrace( point, // origin refVector, // direction objId, // object id samplerPtr, // sampler info depth, // ray depth reflectColor, // output color and transp reflectTransparency); // add in the reflection color resultColor[0] += reflectGain * (reflectColor[0]); resultColor[1] += reflectGain * (reflectColor[1]); resultColor[2] += reflectGain * (reflectColor[2]); } // set ouput color attribute MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; outColorHandle.setClean(); return MS::kSuccess; }
MStatus anisotropicShaderNode::compute( const MPlug& plug, MDataBlock& block ) { if ((plug == aOutColor) || (plug.parent() == aOutColor)) { MFloatVector resultColor(0.0,0.0,0.0); MFloatVector diffuseColor( 0.0,0.0,0.0 ); MFloatVector specularColor( 0.0,0.0,0.0 ); MFloatVector ambientColor( 0.0,0.0,0.0 ); // get matrix MFloatMatrix& matrixOToW = block.inputValue( aMatrixOToW ).asFloatMatrix(); MFloatMatrix& matrixWToC = block.inputValue( aMatrixWToC ).asFloatMatrix(); // spin scratch around this vector (in object space ) MFloatVector& A = block.inputValue( aAxesVector ).asFloatVector(); A.normalize(); // spin scratch around this vector (in world space ) MFloatVector wa = A * matrixOToW; wa.normalize(); // spin scratch around this vector (in camera space ) MFloatVector ca = wa * matrixWToC; ca.normalize(); MFloatVector& surfacePoint = block.inputValue( aPointCamera ).asFloatVector(); // get sample surface shading parameters MFloatVector& N = block.inputValue( aNormalCamera ).asFloatVector(); MFloatVector& surfaceColor = block.inputValue( aColor ).asFloatVector(); float diffuseReflectivity = block.inputValue( aDiffuseReflectivity ).asFloat(); float specularCoeff = block.inputValue( aSpecularCoeff ).asFloat(); // get light list MArrayDataHandle lightData = block.inputArrayValue( aLightData ); int numLights = lightData.elementCount(); // iterate through light list and get ambient/diffuse values for( int count=0; count < numLights; count++ ) { MDataHandle currentLight = lightData.inputValue(); MFloatVector& lightIntensity = currentLight.child( aLightIntensity ).asFloatVector(); MFloatVector& lightDirection = currentLight.child( aLightDirection ).asFloatVector(); // find ambient component if( currentLight.child(aLightAmbient).asBool()) { 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 ){ // 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; }
MStatus PtexColorNode::compute(const MPlug& plug, MDataBlock& block) { if( ( plug != aOutColor ) && ( plug.parent() != aOutColor ) ) { return MS::kUnknownParameter; } if ( m_ptex_cache == NULL ) { m_ptex_cache = PtexCache::create( 0, 1024 * 1024 ); } if ( m_ptex_cache && m_ptex_texture == 0 ) { MDataHandle fileNameHnd = block.inputValue( aPtexFileName ); MDataHandle filterTypeHnd = block.inputValue( aPtexFilterType ); MString fileNameStr = fileNameHnd.asString(); int filterTypeValue = filterTypeHnd.asInt(); const float &filterSize = block.inputValue( aPtexFilterSize ).asFloat(); if ( fileNameStr.length() ) { Ptex::String error; m_ptex_texture = m_ptex_cache->get( fileNameStr.asChar(), error ); } if ( m_ptex_texture == 0 ) { MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor.x = 1.0f; outColor.y = 0.0f; outColor.z = 1.0f; return MS::kSuccess; } m_ptex_num_channels = m_ptex_texture->numChannels(); PtexFilter::FilterType ptexFilterType = PtexFilter::f_point; switch ( filterTypeValue ) { case 0: ptexFilterType = PtexFilter::f_point; break; case 1: ptexFilterType = PtexFilter::f_bilinear; break; case 2: ptexFilterType = PtexFilter::f_box; break; case 3: ptexFilterType = PtexFilter::f_gaussian; break; case 4: ptexFilterType = PtexFilter::f_bicubic; break; case 5: ptexFilterType = PtexFilter::f_bspline; break; case 6: ptexFilterType = PtexFilter::f_catmullrom; break; case 7: ptexFilterType = PtexFilter::f_mitchell; break; } PtexFilter::Options opts( ptexFilterType, 0, filterSize ); m_ptex_filter = PtexFilter::getFilter( m_ptex_texture, opts ); } const float2 &uv = block.inputValue( aUVPos ).asFloat2(); const float2 &duv = block.inputValue( aUVSize ).asFloat2(); int f = (int)uv[ 0 ]; float u = uv[ 0 ] - (float)f; float v = uv[ 1 ]; float result[4]; m_critical_section.lock(); m_ptex_filter->eval( result, 0, m_ptex_num_channels, f, u, v, duv[ 0 ], 0, 0, duv[ 1 ] ); m_critical_section.unlock(); // set ouput color attribute MFloatVector resultColor( result[ 0 ], result[ 1 ], result[ 2 ] ); MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; outColorHandle.setClean(); return MS::kSuccess; }
/* This function gets called by Maya to evaluate the texture. */ MStatus shiftNode::compute( const MPlug& plug, MDataBlock& data ) { MStatus stat; if ((plug != aOutColor) && (plug.parent() != aOutColor)) return MS::kUnknownParameter; MDataHandle colorH; MFloatVector color; MDataHandle shiftH = data.inputValue( aShift, &stat); PERRORfail(stat, "compute getting shift attr"); bool shiftIt = shiftH.asBool(); MDataHandle distH = data.inputValue( aDist, &stat); PERRORfail(stat, "compute getting distance attr"); float distance = distH.asFloat(); MFloatVector clr; if ( shiftIt && distance != 0.0 ) { // first evaluate color at default sample posiiton clr = data.inputValue( aColor ).asFloatVector(); // uv is used by 2d textures // refPointCamera is used by 3d textures MDataHandle refPointCamH = data.inputValue( aRefPointCamera, &stat); PERRORfail(stat, "compute getting refPointCamera attr"); MFloatVector refPC = refPointCamH.asFloatVector(); // get current UV const float2 & oldUV = data.inputValue(aUv).asFloat2(); // shift and set the uv/refPointCamera values so // we can sample around the current uv/refPointCamera MDataHandle outUV = data.outputValue( aUv ); MDataHandle outPC = data.outputValue( aRefPointCamera ); outUV.set( oldUV[0]-distance, oldUV[1] ); outPC.set( refPC.x + distance, refPC.y + distance, refPC.z + distance); colorH = data.inputValue( aColor, &stat); // evaluate at new pos color = colorH.asFloatVector(); clr += color; outUV.set( oldUV[0]+distance, oldUV[1] ); outPC.set( refPC.x - distance, refPC.y + distance, refPC.z + distance); colorH = data.inputValue( aColor, &stat); // evaluate at new pos color = colorH.asFloatVector(); clr += color; outUV.set( oldUV[0], oldUV[1]-distance ); outPC.set( refPC.x + distance, refPC.y - distance, refPC.z + distance); colorH = data.inputValue( aColor, &stat); // evaluate at new pos color = colorH.asFloatVector(); clr += color; outUV.set( oldUV[0], oldUV[1]+distance ); outPC.set( refPC.x - distance, refPC.y - distance, refPC.z + distance); colorH = data.inputValue( aColor, &stat); // evaluate at new pos color = colorH.asFloatVector(); clr += color; clr /= 5.0; // average the colors from all locations // set sample data back to original values outUV.set( oldUV[0], oldUV[1] ); outPC.set( refPC.x, refPC.y, refPC.z ); } else { colorH = data.inputValue( aColor, &stat); clr = colorH.asFloatVector(); } MDataHandle outColorHandle = data.outputValue( aOutColor ); MFloatVector& oclr = outColorHandle.asFloatVector(); oclr = clr; outColorHandle.setClean(); return MS::kSuccess; }
MStatus liqSurfaceNode::compute( const MPlug& plug, MDataBlock& block ) { // outColor or individual R, G, B channel if( (plug == aOutColor) || (plug.parent() == aOutColor) || (plug == aOutTransparency) || (plug.parent() == aOutTransparency) ) { //cout <<"compute... "<<endl; // init shader MStatus status; MFloatVector theColor( 0.0f, 0.0f, 0.0f ); MFloatVector& cColor = block.inputValue(aColor).asFloatVector(); MFloatVector& cTrans = block.inputValue(aOpacity).asFloatVector(); MFloatVector& ctex = block.inputValue(aGLPreviewTexture).asFloatVector(); // exploit maya's free openGL preview if ( ctex != MFloatVector( -1.0, -1.0, -1.0 ) ) theColor = ctex; else theColor = cColor; MFloatVector resultColor( 0.0, 0.0, 0.0 ); MFloatVector resultTrans( cTrans ); // lambert calc ------------------- bool& ignoreLights = block.inputValue( aMayaIgnoreLights, &status ).asBool(); float& Ka = block.inputValue( aMayaKa, &status ).asFloat(); float& Kd = block.inputValue( aMayaKd, &status ).asFloat(); // get surface normal MFloatVector& surfaceNormal = block.inputValue( aNormalCamera, &status ).asFloatVector(); CHECK_MSTATUS( status ); if ( ignoreLights ) { MFloatVector cam( 0.0, 0.0, 1.0 ); float cosln = cam * surfaceNormal; if ( cosln > 0.0f ) { float diff = cosln * cosln * Kd + Ka; resultColor = diff * theColor; } } else { // Get light list MArrayDataHandle lightData = block.inputArrayValue( aLightData, &status ); CHECK_MSTATUS( status ); int numLights = lightData.elementCount( &status ); CHECK_MSTATUS( status ); // Iterate through light list and get ambient/diffuse values for( int count=1; count <= numLights; count++ ) { // Get the current light out of the array MDataHandle currentLight = lightData.inputValue( &status ); CHECK_MSTATUS( status ); // Get the intensity of that light MFloatVector& lightIntensity = currentLight.child( aLightIntensity ).asFloatVector(); // Find ambient component if ( currentLight.child( aLightAmbient ).asBool() ) { resultColor += lightIntensity; } // Find diffuse component if ( currentLight.child( aLightDiffuse ).asBool() ) { MFloatVector& lightDirection = currentLight.child( aLightDirection ).asFloatVector(); float cosln = lightDirection * surfaceNormal; if ( cosln > 0.0f ) resultColor += lightIntensity * cosln * Kd ; } // Advance to the next light. if ( count < numLights ) { status = lightData.next(); CHECK_MSTATUS( status ); } } resultColor[0] *= theColor[0]; resultColor[1] *= theColor[1]; resultColor[2] *= theColor[2]; } resultTrans[0] = ( 1 - resultTrans[0] ); resultTrans[1] = ( 1 - resultTrans[1] ); resultTrans[2] = ( 1 - resultTrans[2] ); // set ouput color attribute MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; outColorHandle.setClean(); MDataHandle outTransHandle = block.outputValue( aOutTransparency ); MFloatVector& outTrans = outTransHandle.asFloatVector(); outTrans = resultTrans; outTransHandle.setClean(); } else return MS::kUnknownParameter; return MS::kSuccess; }
MStatus MG_dotProduct::compute(const MPlug& plug,MDataBlock& dataBlock) { MStatus returnStatus; if ((plug==dotProductA)|| (plug==dotProductMax)|| (plug==proj1on2)|| (plug==proj2on1)|| (plug==angleInBetweenAttr)|| (plug==angleX)|| (plug==angleY)|| (plug==angleZ)) /*get time */ { //creating handles to the input values MDataHandle vector1DataH = dataBlock.inputValue(vector1); MFloatPoint vector1V = vector1DataH.asFloatVector(); MDataHandle vector2DataH = dataBlock.inputValue(vector2); MFloatPoint vector2V = vector2DataH.asFloatVector(); MDataHandle xAxisH = dataBlock.inputValue(projAxisX); MFloatPoint xAxisData = xAxisH.asFloatVector(); MDataHandle yAxisH = dataBlock.inputValue(projAxisY); MFloatPoint yAxisData = yAxisH.asFloatVector(); MDataHandle zAxisH = dataBlock.inputValue(projAxisZ); MFloatPoint zAxisData = zAxisH.asFloatVector(); MDataHandle normData = dataBlock.inputValue(normalize); bool norm =normData.asBool(); //Creating some neededs variables float dotResult; // variable that will hold the dot product result float maxValue; //variable that will hold the dot product max value float distance1; // variable that will hold the vector 1 lenght float distance2; //variable that will hold the vector 2 lenght float angleDeg; //variable that will hold the angle inbetween the two vectors //float cosRad ; //variable that will hold the cosine value in radiants //Dot product math float vec1Array[3] = {vector1V[0],vector1V[1],vector1V[2]}; vector <float> vec1 = makeVector(vec1Array) ; float vec2Array[3] = {vector2V[0],vector2V[1],vector2V[2]}; vector <float> vec2 = makeVector(vec2Array) ; dotResult = vecDotProduct(vec1,vec2); distance1 = vectorLength(vec1); distance2 = vectorLength(vec2); maxValue = distance1*distance2; if (norm == 1) { if (maxValue ==0) { dotResult=0; }else{ dotResult = dotResult/maxValue; } } //Projection v2 on v1 float projV2=0; //variable that will hold the value projection of v2 projected on v1 vector <float> v1Norm; // variable that will hold the normalized v1 vector vector<float> v2Vec; // variable that will hold the projected vector if (distance1 != 0) { projV2 = projVector(vec2,vec1); v1Norm = normVector(vec1); v2Vec = scalarVector(v1Norm,projV2); }else{ //initialize the vector as 0 0 0 float zeroVec2[3]= {0,0,0}; v2Vec=makeVector(zeroVec2); } //Projection v1 on v2 float projV1=0; //variable that will hold the value projection of v1 projected on v2 vector <float> v2Norm;// variable that will hold the normalized v2 vector vector <float> v1Vec;// variable that will hold the projected vector if (distance2 != 0) { projV1 = projVector(vec1,vec2); v2Norm = normVector(vec2); v1Vec = scalarVector(v2Norm,projV1); }else{ //initialize the vector as 0 0 0 float zeroVec1[3]= {0,0,0}; v1Vec=makeVector(zeroVec1); } //Angle in between if ((distance2*distance1)!=0) { angleDeg=angleInbetweenVector(vec1,vec2); }else{ angleDeg=0; } //Angle inbetween splitted into X,Y,Z world rotation //float dotResultV1X; // splitting inbetween angle into X Y Z rotation //converting axis from node into vector class float xAxisArray[3] = {xAxisData[0],xAxisData[1],xAxisData[2]}; vector<float> xAxisVec = makeVector(xAxisArray) ; float yAxisArray[3] = {yAxisData[0],yAxisData[1],yAxisData[2]}; vector<float> yAxisVec = makeVector(yAxisArray) ; float zAxisArray[3] = {zAxisData[0],zAxisData[1],zAxisData[2]}; vector<float> zAxisVec = makeVector(zAxisArray) ; float angleProjXYDeg=0 ; float angleProjYZDeg=0 ; float angleProjXZDeg=0 ; // angle Z vector<float> projectedV1; vector<float> projectedV2; projectedV1= projectVectorOnPlane(vec1,xAxisVec,yAxisVec); projectedV2= projectVectorOnPlane(vec2,xAxisVec,yAxisVec); angleProjXYDeg=angleInbetweenVector(projectedV1,projectedV2); // angle X projectedV1= projectVectorOnPlane(vec1,zAxisVec,yAxisVec); projectedV2= projectVectorOnPlane(vec2,zAxisVec,yAxisVec); angleProjYZDeg=angleInbetweenVector(projectedV1,projectedV2); // angle Y projectedV1= projectVectorOnPlane(vec1,zAxisVec,xAxisVec); projectedV2= projectVectorOnPlane(vec2,zAxisVec,xAxisVec); angleProjXZDeg=angleInbetweenVector(projectedV1,projectedV2); //Setting output values MDataHandle output = dataBlock.outputValue(dotProductA); MDataHandle outputMax = dataBlock.outputValue(dotProductMax); MDataHandle projV1Output = dataBlock.outputValue(proj1on2); MDataHandle projV2Output = dataBlock.outputValue(proj2on1); MDataHandle angleInBetweenOutput = dataBlock.outputValue(angleInBetweenAttr); MDataHandle angleXout = dataBlock.outputValue(angleX); MDataHandle angleYout = dataBlock.outputValue(angleY); MDataHandle angleZout = dataBlock.outputValue(angleZ); output.set(dotResult); outputMax.set(maxValue); projV1Output.set(v1Vec[0],v1Vec[1],v1Vec[2]); projV2Output.set(v2Vec[0],v2Vec[1],v2Vec[2]); angleInBetweenOutput.set(angleDeg); angleXout.set(angleProjYZDeg); angleYout.set(angleProjXZDeg); angleZout.set(angleProjXYDeg); //SetClean tells maya attribute is update outputMax.setClean(); output.setClean(); projV1Output.setClean(); projV2Output.setClean(); angleInBetweenOutput.setClean(); angleXout.setClean(); angleYout.setClean(); angleZout.setClean(); } return MS::kSuccess; }
MStatus OnbShader::compute(const MPlug& plug, MDataBlock& block) { // Sanity check if (plug != aOutColor && plug.parent() != aOutColor && plug != aOutTransparency && plug.parent() != aOutTransparency) { return MS::kUnknownParameter; } // Note that this currently only implements the diffuse portion of the // shader and ignores specular. The diffuse portion is the Oren-Nayar // computation from: // Engel, Wolfgang et al. Programming Vertex, Geometry, and Pixel Shaders // http://content.gpwiki.org/index.php/D3DBook:(Lighting)_Oren-Nayar // Further extensions could be added to this compute method to include // the intended Blinn specular component as well as ambient and // incandescence components. // See the VP2 fragment-based implementation in onbShaderOverride for the // full shader. MStatus status; MFloatVector resultColor(0.0f, 0.0f, 0.0f); MFloatVector resultTransparency(0.0f, 0.0f, 0.0f); // Get surface shading parameters from input block const MFloatVector& surfaceColor = block.inputValue(aColor, &status).asFloatVector(); CHECK_MSTATUS(status); const float roughness = block.inputValue(aRoughness, &status).asFloat(); CHECK_MSTATUS(status); const MFloatVector& transparency = block.inputValue(aTransparency, &status).asFloatVector(); CHECK_MSTATUS(status); const MFloatVector& surfaceNormal = block.inputValue(aNormalCamera, &status).asFloatVector(); CHECK_MSTATUS(status); const MFloatVector& rayDirection = block.inputValue(aRayDirection).asFloatVector(); const MFloatVector viewDirection = -rayDirection; // Pre-compute some values that do not vary with lights const float NV = viewDirection*surfaceNormal; const float acosNV = acosf(NV); const float roughnessSq = roughness*roughness; const float A = 1.0f - 0.5f*(roughnessSq/(roughnessSq + 0.57f)); const float B = 0.45f*(roughnessSq/(roughnessSq + 0.09f)); // Get light list MArrayDataHandle lightData = block.inputArrayValue(aLightData, &status); CHECK_MSTATUS(status); const int numLights = lightData.elementCount(&status); CHECK_MSTATUS(status); // Iterate through light list and get ambient/diffuse values for (int count=1; count<=numLights; count++) { // Get the current light MDataHandle currentLight = lightData.inputValue(&status); CHECK_MSTATUS(status); // Find diffuse component if (currentLight.child(aLightDiffuse).asBool()) { // Get the intensity and direction of that light const MFloatVector& lightIntensity = currentLight.child(aLightIntensity).asFloatVector(); const MFloatVector& lightDirection = currentLight.child(aLightDirection).asFloatVector(); // Compute the diffuse factor const float NL = lightDirection*surfaceNormal; const float acosNL = acosf(NL); const float alpha = std::max(acosNV, acosNL); const float beta = std::min(acosNV, acosNL); const float gamma = (viewDirection - (surfaceNormal*NV)) * (lightDirection - (surfaceNormal*NL)); const float C = sinf(alpha)*tanf(beta); const float factor = std::max(0.0f, NL)*(A + B*std::max(0.0f, gamma)*C); // Add to result color resultColor += lightIntensity*factor; } // Advance to the next light. if (count < numLights) { status = lightData.next(); CHECK_MSTATUS(status); } } // Factor incident light with surface color resultColor[0] = resultColor[0]*surfaceColor[0]; resultColor[1] = resultColor[1]*surfaceColor[1]; resultColor[2] = resultColor[2]*surfaceColor[2]; // Set ouput color attribute if (plug == aOutColor || plug.parent() == aOutColor) { // Get the handle to the attribute MDataHandle outColorHandle = block.outputValue(aOutColor, &status); CHECK_MSTATUS(status); MFloatVector& outColor = outColorHandle.asFloatVector(); // Set the result and mark it clean outColor = resultColor; outColorHandle.setClean(); } // Set ouput transparency if (plug == aOutTransparency || plug.parent() == aOutTransparency) { // Get the handle to the attribute MDataHandle outTransHandle = block.outputValue(aOutTransparency, &status); CHECK_MSTATUS(status); MFloatVector& outTrans = outTransHandle.asFloatVector(); // Set the result and mark it clean outTrans = transparency; outTransHandle.setClean(); } return MS::kSuccess; }
// // DESCRIPTION: /////////////////////////////////////////////////////// MStatus VolumeNode::compute(const MPlug& plug, MDataBlock& block ) { if ((plug != aOutColor) && (plug.parent() != aOutColor) && (plug != aOutTransparency) && (plug.parent() != aOutTransparency)) return MS::kUnknownParameter; MFloatVector& InputColor = block.inputValue( aColor ).asFloatVector(); float Distance = block.inputValue( aInputValue ).asFloat(); MFloatVector& FarCamera = block.inputValue( aFarPointC ).asFloatVector(); MFloatVector& FarObject = block.inputValue( aFarPointO ).asFloatVector(); MFloatVector& FarWorld = block.inputValue( aFarPointW ).asFloatVector(); MFloatVector& PointCam = block.inputValue( aPointC ).asFloatVector(); MFloatVector& PointObj = block.inputValue( aPointO ).asFloatVector(); MFloatVector& PointWor = block.inputValue( aPointW ).asFloatVector(); bool Camera = block.inputValue( aToggleCamera ).asBool(); bool Object = block.inputValue( aToggleObject ).asBool(); bool World = block.inputValue( aToggleWorld ).asBool(); MFloatVector interval(0.0,0.0,0.0); if (Camera) { interval = FarCamera - PointCam; } if (Object) { interval = FarObject - PointObj; } if (World) { interval = FarWorld - PointWor; } double value,dist; if ((value = ((interval[0]*interval[0]) + (interval[1]*interval[1]) + (interval[2]*interval[2])) )) { dist = sqrt ( value ); } else dist = 0.0; MFloatVector resultColor(0.0,0.0,0.0); if (dist <= Distance) { resultColor[0] = InputColor[0]; resultColor[1] = InputColor[1]; resultColor[2] = InputColor[2]; } // set ouput color attribute MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; outColorHandle.setClean(); // set output transparency MFloatVector transparency(resultColor[2],resultColor[2],resultColor[2]); MDataHandle outTransHandle = block.outputValue( aOutTransparency ); MFloatVector& outTrans = outTransHandle.asFloatVector(); outTrans = transparency; outTransHandle.setClean( ); MDataHandle outAlphaHandle = block.outputValue( aOutAlpha ); float& outAlpha = outAlphaHandle.asFloat(); outAlpha = resultColor[2]; outAlphaHandle.setClean( ); return MS::kSuccess; }
// Main entry // virtual MStatus compute( const MPlug& plug, MDataBlock& dataBlock ) { // enable this node or not if ( dataBlock.inputValue(aEnable).asBool() == false ) return MS::kSuccess; // execution when rendering if ( dataBlock.inputValue(aEnableRender).asBool() == true ) if ( MRenderUtil::mayaRenderState() == MRenderUtil::kNotRendering ) //MGlobal::displayInfo( "not rendering"); return MS::kSuccess; // Execution when the specified output attributes need to be updated if ( !( plug == aOutColor || plug == aUVCoord ) ) return MS::kSuccess; // Check if the aShape is connected if ( isPlugConnect(aShape) != true ) return MS::kSuccess; // From each pixel, sample required info, like point world, UV, .etc. // // 01. get W-space point MDataHandle PointWorldHandle = dataBlock.inputValue( aPointWorld ); MFloatVector pointWorld = PointWorldHandle.asFloatVector(); float uv[2]; // input shape is NURBS Surface // if ( dataBlock.inputValue( aShape ).type() == MFnData::kNurbsSurface ) { // 02. get each UV for the overlaped area // MObject nurbsShape = dataBlock.inputValue(aShape).asNurbsSurface(); getOverlapUVbyNurbs( nurbsShape, pointWorld, uv ); } // input shape is Mesh else if ( dataBlock.inputValue( aShape ).type() == MFnData::kMesh ) { // 02. get each UV for the overlaped area // MObject meshShape = dataBlock.inputValue(aShape).asMeshTransformed(); //W-space mesh getOverlapUVbyMesh( meshShape, pointWorld, uv ); } // if inpute object is neither Mesh nor Nurbs else { return MS::kSuccess; } MFloatVector resultColor( 0.0, 0.0, 0.0 ); // run super sampling function if ( dataBlock.inputValue(aIsSpuersampling).asBool() == true ) { float offsetUV = dataBlock.inputValue(aOffsetSample).asFloat(); int2& filterSize = dataBlock.inputValue(aFilterSize).asInt2(); int x_width = filterSize[0]; int y_width = filterSize[1]; //cout << "super!" << endl; resultColor = doSupersampling( dataBlock, aUVCoord, aColor, uv, x_width, y_width, offsetUV ); } else { // 1. u, v coordinate // 2. get get color by uv dataBlock.outputValue(aUVCoord).set( uv[0], uv[1] ); resultColor = dataBlock.inputValue(aColor).asFloatVector(); } dataBlock.outputValue(aOutColor).set(resultColor); return MS::kSuccess; }