/*///////////////////////////////////////////////////////////////// jpMayaToMia author: Jon Parker parker.jon@gmail.com created May 4, 2008 usage: jpMayaToMia() jpMayaToMia_selected() return value: jpMayaToMia -> mia_material description: converts a maya blinn, phong, phongE, lambert or anisotropic material to a mia_material shader. This does some rough guesswork on converting some of the parameters and is often not 100% visually identical to the original in its result. /////////////////////////////////////////////////////////////////*/ // returns nodes of type "type" in input list proc string[] jpFilterNodeType(string $type, string $inputList[]) { string $outputNodeList[]; for ($input in $inputList) { string $inputType = `nodeType $input`; string $inputClass[] =`getClassification $inputType`; // do this to a type node if ($inputType == $type) { $outputNodeList[size($outputNodeList)] = $input; } // do this to non-shader object else if ($inputType == "transform" || $inputType == "mesh" || $inputType == "nurbsSurface") { string $shapeList[] = `listRelatives -ad -pa -type "surfaceShape" $input`; $shapeList = stringArrayRemoveDuplicates($shapeList); for ($shape in $shapeList) { string $sg[] = `listConnections -type "shadingEngine" $shape`; if (($sg[0] != "initialShadingGroup") && (size($sg))) { string $shadingNetwork[] = `listHistory -pdo 1 $sg[0]`; if (size($shadingNetwork)) { for ($outputNode in $shadingNetwork) { if (`nodeType $outputNode` == $type) { $outputNodeList[size($outputNodeList)] = $outputNode; } } } } } } // ...or do this to a shader else { string $shadingNetwork[] = `listHistory -pdo 1 $input`; if (size($shadingNetwork)) { for ($outputNode in $shadingNetwork) { if (`nodeType $outputNode` == $type) { $outputNodeList[size($outputNodeList)] = $outputNode; } } } } } $outputNodeList = stringArrayRemoveDuplicates($outputNodeList); return $outputNodeList; } proc string createAndPrepareMia(string $shader) { string $mia = `shadingNode -asShader -n ($shader+"_mia") mia_material_x`; setAttr ".brdf_0_degree_refl" 1; setAttr ".skip_inside_refl" 0; setAttr ".refr_ior" 1.0 ; setAttr ".brdf_conserve_energy" off ; warning ("createAndPrepareMia: "+$mia+": 'brdf conserve energy' is turned off for visual equality with the Maya shader. You should turn this back on for better physical accuracy."); return $mia; } proc copyAttribute(string $src, string $dest) { string $srcSplit[]; tokenize $src "." $srcSplit; string $srcNode = $srcSplit[0]; string $srcAttr = $srcSplit[1]; string $srcScalar[] = `listAttr -s $src`; // print $srcScalar; string $destSplit[]; tokenize $dest "." $destSplit; string $destNode = $destSplit[0]; string $destAttr = $destSplit[1]; string $destScalar[] = `listAttr -s $dest`; // print $destScalar; if (`attributeQuery -n $srcNode -uac $srcAttr` && `connectionInfo -id $src`) { string $inputNode = `connectionInfo -sfd $src`; connectAttr -f $inputNode $dest; } else { for ($i = 0; $i < size($srcScalar); $i++) { if (`connectionInfo -id ($srcNode+"."+$srcScalar[$i])`) { string $inputNode = `connectionInfo -sfd ($srcNode+"."+$srcScalar[$i])`; connectAttr -f $inputNode ($destNode+"."+$destScalar[$i]); } else { float $srcValue = `getAttr ($srcNode+"."+$srcScalar[$i])`; setAttr ($destNode+"."+$destScalar[$i]) $srcValue; } } } } global proc copyCommonAttributesToMiaMaterial(string $shader, string $mia) { // color copyAttribute(($shader+".color"), ($mia+".diffuse")); // transparency // only set it up if we have transparency float $trans[] = `getAttr ($shader+".transparency")`; if ((`connectionInfo -id ($shader+".transparency")`) || ($trans[0] || $trans[1] || $trans[2] !=0)) { print $trans; setAttr ($mia+".transparency") 1; copyAttribute(($shader+".transparency"), ($mia+".refr_color")); } // ambient color setAttr ($mia+".ao_on") true; setAttr ($mia+".ao_samples") 0; setAttr ($mia+".ao_distance") 0; setAttr ($mia+".ao_do_details") 0; setAttr ($mia+".ao_dark") -type double3 1 1 1; copyAttribute(($shader+".ambientColor"), ($mia+".ao_ambient")); // incandescence copyAttribute(($shader+".incandescence"), ($mia+".additional_color")); // bump mapping if (`connectionInfo -id ($shader+".normalCamera")`) { string $srcBump = `connectionInfo -sfd ($shader+".normalCamera")`; connectAttr -f $srcBump ($mia+".overall_bump"); } // diffuse attr copyAttribute(($shader+".diffuse"), ($mia+".diffuse_weight")); // translucence if (`getAttr ($shader+".translucence")` != 0) { setAttr ($mia+".refr_translucency") on; copyAttribute(($shader+".color"), ($mia+".refr_trans_color")); copyAttribute(($shader+".translucence"), ($mia+".refr_trans_weight")); // multiply it by the transparency... if (`getAttr ($mia+".transparency")` != 0) { // set translucency weight string $rev = `shadingNode -asUtility -n ($mia+"_refr_trans_weight_rev") reverse`; string $lum = `shadingNode -asUtility -n ($mia+"_refr_trans_weight_lum") luminance`; copyAttribute(($mia+".refr_color"), ($rev+".input")); connectAttr -f ($rev+".output") ($lum+".value"); connectAttr -f ($lum+".outValue") ($mia+".refr_trans_weight"); // set translucency color string $mult = `shadingNode -asUtility -n ($mia+"_refr_color_mult") multiplyDivide`; copyAttribute(($shader+".color"), ($mult+".input1")); copyAttribute(($shader+".translucence"), ($mult+".input2X")); copyAttribute(($shader+".translucence"), ($mult+".input2Y")); copyAttribute(($shader+".translucence"), ($mult+".input2Z")); connectAttr -f ($mult+".output") ($mia+".refr_trans_color"); // set transparency color string $rgbIn = `shadingNode -asUtility -n ($mia+"_refr_color_rgbIn") rgbToHsv`; string $setRange = `shadingNode -asUtility -n ($mia+"_refr_color_setRange") setRange`; setAttr ".minZ" 1; setAttr ".maxX" 1; setAttr ".maxY" 1; setAttr ".maxZ" 1; setAttr ".oldMaxX" 1; setAttr ".oldMaxY" 1; setAttr ".oldMaxZ" 1; string $rgbOut = `shadingNode -asUtility -n ($mia+"_refr_color_rgbOut") hsvToRgb`; copyAttribute(($shader+".transparency"), ($rgbIn+".inRgb")); connectAttr -f ($rgbIn+".outHsv") ($setRange+".value") ; connectAttr -f ($setRange+".outValue") ($rgbOut+".inHsv") ; connectAttr -f ($rgbOut+".outRgb") ($mia+".refr_color") ; } else { copyAttribute(($shader+".translucence"), ($mia+".transparency")); setAttr ($mia+".refr_trans_weight") 1; } } // raytracing if (`getAttr ($shader+".refractions")` == 1) { copyAttribute(($shader+".refractiveIndex"), ($mia+".refr_ior")); copyAttribute(($shader+".refractionLimit"), ($mia+".refr_depth")); if (`getAttr ($shader+".lightAbsorbance")` != 0) { setAttr ($mia+".refr_falloff_on") true; copyAttribute(($shader+".lightAbsorbance"), ($mia+".refr_falloff_dist")); } } // mental ray // irradiance if (`connectionInfo -id ($shader+".miIrradianceColor")`) { string $input = `connectionInfo -sfd ($shader+".miIrradianceColor")`; string $lumaNode = `shadingNode -asUtility luminance`; connectAttr -f $input ($lumaNode+".value") ; connectAttr -f ($lumaNode+".outValue") ($mia+".indirect_multiplier"); } else { float $irrad[] = `getAttr ($shader+".miIrradianceColor")`; float $indMult = ($irrad[0]+$irrad[1]+$irrad[2])/3; setAttr ($mia+".indirect_multiplier") $indMult; } // refraction blur if (`connectionInfo -id ($shader+".miRefractionBlur")`) { string $input = `connectionInfo -sfd ($shader+".miRefractionBlur")`; string $mult = `shadingNode -asUtility -n ($mia+"_refr_gloss_mult") multiplyDivide`; setAttr ".input2X" 0.1 ; string $rev = `shadingNode -asUtility -n ($mia+"_refr_gloss_rev") reverse`; connectAttr -f $input ($mult+".input1X"); connectAttr -f ($mult+".outputX") ($rev+".inputX") ; connectAttr -f ($rev+".outputX") ($mia+".refr_gloss") ; } else { float $refrBlur = `getAttr ($shader+".miRefractionBlur")`; if ($refrBlur != 0) setAttr ($mia+".refr_gloss") (1-($refrBlur*.1)) ; } } proc copyLambertAttributesToMiaMaterial(string $shader, string $mia) { setAttr ($mia+".reflectivity") 0; } proc copyPhongAttributesToMiaMaterial(string $shader, string $mia) { if (`connectionInfo -id ($shader+".cosinePower")`) { string $input = `connectionInfo -sfd ($shader+".cosinePower")`; string $clamp = `shadingNode -asUtility -n ($mia+"_refl_gloss_clamp") clamp`; setAttr ".maxR" 100 ; string $mult = `shadingNode -asUtility -n ($mia+"_refl_gloss_mult") multiplyDivide`; setAttr ".input2X" 0.01 ; connectAttr -f $input ($clamp+".inputR") ; connectAttr -f ($clamp+".outputR") ($mult+".input1X") ; connectAttr -f ($mult+".outputX") ($mia+".refl_gloss") ; } else { float $cosine = `getAttr ($shader+".cosinePower")`; setAttr ($mia+".refl_gloss") (clamp(0, 100, $cosine)*.01); } copyAttribute(($shader+".specularColor"), ($mia+".refl_color")) ; copyAttribute(($shader+".reflectivity"), ($mia+".reflectivity")) ; copyAttribute(($shader+".reflectionLimit"), ($mia+".refl_depth")) ; } proc copyPhongEAttributesToMiaMaterial(string $shader, string $mia) { warning "copyPhongEAttributesToMiaMaterial: certain phongE material settings are weird and unsupported... set the reflection glossiness in the mia material to approximate phongE specular attributes."; copyAttribute(($shader+".specularColor"), ($mia+".refl_color")) ; copyAttribute(($shader+".reflectivity"), ($mia+".reflectivity")) ; copyAttribute(($shader+".reflectionLimit"), ($mia+".refl_depth")) ; } proc copyBlinnAttributesToMiaMaterial(string $shader, string $mia) { // figure out that inverse eccentricity thing... it's roughly worked out... if (`connectionInfo -id ($shader+".eccentricity")`) { string $input = `connectionInfo -sfd ($shader+".eccentricity")`; string $gamma = `shadingNode -asUtility -n ($mia+"_refl_gloss_gamma") gammaCorrect`; setAttr ".gammaX" 2.718 ; string $rev = `shadingNode -asUtility -n ($mia+"_refl_gloss_rev") reverse`; connectAttr -f $input ($gamma+".valueX") ; connectAttr -f ($gamma+".outValueX") ($rev+".inputX") ; connectAttr -f ($rev+".outputX") ($mia+".refl_gloss") ; } else { float $ecc = `getAttr ($shader+".eccentricity")`; float $thinger = 1-((exp($ecc)-.5) * .5); setAttr ($mia+".refl_gloss") (1-((exp($ecc)-.5) * .5)) ; } // let's put the specular roll-off into the forward-facing reflectivity of the mia... copyAttribute(($shader+".specularRollOff"), ($mia+".brdf_0_degree_refl")) ; // do the standard specular stuff copyAttribute(($shader+".specularColor"), ($mia+".refl_color")) ; copyAttribute(($shader+".reflectivity"), ($mia+".reflectivity")) ; copyAttribute(($shader+".reflectionLimit"), ($mia+".refl_depth")) ; } proc copyAnisoAttributesToMiaMaterial(string $shader, string $mia) { setAttr ($mia+".anisotropy_channel") -2 ; // get angle, see if it's mapped first if (`connectionInfo -id ($shader+".angle")`) { string $mult = `shadingNode -asUtility -n ($mia+"_anisotropy_rotation_mult") multiplyDivide`; setAttr ".operation" 2 ; setAttr ".input1Y" 720 ; copyAttribute(($shader+".angle"), ($mult+".input1X")); connectAttr -f ($mult+".outputX") ($mia+".anisotropy_rotation") ; } else { float $rotation = `getAttr ($shader+".angle")` / 720 ; setAttr ($mia+".anisotropy_rotation") $rotation ; } // divide the x and y aniso values to approximate the mia anisotropy if (`connectionInfo -id ($shader+".spreadX")` || `connectionInfo -id ($shader+".spreadY")`) { string $div = `shadingNode -asUtility -n ($mia+"_anisotropy_div") multiplyDivide`; setAttr ".operation" 2 ; copyAttribute(($shader+".spreadY"), ($div+".input1X")); copyAttribute(($shader+".spreadX"), ($div+".input1Y")); connectAttr -f ($div+".outputX") ($mia+".anisotropy"); } else { float $anisoValue = `getAttr ($shader+".spreadY")` / `getAttr ($shader+".spreadX")`; setAttr ($mia+".anisotropy") $anisoValue ; } // finally roughness if (`connectionInfo -id ($shader+".roughness")`) { string $inv = `shadingNode -asUtility -n ($mia+"_refl_gloss_inv") reverse`; copyAttribute ($shader+".roughness") ($inv+".inputX") ; connectAttr -f ($inv+".outputX") ($mia+".refl_gloss") ; } else { float $gloss = 1 - `getAttr ($shader+".roughness")` ; setAttr ($mia+".refl_gloss") $gloss ; } // figure out what to do with the anisotropic reflection attribute if (`getAttr ($shader+".anisotropicReflectivity")`) warning ("copyAnisoAttributesToMiaMaterial: "+$shader+": anisotropic reflectivity settings ignored."); copyAttribute(($shader+".specularColor"), ($mia+".refl_color")) ; copyAttribute(($shader+".reflectivity"), ($mia+".reflectivity")) ; copyAttribute(($shader+".reflectionLimit"), ($mia+".refl_depth")) ; } global proc string jpMayaToMia(string $shader) { string $mia = createAndPrepareMia($shader); copyCommonAttributesToMiaMaterial($shader, $mia); if (`nodeType $shader` == "lambert") copyLambertAttributesToMiaMaterial($shader, $mia); if (`nodeType $shader` == "phong") copyPhongAttributesToMiaMaterial($shader, $mia); if (`nodeType $shader` == "phongE") copyPhongEAttributesToMiaMaterial($shader, $mia); if (`nodeType $shader` == "blinn") copyBlinnAttributesToMiaMaterial($shader, $mia); if (`nodeType $shader` == "anisotropic") copyAnisoAttributesToMiaMaterial($shader, $mia); return $mia; } global proc jpMayaToMia_selected() { string $selection[] = `ls -sl`; string $shaderList[] ; string $lambertList[] = jpFilterNodeType("lambert", $selection) ; string $phongList[] = jpFilterNodeType("phong", $selection) ; string $phongEList[] = jpFilterNodeType("phongE", $selection); string $blinnList[] = jpFilterNodeType("blinn", $selection); string $anisoList[] = jpFilterNodeType("anisotropic", $selection); $shaderList = stringArrayCatenate($shaderList, $lambertList); $shaderList = stringArrayCatenate($shaderList, $phongList); $shaderList = stringArrayCatenate($shaderList, $phongEList); $shaderList = stringArrayCatenate($shaderList, $blinnList); $shaderList = stringArrayCatenate($shaderList, $anisoList); // print $shaderList ; for ($shader in $shaderList) { string $mia = jpMayaToMia($shader) ; string $sgList[] = `listConnections -type "shadingEngine" $shader`; for ($sg in $sgList) { string $miaSG[] = `duplicate -ic -n ($mia + "SG") $sg` ; string $shader = `connectionInfo -sfd ($miaSG[0]+".surfaceShader")`; disconnectAttr $shader ($miaSG[0]+".surfaceShader") ; connectAttr -f ($mia+".message") ($miaSG[0]+".miMaterialShader") ; connectAttr -f ($mia+".message") ($miaSG[0]+".miPhotonShader") ; connectAttr -f ($mia+".message") ($miaSG[0]+".miShadowShader") ; string $assignedObjectList[] = `sets -q $sg`; sets -e -fe $miaSG[0] $assignedObjectList ; } } }