/// <summary> /// Return the file name for the given material node's parameter. /// </summary> /// <param name="session">Current session</param> /// <param name="nodeID">Material node ID</param> /// <param name="parmInfo">Parameter on material to query</param> /// <returns>Given parameter's string value</returns> internal static string GetTextureFileNameFromMaterialParam(HEU_SessionBase session, HAPI_NodeId nodeID, HAPI_ParmInfo parmInfo) { string textureFileName = "default_texture.png"; HAPI_StringHandle stringValue; string paramName = HEU_SessionManager.GetString(parmInfo.nameSH, session); if (session.GetParmStringValue(nodeID, paramName, 0, true, out stringValue)) { string paramStrValue = HEU_SessionManager.GetString(stringValue, session); // The returned string needs to be cleaned up: // eg. opdef:/Sop/testgeometry_pighead?lowres.jpg -> Sop_testgeometry_pighead_lowres.jpg textureFileName = paramStrValue; int lastColon = textureFileName.LastIndexOf(':'); if (lastColon > 0 && (lastColon + 1) < textureFileName.Length) { textureFileName = textureFileName.Substring(lastColon + 1); } // Remove starting / after removing :: above textureFileName = textureFileName.TrimStart('/'); textureFileName = textureFileName.Replace("?", "_"); textureFileName = textureFileName.Replace("/", "_"); // Filename is too long! Shorten it! int lastDot = textureFileName.LastIndexOf('.'); if (lastDot != -1) { string baseName = textureFileName.Substring(0, lastDot); while (baseName.Length > 50 && baseName.IndexOf('_') != -1) { baseName = baseName.Substring(baseName.IndexOf('_') + 1); } textureFileName = baseName + textureFileName.Substring(lastDot); } //HEU_Logger.LogFormat("Texture File Name: {0}, {1}", paramStrValue, textureFileName); } return textureFileName; }
/// <summary> /// For this object's _material, we update the shader attributes and /// fetch the textures from Houdini. /// </summary> /// <param name="materialInfo">This material's info from Houdini</param> /// <param name="assetCacheFolderPath">Path to asset's cache folder</param> public bool UpdateMaterialFromHoudini(HAPI_MaterialInfo materialInfo, string assetCacheFolderPath) { if (_material == null) { return false; } HEU_SessionBase session = HEU_SessionManager.GetOrCreateDefaultSession(); HAPI_NodeInfo nodeInfo = new HAPI_NodeInfo(); if (!session.GetNodeInfo(materialInfo.nodeId, ref nodeInfo)) { return false; } // Get all parameters of this material HAPI_ParmInfo[] parmInfos = new HAPI_ParmInfo[nodeInfo.parmCount]; if (!HEU_GeneralUtility.GetArray1Arg(materialInfo.nodeId, session.GetParams, parmInfos, 0, nodeInfo.parmCount)) { return false; } // Assign transparency shader or non-transparent. bool isTransparent = IsTransparentMaterial(session, materialInfo.nodeId, parmInfos); if (isTransparent) { _material.shader = HEU_MaterialFactory.FindPluginShader(HEU_PluginSettings.DefaultTransparentShader); } else { _material.shader = HEU_MaterialFactory.FindPluginShader(HEU_PluginSettings.DefaultStandardShader); } if (HEU_PluginSettings.UseLegacyShaders) { return UseLegacyShaders(materialInfo, assetCacheFolderPath, session, nodeInfo, parmInfos); } // Diffuse texture - render & extract int diffuseMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_TEX1_ATTR, HEU_Defines.MAT_OGL_TEX1_ATTR_ENABLED); if (diffuseMapParmIndex < 0) { diffuseMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_BASECOLOR_ATTR, HEU_Defines.MAT_BASECOLOR_ATTR_ENABLED); } if (diffuseMapParmIndex >= 0 && diffuseMapParmIndex < parmInfos.Length) { string diffuseTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[diffuseMapParmIndex]); _material.mainTexture = HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[diffuseMapParmIndex].id, diffuseTextureFileName, assetCacheFolderPath, false); } Color diffuseColor; if (!HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_DIFF_ATTR, Color.white, out diffuseColor)) { HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_DIFF_ATTR, Color.white, out diffuseColor); } float alpha; GetMaterialAlpha(session, materialInfo.nodeId, parmInfos, 1f, out alpha); if (isTransparent) { int opacityMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_OPACITY_MAP_ATTR, HEU_Defines.MAT_OGL_OPACITY_MAP_ATTR_ENABLED); if (opacityMapParmIndex < 0) { opacityMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OPACITY_MAP_ATTR, HEU_Defines.MAT_OPACITY_MAP_ATTR_ENABLED); } if (opacityMapParmIndex >= 0 && opacityMapParmIndex < parmInfos.Length) { string opacityTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[opacityMapParmIndex]); _material.SetTexture(HEU_Defines.UNITY_SHADER_OPACITY_MAP, HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[opacityMapParmIndex].id, opacityTextureFileName, assetCacheFolderPath, false)); } } diffuseColor.a = alpha; _material.SetColor(HEU_Defines.UNITY_SHADER_COLOR, diffuseColor); if (HEU_PluginSettings.UseSpecularShader) { Color specular; Color defaultSpecular = new Color(0.2f, 0.2f, 0.2f, 1); if (!HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_SPEC_ATTR, defaultSpecular, out specular)) { HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_SPEC_ATTR, defaultSpecular, out specular); } _material.SetColor(HEU_Defines.UNITY_SHADER_SPEC_COLOR, specular); int specMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_SPEC_MAP_ATTR, HEU_Defines.MAT_OGL_SPEC_MAP_ATTR_ENABLED); if (specMapParmIndex < 0) { specMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_SPEC_MAP_ATTR, HEU_Defines.MAT_SPEC_MAP_ATTR_ENABLED); } if (specMapParmIndex >= 0 && specMapParmIndex < parmInfos.Length) { string specTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[specMapParmIndex]); _material.SetTexture(HEU_Defines.UNITY_SHADER_SPEC_MAP, HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[specMapParmIndex].id, specTextureFileName, assetCacheFolderPath, false)); } } else { float metallic = 0; if (!HEU_ParameterUtility.GetParameterFloatValue(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_METALLIC_ATTR, 0f, out metallic)) { HEU_ParameterUtility.GetParameterFloatValue(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_METALLIC_ATTR, 0f, out metallic); } _material.SetFloat(HEU_Defines.UNITY_SHADER_METALLIC, metallic); int metallicMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_METALLIC_MAP_ATTR, HEU_Defines.MAT_OGL_METALLIC_MAP_ATTR_ENABLED); if (metallicMapParmIndex < 0) { metallicMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_METALLIC_MAP_ATTR, HEU_Defines.MAT_METALLIC_MAP_ATTR_ENABLED); } if (metallicMapParmIndex >= 0 && metallicMapParmIndex < parmInfos.Length) { string metallicTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[metallicMapParmIndex]); _material.SetTexture(HEU_Defines.UNITY_SHADER_METALLIC_MAP, HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[metallicMapParmIndex].id, metallicTextureFileName, assetCacheFolderPath, false)); } } // Normal map - render & extract texture int normalMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_NORMAL_ATTR, HEU_Defines.MAT_NORMAL_ATTR_ENABLED); if (normalMapParmIndex < 0) { normalMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_NORMAL_ATTR, ""); } if (normalMapParmIndex >= 0 && normalMapParmIndex < parmInfos.Length) { string normalTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[normalMapParmIndex]); Texture2D normalMap = HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[normalMapParmIndex].id, normalTextureFileName, assetCacheFolderPath, true); if (normalMap != null) { _material.SetTexture(HEU_Defines.UNITY_SHADER_BUMP_MAP, normalMap); } } // Emission Color emission; Color defaultEmission = new Color(0, 0, 0, 0); if (!HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_EMISSIVE_ATTR, defaultEmission, out emission)) { HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_EMISSIVE_ATTR, defaultEmission, out emission); } _material.SetColor(HEU_Defines.UNITY_SHADER_EMISSION_COLOR, emission); int emissionMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_EMISSIVE_MAP_ATTR, HEU_Defines.MAT_OGL_EMISSIVE_MAP_ATTR_ENABLED); if (emissionMapParmIndex < 0) { emissionMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_EMISSIVE_MAP_ATTR, HEU_Defines.MAT_EMISSIVE_MAP_ATTR_ENABLED); } if (emissionMapParmIndex >= 0 && emissionMapParmIndex < parmInfos.Length) { string emissionTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[emissionMapParmIndex]); _material.SetTexture(HEU_Defines.UNITY_SHADER_EMISSION_MAP, HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[emissionMapParmIndex].id, emissionTextureFileName, assetCacheFolderPath, false)); } // Smoothness (need to invert roughness!) float roughness; float defaultRoughness = 0.5f; if (!HEU_ParameterUtility.GetParameterFloatValue(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_ROUGH_ATTR, defaultRoughness, out roughness)) { HEU_ParameterUtility.GetParameterFloatValue(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_ROUGH_ATTR, defaultRoughness, out roughness); } // Clamp shininess to non-zero as results in very hard shadows. Unity's UI does not allow zero either. _material.SetFloat(HEU_Defines.UNITY_SHADER_SMOOTHNESS, Mathf.Max(0.03f, 1.0f - roughness)); int roughMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_ROUGH_MAP_ATTR, HEU_Defines.MAT_OGL_ROUGH_MAP_ATTR_ENABLED); if (roughMapParmIndex < 0) { roughMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_ROUGH_MAP_ATTR, HEU_Defines.MAT_ROUGH_MAP_ATTR_ENABLED); } if (roughMapParmIndex >= 0 && roughMapParmIndex < parmInfos.Length) { string roughTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[roughMapParmIndex]); _material.SetTexture(HEU_Defines.UNITY_SHADER_SMOOTHNESS_MAP, HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[roughMapParmIndex].id, roughTextureFileName, assetCacheFolderPath, false, invertTexture: true)); } // Occlusion (only has ogl map) int occlusionMapParmIndex = HEU_ParameterUtility.FindTextureParamByNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_OCCLUSION_MAP_ATTR, HEU_Defines.MAT_OGL_ROUGH_MAP_ATTR_ENABLED); if (occlusionMapParmIndex >= 0 && occlusionMapParmIndex < parmInfos.Length) { string occlusionTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[occlusionMapParmIndex]); _material.SetTexture(HEU_Defines.UNITY_SHADER_OCCLUSION_MAP, HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[occlusionMapParmIndex].id, occlusionTextureFileName, assetCacheFolderPath, false)); } return true; }
/// <summary> /// For this object's _material, we update the shader attributes and /// fetch the textures from Houdini. /// </summary> /// <param name="materialInfo">This material's info from Houdini</param> /// <param name="assetCacheFolderPath">Path to asset's cache folder</param> public void UpdateMaterialFromHoudini(HAPI_MaterialInfo materialInfo, string assetCacheFolderPath) { HEU_SessionBase session = HEU_SessionManager.GetOrCreateDefaultSession(); HAPI_NodeInfo nodeInfo = new HAPI_NodeInfo(); if (!session.GetNodeInfo(materialInfo.nodeId, ref nodeInfo)) { return; } // Get all parameters of this material HAPI_ParmInfo[] parmInfos = new HAPI_ParmInfo[nodeInfo.parmCount]; if (!HEU_GeneralUtility.GetArray1Arg(materialInfo.nodeId, session.GetParams, parmInfos, 0, nodeInfo.parmCount)) { return; } // Assign transparency shader or non-transparent. if (IsTransparentMaterial(session, materialInfo.nodeId, parmInfos)) { _material.shader = HEU_MaterialFactory.FindPluginShader(HEU_PluginSettings.DefaultTransparentShader); } else { _material.shader = HEU_MaterialFactory.FindPluginShader(HEU_PluginSettings.DefaultStandardShader); } // Diffuse texture - render & extract int diffuseMapParmIndex = HEU_ParameterUtility.GetParameterIndexFromNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_TEX1_ATTR); if (diffuseMapParmIndex < 0) { diffuseMapParmIndex = HEU_ParameterUtility.GetParameterIndexFromNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_BASECOLOR_ATTR); if (diffuseMapParmIndex < 0) { diffuseMapParmIndex = HEU_ParameterUtility.GetParameterIndexFromNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_MAP_ATTR); } } if (diffuseMapParmIndex >= 0 && diffuseMapParmIndex < parmInfos.Length) { string diffuseTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[diffuseMapParmIndex]); _material.mainTexture = HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[diffuseMapParmIndex].id, diffuseTextureFileName, assetCacheFolderPath); } // Normal map - render & extract texture int normalMapParmIndex = HEU_ParameterUtility.GetParameterIndexFromNameOrTag(session, nodeInfo.id, parmInfos, HEU_Defines.MAT_OGL_NORMAL_ATTR); if (normalMapParmIndex >= 0 && normalMapParmIndex < parmInfos.Length) { string normalTextureFileName = GetTextureFileNameFromMaterialParam(session, materialInfo.nodeId, parmInfos[normalMapParmIndex]); Texture2D normalMap = HEU_MaterialFactory.RenderAndExtractImageToTexture(session, materialInfo, parmInfos[normalMapParmIndex].id, normalTextureFileName, assetCacheFolderPath); if (normalMap != null) { _material.SetTexture(HEU_Defines.UNITY_SHADER_BUMP_MAP, normalMap); } } // Assign shader properties // Clamp shininess to non-zero as results in very hard shadows. Unity's UI does not allow zero either. float shininess = HEU_ParameterUtility.GetParameterFloatValue(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_ROUGH_ATTR, 0f); _material.SetFloat(HEU_Defines.UNITY_SHADER_SHININESS, Mathf.Max(0.03f, 1.0f - shininess)); Color diffuseColor = HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_DIFF_ATTR, Color.white); diffuseColor.a = HEU_ParameterUtility.GetParameterFloatValue(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_ALPHA_ATTR, 1f); _material.SetColor(HEU_Defines.UNITY_SHADER_COLOR, diffuseColor); Color specular = HEU_ParameterUtility.GetParameterColor3Value(session, materialInfo.nodeId, parmInfos, HEU_Defines.MAT_OGL_SPEC_ATTR, Color.black); _material.SetColor(HEU_Defines.UNITY_SHADER_SPECCOLOR, specular); }