glm::vec3 BidirectionalIntegrator::TraceRay(Ray r, unsigned int depth) { Intersection isx = intersection_engine->GetIntersection(r); if(isx.t < 0) return glm::vec3(0); else if(isx.object_hit->material->is_light_source) { return isx.object_hit->material->base_color * isx.texture_color; } glm::vec3 resultColor(0); for(Geometry* light : scene->lights) { std::vector<PathNode> eyePath = generateEyePath(r); std::vector<PathNode> lightPath = generateLightPath(light); if(!eyePath.empty() && !lightPath.empty()) { PathNode* node = &lightPath[0]; float lightPdf = light->RayPDF(node->isx,Ray(node->isx.point,node->dirIn_world)); glm::vec3 Le(0); if(lightPdf != 0) Le = light->material->base_color * light->material->intensity / lightPdf; glm::vec3 directWt(1.0f); for(int i=1;i<=eyePath.size();i++) { node = &eyePath[i-1]; Ray ray(light->transform.position(), - node->dirIn_world); resultColor += directWt * EstimateDirectLight(node->isx, ray, light) / WeightPath(i,0); directWt *= node->F * glm::abs(glm::dot(node->dirOut_world,node->isx.normal)) / node->pdf; for(int j=1;j<=lightPath.size();j++) { resultColor += Le * EvaluatePath(eyePath,i,lightPath,j) / WeightPath(i,j); } } } else { continue; } } return resultColor; }
// // DESCRIPTION: /////////////////////////////////////////////////////// MStatus DispNode::compute( const MPlug& plug, MDataBlock& block ) { if ((plug == aOutColor) || (plug.parent() == aOutColor) || (plug == aOutDisplacement)) { MFloatVector resultColor(0.0,0.0,0.0); MFloatVector& InputColor = block.inputValue( aColor ).asFloatVector(); float MultValue = block.inputValue( aInputValue ).asFloat(); resultColor = InputColor; float scalar = resultColor[0] + resultColor[1] + resultColor[2]; if (scalar != 0.0) { scalar /= 3.0; scalar *= MultValue; } // set ouput color attribute MDataHandle outColorHandle = block.outputValue( aOutColor ); MFloatVector& outColor = outColorHandle.asFloatVector(); outColor = resultColor; outColorHandle.setClean(); MDataHandle outDispHandle = block.outputValue( aOutDisplacement ); float& outDisp = outDispHandle.asFloat(); outDisp = scalar; outDispHandle.setClean( ); } else if ((plug == aOutTransparency) || (plug.parent() == aOutTransparency)) { // set output transparency to be opaque MFloatVector transparency(0.0,0.0,0.0); MDataHandle outTransHandle = block.outputValue( aOutTransparency ); MFloatVector& outTrans = outTransHandle.asFloatVector(); outTrans = transparency; outTransHandle.setClean( ); } else return MS::kUnknownParameter; return MS::kSuccess; }
Color FresnelTexture::getTextureColor(const Ray& ray, double u, double v, Vector& normal) const { Vector faceForwardNormal = Vector::faceForward(ray.Direction(), normal); double indexOfRefraction = this->indexOfRefraction; // If the ray is entering the geometry we must use the reciprocal of the index of refraction if (Vector::dotProduct(ray.Direction(), normal) > 0.0) { indexOfRefraction = 1.0 / indexOfRefraction; } double fresnelCoefficient = this->fresnel(ray.Direction(), faceForwardNormal, indexOfRefraction); Color resultColor(fresnelCoefficient, fresnelCoefficient, fresnelCoefficient); return resultColor; }
// The compute() method does the actual work of the node using the inputs // of the node to generate its output. // // 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 DynamicEnum::compute( const MPlug& plug, MDataBlock& block ) { // The plug parameter will allow us to determine which output attribute // needs to be calculated. // if( plug == aOutColor ) { MStatus status; MFloatVector resultColor( 0.0, 0.0, 0.0 ); } else { return( MS::kUnknownParameter ); // We got an unexpected plug } return( MS::kSuccess ); }
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; }
// 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; }
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 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; }