public static TerrainLayer createTerrainLayer(Material mat, float tiling) { TerrainLayer terrainLayer = new TerrainLayer(); string path = AssetDatabase.GetAssetPath(mat); path = path.Replace(".mat", ".terrainlayer"); AssetDatabase.CreateAsset(terrainLayer, path); AssetDatabase.Refresh(); terrainLayer.diffuseTexture = (Texture2D)mat.mainTexture; //attempt to auto-detect a settings file for Lightweight or HD pipelines switch (MegascansUtilities.getCurrentPipeline()) { case Pipeline.HDRP: terrainLayer.normalMapTexture = (Texture2D)mat.GetTexture("_NormalMap"); if (mat.GetFloat("_MaterialID") == 4) { terrainLayer.maskMapTexture = (Texture2D)mat.GetTexture("_SpecularColorMap"); terrainLayer.metallic = 1.0f; } else if (mat.GetFloat("_MaterialID") == 1) { terrainLayer.maskMapTexture = (Texture2D)mat.GetTexture("_MaskMap"); terrainLayer.specular = new Color(1.0f, 1.0f, 1.0f); } break; case Pipeline.LWRP: terrainLayer.normalMapTexture = (Texture2D)mat.GetTexture("_BumpMap"); if (mat.GetFloat("_WorkflowMode") == 1) { terrainLayer.maskMapTexture = (Texture2D)mat.GetTexture("_MetallicGlossMap"); terrainLayer.specular = new Color(1.0f, 1.0f, 1.0f); } else { terrainLayer.maskMapTexture = (Texture2D)mat.GetTexture("_SpecGlossMap"); terrainLayer.metallic = 1.0f; } break; case Pipeline.Standard: terrainLayer.normalMapTexture = (Texture2D)mat.GetTexture("_BumpMap"); if (mat.shader.ToString() == "Standard (Specular setup)") { terrainLayer.maskMapTexture = (Texture2D)mat.GetTexture("_SpecGlossMap"); terrainLayer.metallic = 1.0f; } else { terrainLayer.maskMapTexture = (Texture2D)mat.GetTexture("_MetallicGlossMap"); terrainLayer.specular = new Color(1.0f, 1.0f, 1.0f); } break; } terrainLayer.tileSize = new Vector2(tiling, tiling); return(terrainLayer); }
/// <summary> /// Invert green channel of the selected texture 2D /// </summary> public static void FlipGreenChannel() { try { string sourcePath = MegascansUtilities.GetSelectedTexture(); if (sourcePath == null) { return; } EditorUtility.DisplayProgressBar("Bridge Plugin", "Flipping green channel...", 0.5f); UnityEngine.Color[] rgbCols = ImportJPG(sourcePath).GetPixels(); UnityEngine.Color[] rgbaCols = new UnityEngine.Color[width * height]; for (int i = 0; i < width * height; ++i) { rgbaCols[i] = rgbCols != null ? rgbCols[i] : new UnityEngine.Color(1.0f, 1.0f, 1.0f); rgbaCols[i].g = 1.0f - rgbaCols[i].g; rgbaCols[i].a = 1.0f; } Texture2D tex = new Texture2D(width, height, TextureFormat.RGBAFloat, false); tex.SetPixels(rgbaCols); File.WriteAllBytes(sourcePath, tex.EncodeToPNG()); AssetDatabase.ImportAsset(sourcePath); MegascansUtilities.HideProgressBar(); Debug.Log("Successfully flipped green channel."); } catch (Exception ex) { Debug.Log("Exception::MegascansImageUtils::Flip Green Channel:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); } }
/// <summary> /// reads a texture file straight from hard drive absolute path, converts it to a Unity texture. /// </summary> /// <param name="sourcePath"></param> /// <param name="width"></param> /// <param name="height"></param> /// <returns></returns> public static Texture2D ImportJPG(string sourcePath) { try { if (sourcePath == null) { return(null); } if (!File.Exists(sourcePath)) { Debug.LogWarning("Could not find " + sourcePath + "\nPlease make sure it is downloaded."); return(null); } byte[] texData = File.ReadAllBytes(sourcePath); Texture2D tex = new Texture2D(2, 2, TextureFormat.RGBAFloat, true); tex.LoadImage(texData); width = tex.width; height = tex.height; return(tex); } catch (Exception ex) { Debug.Log("Exception::MegascansImageUtils::Import JPG:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); return(null); } }
/// <summary> /// used for packing an alpha channel into an existing RGB texture. Uses native Unity API calls, can't be multithreaded, and is considerably slower than our own method. /// Currently has to run if using Mac OSX as there is no support for the system.imaging library on that operating system. /// Will fail if textures aren't the same resolution. /// </summary> /// <param name="cPixels"></param> /// <param name="aPixels"></param> /// <param name="invertAlpha"></param> /// <returns></returns> public static Texture2D PackTextures(string rgbPath, string aPath, string savePath, bool invertAlpha = false) { try { if ((rgbPath == null) && (aPath == null)) { return(null); } UnityEngine.Color[] rgbCols = ImportJPG(rgbPath) != null?ImportJPG(rgbPath).GetPixels() : null; UnityEngine.Color[] aCols = ImportJPG(aPath) != null?ImportJPG(aPath).GetPixels() : null; UnityEngine.Color[] rgbaCols = new UnityEngine.Color[width * height]; for (int i = 0; i < width * height; ++i) { rgbaCols[i] = rgbCols != null ? rgbCols[i] : new UnityEngine.Color(1.0f, 1.0f, 1.0f); rgbaCols[i].a = aCols != null ? ((aCols[i].r + aCols[i].g + aCols[i].b) / 3.0f) : 1.0f; rgbaCols[i].a = invertAlpha ? 1.0f - rgbaCols[i].a : rgbaCols[i].a; } Texture2D tex = new Texture2D(width, height, TextureFormat.RGBAFloat, false); tex.SetPixels(rgbaCols); File.WriteAllBytes(savePath, tex.EncodeToPNG()); AssetDatabase.ImportAsset(savePath); DestroyImmediate(tex); return(TextureImportSetup(savePath, false)); } catch (Exception ex) { Debug.Log("Exception::MegascansImageUtils::Channel Pack RGB + A:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); return(null); } }
/// <summary> /// This function attempts to auto-detect which template the project is using. Defaults to Legacy/Standard if all else fails. /// </summary> void GetShaderType() { shaderType = EditorPrefs.GetInt("QuixelDefaultShader"); if (shaderType == 3) { //attempt to auto-detect a settings file for Lightweight or HD pipelines switch (MegascansUtilities.getCurrentPipeline()) { case Pipeline.HDRP: shaderType = 0; break; case Pipeline.LWRP: shaderType = 1; break; case Pipeline.Standard: shaderType = 2; break; default: shaderType = 2; break; } } }
public static void CreateDecalPrefab(string materialPath, Material decalMaterial, float size) { #if HDRP string assetPath = materialPath.Substring(0, materialPath.IndexOf("/Materials/")); string materialName = Path.GetFileName(materialPath); string prefabName = materialName.Replace(".mat", ""); string prefabPath = MegascansUtilities.ValidateFolderCreate(assetPath, "Prefabs"); GameObject g = new GameObject(); g.AddComponent <UnityEngine.Experimental.Rendering.HDPipeline.DecalProjectorComponent>(); g.name = prefabName; UnityEngine.Experimental.Rendering.HDPipeline.DecalProjectorComponent decalProjector = g.GetComponent <UnityEngine.Experimental.Rendering.HDPipeline.DecalProjectorComponent>(); decalProjector.material = decalMaterial; #if UNITY_2018_3 || UNITY_2019 decalProjector.size = new Vector3(size, size, size); #endif string finalName = prefabPath + "/" + prefabName + "_Decal" + ".prefab"; UnityEngine.Object pf = null; try { pf = AssetDatabase.LoadAssetAtPath(finalName, typeof(UnityEngine.Object)); } catch (Exception ex) { Debug.Log("Error verifying prefab."); Debug.Log(ex); } if (!pf) { PrefabUtility.CreatePrefab(finalName, g); } else { PrefabUtility.ReplacePrefab(g, pf, ReplacePrefabOptions.ReplaceNameBased); } DestroyImmediate(g); #endif }
public static Material CreateMaterial(string mPath, string name, string shaderName) { string path = MegascansUtilities.FixPath(mPath); /// Unity doesn't allow you to create objects in directories which don't exist. /// So in this function, we create any and all necessary subdirectories that are required. /// We return the final subdirectory, which is used later in the asset creation too. //first, create the user specified path from the importer settings. string[] pathParts = MegascansUtilities.FixSlashes(path).Split('/'); string defPath = "Assets"; if (pathParts.Length > 0) { for (int i = 0; i < pathParts.Length; ++i) { defPath = MegascansUtilities.ValidateFolderCreate(defPath, pathParts[i]); } } defPath = defPath + "/" + name + ".mat"; Material terrainMaterial = new Material(Shader.Find(shaderName)); AssetDatabase.CreateAsset(terrainMaterial, defPath); AssetDatabase.Refresh(); return(terrainMaterial); }
/// <summary> /// used for packing an alpha channel into an existing RGB texture. Uses native Unity API calls, can't be multithreaded, and is considerably slower than our own method. /// Currently has to run if using Mac OSX as there is no support for the system.imaging library on that operating system. /// Will fail if textures aren't the same resolution. /// </summary> /// <param name="cPixels"></param> /// <param name="invertAlpha"></param> /// <returns></returns> public static void ImportTerrainNormal(string sourcepath, string destPath) { try { if (sourcepath == null) { return; } UnityEngine.Color[] rgbCols = ImportJPG(sourcepath) != null?ImportJPG(sourcepath).GetPixels() : null; UnityEngine.Color[] rgbaCols = new UnityEngine.Color[width * height]; for (int i = 0; i < width * height; ++i) { rgbaCols[i] = rgbCols != null ? rgbCols[i] : new UnityEngine.Color(1.0f, 1.0f, 1.0f); rgbaCols[i].g = 1.0f - rgbaCols[i].g; rgbaCols[i].a = 1.0f; } Texture2D tex = new Texture2D(width, height, TextureFormat.RGBAFloat, false); tex.SetPixels(rgbaCols); File.WriteAllBytes(destPath, tex.EncodeToPNG()); AssetDatabase.ImportAsset(destPath); TextureImportSetup(destPath, true, false); } catch (Exception ex) { Debug.Log("Exception::MegascansImageUtils::Generate Terrain Normal:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); } }
void LoadPreferences() { path = MegascansUtilities.FixPath(EditorPrefs.GetString("QuixelDefaultPath", "Quixel/Megascans/")); dispType = EditorPrefs.GetInt("QuixelDefaultDisplacement"); texPack = EditorPrefs.GetInt("QuixelDefaultTexPacking"); shaderType = EditorPrefs.GetInt("QuixelDefaultShader"); lodFadeMode = EditorPrefs.GetInt("QuixelDefaultLodFadeMode", 1); setupCollision = EditorPrefs.GetBool("QuixelDefaultSetupCollision", true); applyToSelection = EditorPrefs.GetBool("QuixelDefaultApplyToSelection", false); addAssetToScene = EditorPrefs.GetBool("QuixelDefaultAddAssetToScene", false); importAllTextures = EditorPrefs.GetBool("QuixelDefaultImportAllTextures", false); }
public Texture2D ImportTexture() { MegascansUtilities.CopyFileToProject(sourcePath, destPath); TextureImporter tImp = AssetImporter.GetAtPath(destPath) as TextureImporter; int importResolution = Convert.ToInt32(Math.Pow(2, 9 + EditorPrefs.GetInt("QuixelDefaultImportResolution", 4))); tImp.maxTextureSize = importResolution; tImp.sRGBTexture = sRGB; tImp.textureType = normalMap ? TextureImporterType.NormalMap : TextureImporterType.Default; AssetDatabase.ImportAsset(destPath); AssetDatabase.Refresh(); return(AssetDatabase.LoadAssetAtPath <Texture2D>(destPath)); }
static void ImportMesh(string sourcePath, string destPath) { try { MegascansUtilities.UpdateProgressBar(1.0f, "Importing Megascans Asset", "Importing Mesh..."); if (File.Exists(sourcePath)) { File.Copy(sourcePath, destPath, true); AssetDatabase.ImportAsset(destPath); } } catch (Exception ex) { Debug.Log("Exception::MegascansMeshUtils::Importing Mesh:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); } }
/// <summary> /// This function attempts to create a folder name /// </summary> void GetAssetFolderName(JObject objectList) { assetName = (string)objectList["name"]; id = (string)objectList["id"]; assetResolution = ""; try { string namingConvention = (string)objectList["namingConvention"]; finalName = namingConvention; if (namingConvention != "" && namingConvention != null) { if (namingConvention.Contains("$id")) { finalName = finalName.Replace("$id", id); } if (namingConvention.Contains("$name")) { finalName = finalName.Replace("$name", assetName); } //Add support for $matName when it is finalized. if (namingConvention.Contains("$matName")) { finalName = finalName.Replace("$matName", ""); } if (namingConvention.Contains("$type")) { finalName = finalName.Replace("$type", (string)objectList["type"]); } if (namingConvention.Contains("$resolution")) { assetResolution = (string)objectList["resolution"]; } return; } } catch (Exception ex) { Debug.Log(ex); MegascansUtilities.HideProgressBar(); } finalName = finalName.Replace("__", "_").Replace(".", ""); finalName = MegascansUtilities.FixSpaces(new string[] { assetName.Replace(" ", "_"), id }); }
/// <summary> /// literally just write the file to disk. /// </summary> /// <param name="tex"></param> /// <param name="assetPath"></param> public static void CreateTexture(string tex, string assetPath) { try { if ((tex == null) || (File.Exists(tex) == false)) { return; } Texture2D t = ImportJPG(tex); File.WriteAllBytes(assetPath, t.EncodeToPNG()); AssetDatabase.ImportAsset(assetPath); } catch (Exception ex) { Debug.Log("Exception::MegascansImageUtils::Create Texture:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); } }
static GameObject SavePrefab(GameObject prefabGo, string savePath, bool addAssetToScene = false) { try { //Set all children objects of the prefab to static Transform[] allChildren = prefabGo.GetComponentsInChildren <Transform>(); foreach (Transform child in allChildren) { child.gameObject.isStatic = true; } GameObject newPrefabObject = prefabGo; MegascansUtilities.UpdateProgressBar(1.0f, "Importing Megascans Asset", "Creating Prefab..."); #if UNITY_5 || UNITY_2017 || UNITY_2018 UnityEngine.Object existingPrefab = AssetDatabase.LoadAssetAtPath(savePath, typeof(UnityEngine.Object)); if (!existingPrefab) { PrefabUtility.CreatePrefab(savePath, prefabGo); } else { PrefabUtility.ReplacePrefab(prefabGo, existingPrefab, ReplacePrefabOptions.ReplaceNameBased); } #else PrefabUtility.SaveAsPrefabAsset(prefabGo, savePath); #endif DestroyImmediate(prefabGo); if (addAssetToScene) { UnityEngine.Object prefabObject = AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(savePath); newPrefabObject = (GameObject)PrefabUtility.InstantiatePrefab(prefabObject); newPrefabObject.isStatic = true; } return(newPrefabObject); } catch (Exception ex) { Debug.Log("Exception::MegascansMeshUtils::Saving Prefab:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); return(null); } }
public static void CreateTerrainLayerFromMat() { try { Material selectedMat = MegascansUtilities.GetSelectedMaterial(); if (!selectedMat) { return; } Debug.Log("Here"); createTerrainLayer(selectedMat, 1f); Debug.Log("Successfully created the terrain layer."); } catch (Exception ex) { Debug.Log("Exception::MegascansImageUtils::Flip Green Channel:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); } }
public static Material CreateDecalMaterial(string selectedMaterialPath, Material selectedMaterial, float decalBlend) { Material decalMaterial = new Material(Shader.Find("Standard")); #if UNITY_2018_3 || UNITY_2018_4 || UNITY_2019 decalMaterial.shader = Shader.Find("HDRP/Decal"); #else decalMaterial.shader = Shader.Find("HDRenderPipeline/Decal"); #endif string decalMaterialPath = selectedMaterialPath.Replace(".mat", "_Decal.mat"); AssetDatabase.CreateAsset(decalMaterial, decalMaterialPath); AssetDatabase.Refresh(); decalMaterial.enableInstancing = true; //Enable material keywords decalMaterial.EnableKeyword("_ALPHATEST_ON"); decalMaterial.EnableKeyword("_ALBEDOCONTRIBUTION"); decalMaterial.EnableKeyword("_COLORMAP"); decalMaterial.EnableKeyword("_DISPLACEMENT_LOCK_TILING_SCALE"); decalMaterial.EnableKeyword("_DOUBLESIDED_ON"); decalMaterial.EnableKeyword("_MASKMAP"); decalMaterial.EnableKeyword("_METALLICSPECGLOSSMAP"); decalMaterial.EnableKeyword("_NORMALMAP"); decalMaterial.EnableKeyword("_NORMALMAP_TANGENT_SPACE"); decalMaterial.EnableKeyword("_PIXEL_DISPLACEMENT"); decalMaterial.EnableKeyword("_PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE"); //Set material textures decalMaterial.SetTexture("_BaseColorMap", selectedMaterial.mainTexture); decalMaterial.SetTexture("_MaskMap", selectedMaterial.GetTexture("_MaskMap")); decalMaterial.SetTexture("_NormalMap", selectedMaterial.GetTexture("_NormalMap")); //Set material keywords decalMaterial.SetFloat("_AlbedoMode", 1f); if (!MegascansUtilities.isLegacy()) { decalMaterial.SetFloat("_MaskBlendSrc", 0f); } decalMaterial.SetFloat("_DecalBlend", decalBlend); return(decalMaterial); }
/// <summary> /// This function attempts to create a folder name /// </summary> void GetAssetFolderName(JObject objectList) { try { assetResolution = ""; string namingConvention = (string)objectList["namingConvention"]; finalName = namingConvention; if (namingConvention != "" && namingConvention != null) { if (namingConvention.Contains("$id")) { finalName = finalName.Replace("$id", (string)objectList["id"]); } if (namingConvention.Contains("$name")) { finalName = finalName.Replace("$name", (string)objectList["name"]); } if (namingConvention.Contains("$type")) { finalName = finalName.Replace("$type", (string)objectList["type"]); } if (namingConvention.Contains("$resolution")) { assetResolution = (string)objectList["resolution"]; } return; } } catch (Exception ex) { Debug.Log(ex); MegascansUtilities.HideProgressBar(); } //then create a unique subfolder for the asset. assetName = (string)objectList["name"]; id = (string)objectList["id"]; finalName = MegascansUtilities.FixSpaces(new string[] { assetName.Replace(" ", "_"), id }); Debug.Log("Final name:" + finalName); }
static GameObject SavePrefab(GameObject prefabGo, string savePath, bool addAssetToScene = false) { try { GameObject newPrefabObject = prefabGo; MegascansUtilities.UpdateProgressBar(1.0f, "Importing Megascans Asset", "Creating Prefab..."); #if UNITY_2019 PrefabUtility.SaveAsPrefabAsset(prefabGo, savePath); DestroyImmediate(prefabGo); if (addAssetToScene) { UnityEngine.Object prefabObject = AssetDatabase.LoadAssetAtPath <UnityEngine.Object>(savePath); newPrefabObject = (GameObject)PrefabUtility.InstantiatePrefab(prefabObject); } #else UnityEngine.Object existingPrefab = AssetDatabase.LoadAssetAtPath(savePath, typeof(UnityEngine.Object)); if (!existingPrefab) { PrefabUtility.CreatePrefab(savePath, prefabGo); } else { PrefabUtility.ReplacePrefab(prefabGo, existingPrefab, ReplacePrefabOptions.ReplaceNameBased); } if (!addAssetToScene) { DestroyImmediate(prefabGo); } #endif return(newPrefabObject); } catch (Exception ex) { Debug.Log("Exception::MegascansMeshUtils::Saving Prefab:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); return(null); } }
/// <summary> /// Sets the import settings for textures, normalmap, sRGB etc. /// </summary> /// <param name="assetPath"></param> /// <param name="normalMap"></param> /// <param name="sRGB"></param> public static Texture2D TextureImportSetup(string assetPath, bool normalMap, bool sRGB = true) { try { TextureImporter tImp = AssetImporter.GetAtPath(assetPath) as TextureImporter; if (tImp == null) { return(null); } int importResolution = Convert.ToInt32(Math.Pow(2, 9 + EditorPrefs.GetInt("QuixelDefaultImportResolution", 4))); tImp.maxTextureSize = importResolution; tImp.sRGBTexture = sRGB; tImp.textureType = normalMap ? TextureImporterType.NormalMap : TextureImporterType.Default; AssetDatabase.ImportAsset(assetPath); return(AssetDatabase.LoadAssetAtPath <Texture2D>(assetPath)); } catch (Exception ex) { Debug.Log("Exception::MegascansImageUtils::Texture Import Setup:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); return(null); } }
void ProcessTextures(JObject objectList) { texPath = MegascansUtilities.ValidateFolderCreate(path, "Textures"); matPath = Path.Combine(MegascansUtilities.ValidateFolderCreate(path, "Materials"), folderNamingConvention); if (!(plant && hasBillboardLODOnly)) { MegascansUtilities.UpdateProgressBar(1.0f, "Processing Asset " + assetName, "Creating material..."); finalMat = MegascansMaterialUtils.CreateMaterial(shaderType, matPath, isAlembic, dispType, texPack); ImportAllTextures(finalMat, (JArray)objectList["components"]); ImportAllTextures(finalMat, (JArray)objectList["packedTextures"]); } if (plant && hasBillboardLOD) { texPath = MegascansUtilities.ValidateFolderCreate(texPath, "Billboard"); matPath += "_Billboard"; MegascansUtilities.UpdateProgressBar(1.0f, "Processing Asset " + assetName, "Creating material..."); billboardMat = MegascansMaterialUtils.CreateMaterial(shaderType, matPath, isAlembic, dispType, texPack); ImportAllTextures(billboardMat, (JArray)objectList["components-billboard"]); ImportAllTextures(billboardMat, (JArray)objectList["packed-billboard"]); } }
public static List <Material> GetSelectedMaterialsInProjectHierarchy() { List <Material> selectedMaterials = new List <Material>(); List <string> selectedMaterialPaths = new List <string>(); List <UnityEngine.Object> selection = new List <UnityEngine.Object>(); foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets)) { if (obj.GetType() == typeof(Material) && selectedMaterials.Count <= maxMaterialAllowed) { selectedMaterials.Add((Material)obj); } else { selection.Add(obj); } } List <string> selectedFolders = MegascansUtilities.GetSelectedFolders(selection); foreach (string folder in selectedFolders) { selectedMaterialPaths = selectedMaterialPaths.Concat(MegascansUtilities.GetFiles(folder, ".mat")).ToList(); } foreach (string mPath in selectedMaterialPaths) { Material mat = (Material)AssetDatabase.LoadAssetAtPath(mPath, typeof(Material)); if (mat != null && selectedMaterials.Count <= maxMaterialAllowed) //4 is the max number of layers currently allowed in the HDRenderPipeline/LayeredLit shader. { selectedMaterials.Add(mat); } } return(selectedMaterials); }
public static void SetupTerrain() { string materialName = EditorPrefs.GetString("QuixelDefaultMaterialName", "Terrain Material"); string materialPath = EditorPrefs.GetString("QuixelDefaultMaterialPath", "Quixel/"); string tilingNumber = EditorPrefs.GetString("QuixelDefaultTiling", "10"); string[] versionParts = Application.unityVersion.Split('.'); int majorVersion = int.Parse(versionParts[0]); if (majorVersion < 2018) { Debug.Log("This Unity version doesn't support this feature."); return; } else { float tiling; try { tiling = float.Parse(tilingNumber); } catch (Exception ex) { Debug.Log("Exception: " + ex.ToString()); tiling = 1f; } maxMaterialAllowed = MegascansUtilities.isLegacy() ? 4 : 8; List <Material> sourceMaterials = new List <Material>(); Terrain terrain = null; try { //Get currently highlighted materials in the project window. sourceMaterials = GetSelectedMaterialsInProjectHierarchy(); //Verify two or more materails were seleted. if (sourceMaterials.Count < 2 && MegascansUtilities.isLegacy()) { Debug.Log("Not enough materials to create a blend material. Please select more materials."); return; } //Get selected terrain in the scene view. terrain = getCurrentlySelectedTerrain(); //Verify a terrain is selected. if (terrain == null) { Debug.Log("No terrain selected. Please select a terrain."); //return; } } catch (Exception ex) { Debug.Log("Error getting select terrain/materials."); Debug.Log(ex); } if (MegascansUtilities.isLegacy()) { try { //Set up the material here. Material terrainMaterial = SetupTerrainMaterialDeprecated(sourceMaterials, materialPath, materialName, tiling); //Get terrain data for splat maps. TerrainData terrainData = terrain.terrainData; //Get the textures from source materials to add to the painting. if (terrainData) { #pragma warning disable terrainData.splatPrototypes = getMaterialTexturesForSplatMap(sourceMaterials, tiling); } terrain.materialType = Terrain.MaterialType.Custom; terrain.materialTemplate = terrainMaterial; EnableSplatmaps(terrainData); Texture2D alphaMap = terrainData.alphamapTextures[0]; terrainMaterial.SetTexture("_LayerMaskMap", alphaMap); Debug.Log("Terrain blend material successfully created!"); } catch (Exception ex) { Debug.Log("Error Generating terrain blend material!"); Debug.Log(ex); } } else { #if UNITY_2018_3 || UNITY_2019 //Create the material here. //Material terrainMaterial = SetupTerrainMaterial(materialPath, materialName); List <TerrainLayer> terrainLayers = new List <TerrainLayer>(); foreach (TerrainLayer tl in terrain.terrainData.terrainLayers) { terrainLayers.Add(tl); } foreach (Material mat in sourceMaterials) { if (terrainLayers.Count <= 8) { terrainLayers.Add(createTerrainLayer(mat, tiling)); } } if (terrainLayers.Count > 0) { terrain.terrainData.terrainLayers = terrainLayers.ToArray(); } #endif } } }
/// <summary> /// Creates materials needed for the asset. /// </summary> /// <returns></returns> Material CreateMaterial() { MegascansUtilities.UpdateProgressBar(1.0f, "Processing Asset " + assetName, "Creating material..."); if ((shaderType == 0 || shaderType == 1) && isAlembic) { Debug.Log("Alembic files are not supported in LWRP/HDRP. Please change your export file format in Bridge or change your SRP in Unity."); return(null); } try { string rp = matPath + ".mat"; Material mat = (Material)AssetDatabase.LoadAssetAtPath(rp, typeof(Material)); if (!mat) { mat = new Material(Shader.Find("Standard")); AssetDatabase.CreateAsset(mat, rp); AssetDatabase.Refresh(); if (shaderType < 1) { mat.shader = Shader.Find("HDRenderPipeline/Lit"); #if UNITY_2018_3 || UNITY_2019 mat.shader = Shader.Find("HDRP/Lit"); #endif mat.SetInt("_DisplacementMode", dispType); } if (shaderType > 0) { if (MegascansUtilities.isLegacy()) { mat.shader = Shader.Find("LightweightPipeline/Standard (Physically Based)"); } else { mat.shader = Shader.Find("Lightweight Render Pipeline/Lit"); } } if (shaderType > 1) { if (isAlembic) { mat.shader = Shader.Find("Alembic/Standard"); if (texPack > 0) { mat.shader = Shader.Find("Alembic/Standard (Specular setup)"); } } else { mat.shader = Shader.Find("Standard"); if (texPack > 0) { mat.shader = Shader.Find("Standard (Specular setup)"); } } } } return(mat); } catch (Exception ex) { Debug.Log("Exception: " + ex.ToString()); MegascansUtilities.HideProgressBar(); return(null); } }
/// <summary> /// Previous version of the importer would loop through a list of texture paths, and use a bunch of if-statements and do things accordingly. /// This version just takes in every texture path and if it's not null, does the thing. Less looping, better overall performance. /// </summary> /// <param name="albedo"></param> /// <param name="opacity"></param> /// <param name="normals"></param> /// <param name="metallic"></param> /// <param name="specular"></param> /// <param name="AO"></param> /// <param name="gloss"></param> /// <param name="displacement"></param> /// <param name="roughness"></param> /// <param name="translucency"></param> Material ReadWriteAllTextures(string albedo, string opacity, string normals, string metallic, string specular, string AO, string gloss, string displacement, string roughness, string translucency) { try { Material mat = CreateMaterial(); if (mat == null) { return(null); } //create a new work thread for each texture to be processed. //Pack the opacity into the alpha channel of albedo if it exists. string texMapName = (string)mapNames["Albedo"]; tempTexName = texPath.Contains("$mapName")? texPath.Replace("$mapName", texMapName): texPath + texMapName; string p = tempTexName + ".png"; mapName = opacity != null ? "Albedo + Alpha" : "Albedo"; MegascansUtilities.UpdateProgressBar(1.0f, "Processing Asset " + assetName, "Importing texture: " + mapName); Texture2D tex = MegascansImageUtils.PackTextures(albedo, opacity, p); mat.SetTexture("_MainTex", tex); mat.SetTexture("_BaseColorMap", tex); if (shaderType == 1) { mat.SetTexture("_BaseMap", tex); mat.SetColor("_BaseColor", Color.white); } if (opacity != null) { if (shaderType > 0) { mat.SetFloat("_AlphaClip", 1); mat.SetFloat("_Mode", 1); mat.SetFloat("_Cull", 1); mat.EnableKeyword("_ALPHATEST_ON"); } else { mat.SetInt("_AlphaCutoffEnable", 1); mat.SetFloat("_AlphaCutoff", 0.333f); mat.SetInt("_DoubleSidedEnable", 1); mat.SetOverrideTag("RenderType", "TransparentCutout"); mat.SetInt("_ZTestGBuffer", (int)UnityEngine.Rendering.CompareFunction.Equal); mat.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Off); mat.SetInt("_CullModeForward", (int)UnityEngine.Rendering.CullMode.Back); mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); mat.SetInt("_ZWrite", 1); mat.renderQueue = 2450; mat.SetInt("_ZTestGBuffer", (int)UnityEngine.Rendering.CompareFunction.Equal); mat.EnableKeyword("_ALPHATEST_ON"); mat.EnableKeyword("_DOUBLESIDED_ON"); mat.DisableKeyword("_BLENDMODE_ALPHA"); mat.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); } } //test to see if gloss is absent but roughness is present... bool useRoughness = (gloss == null && roughness != null); if (texPack < 1 || shaderType < 1) { mapName = "Masks"; MegascansUtilities.UpdateProgressBar(1.0f, "Processing Asset " + assetName, "Importing texture: " + mapName); tempTexName = texPath.Contains("$mapName") ? texPath.Replace("$mapName", "Masks"): texPath + "Masks"; p = tempTexName + ".png"; mat.SetFloat("_Metallic", 1.0f); tex = MegascansImageUtils.PackTextures(metallic, AO, displacement, useRoughness ? roughness : gloss, p, useRoughness); mat.SetTexture("_MaskMap", tex); mat.EnableKeyword("_MASKMAP"); mat.SetFloat("_MaterialID", 1); mat.SetTexture("_MetallicGlossMap", tex); mat.EnableKeyword("_METALLICSPECGLOSSMAP"); mat.EnableKeyword("_METALLICGLOSSMAP"); } //do we need to process a specular map? if (texPack > 0 && specular != null) { texMapName = (string)mapNames["Specular"]; mapName = "Specular + Gloss"; MegascansUtilities.UpdateProgressBar(1.0f, "Processing Asset " + assetName, "Importing texture: " + mapName); tempTexName = texPath.Contains("$mapName") ? texPath.Replace("$mapName", texMapName): texPath + texMapName; p = tempTexName + ".png"; tex = MegascansImageUtils.PackTextures(specular, useRoughness ? roughness : gloss, p, useRoughness); mat.SetTexture("_SpecGlossMap", tex); mat.SetColor("_SpecColor", new UnityEngine.Color(1.0f, 1.0f, 1.0f)); mat.SetColor("_SpecularColor", new UnityEngine.Color(1.0f, 1.0f, 1.0f)); mat.SetFloat("_WorkflowMode", 0); mat.SetFloat("_MaterialID", 4); mat.SetTexture("_SpecularColorMap", tex); mat.EnableKeyword("_METALLICSPECGLOSSMAP"); mat.EnableKeyword("_SPECGLOSSMAP"); mat.EnableKeyword("_SPECULAR_SETUP"); mat.EnableKeyword("_SPECULARCOLORMAP"); mat.EnableKeyword("_MATERIAL_FEATURE_SPECULAR_COLOR"); } //handle any textures which can just be converted in place. if (normals != null) { texMapName = (string)mapNames["Normal"]; mapName = "Normals"; MegascansUtilities.UpdateProgressBar(1.0f, "Processing Asset " + assetName, "Importing texture: " + mapName); tempTexName = texPath.Contains("$mapName") ? texPath.Replace("$mapName", texMapName): texPath + texMapName; p = tempTexName + ".png"; MegascansImageUtils.CreateTexture(normals, p); tex = MegascansImageUtils.TextureImportSetup(p, true, false); mat.SetTexture("_BumpMap", tex); mat.SetTexture("_NormalMap", tex); mat.EnableKeyword("_NORMALMAP_TANGENT_SPACE"); mat.EnableKeyword("_NORMALMAP"); mapName = "Normals_Terrain"; tempTexName = texPath.Contains("$mapName") ? texPath.Replace("$mapName", texMapName + "_Terrain"): texPath + texMapName + "_Terrain"; p = tempTexName + ".png"; if (generateTerrainNormal && type.ToLower().Contains("surface")) { MegascansImageUtils.ImportTerrainNormal(normals, p); } } if (displacement != null && dispType > 0) { texMapName = (string)mapNames["Displacement"]; mapName = "Displacement"; MegascansUtilities.UpdateProgressBar(1.0f, "Processing Asset " + assetName, "Importing texture: " + mapName); tempTexName = texPath.Contains("$mapName") ? texPath.Replace("$mapName", texMapName): texPath + texMapName; p = tempTexName + ".png"; MegascansImageUtils.CreateTexture(displacement, p); tex = MegascansImageUtils.TextureImportSetup(p, false, false); mat.SetTexture("_HeightMap", tex); mat.SetTexture("_ParallaxMap", tex); mat.EnableKeyword("_DISPLACEMENT_LOCK_TILING_SCALE"); if (dispType == 1) { mat.EnableKeyword("_VERTEX_DISPLACEMENT"); mat.EnableKeyword("_VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE"); } if (dispType == 2) { mat.EnableKeyword("_PIXEL_DISPLACEMENT"); mat.EnableKeyword("_PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE"); } } //occlusion may or may not need to be packed, depending on the shader used. if (shaderType > 1 && AO != null) { texMapName = (string)mapNames["AO"]; mapName = "AO"; MegascansUtilities.UpdateProgressBar(1.0f, "Processing Asset " + assetName, "Importing texture: " + mapName); tempTexName = texPath.Contains("$mapName") ? texPath.Replace("$mapName", texMapName): texPath + texMapName; p = tempTexName + ".png"; MegascansImageUtils.CreateTexture(AO, p); tex = MegascansImageUtils.TextureImportSetup(p, false, false); mat.SetTexture("_OcclusionMap", tex); mat.EnableKeyword("_OCCLUSIONMAP"); } if (translucency != null) { texMapName = (string)mapNames["Translucency"]; mapName = "Translucency"; MegascansUtilities.UpdateProgressBar(1.0f, "Processing Asset " + assetName, "Importing texture: " + mapName); tempTexName = texPath.Contains("$mapName") ? texPath.Replace("$mapName", texMapName): texPath + texMapName; p = tempTexName + ".png"; tex = MegascansImageUtils.PackTextures(translucency, translucency, translucency, null, p); mat.SetInt("_MaterialID", 0); mat.SetInt("_DiffusionProfile", 1); mat.SetFloat("_EnableSubsurfaceScattering", 1); mat.SetTexture("_SubsurfaceMaskMap", tex); mat.SetTexture("_ThicknessMap", tex); if (plant) { mat.SetInt("_DiffusionProfile", 2); mat.SetFloat("_CoatMask", 0.0f); mat.SetInt("_EnableWind", 1); mat.EnableKeyword("_VERTEX_WIND"); } mat.EnableKeyword("_SUBSURFACE_MASK_MAP"); mat.EnableKeyword("_THICKNESSMAP"); mat.EnableKeyword("_MATERIAL_FEATURE_TRANSMISSION"); } return(mat); } catch (Exception ex) { Debug.Log("Exception: " + ex.ToString()); MegascansUtilities.HideProgressBar(); return(null); } }
/// <summary> /// Takes an imported JSON object, and breaks it into relevant components and data. /// Then calls relevant functions for actual import of asset. /// </summary> /// <param name="objectList"></param> public string ImportMegascansAssets(JObject objectList) { var startTime = System.DateTime.Now; activeLOD = (string)objectList["activeLOD"]; string minLOD = (string)objectList["minLOD"]; assetName = (string)objectList["name"]; type = (string)objectList["type"]; isAlembic = false; plant = false; highPoly = false; hasBillboardLOD = false; hasBillboardLODOnly = false; mapName = ""; folderNamingConvention = (string)objectList["folderNamingConvention"]; //get mesh components from the current object. JArray meshComps = (JArray)objectList["meshList"]; //run a check to see if we're using Unity 5 or below, and then if we're trying to import a high poly mesh. if so, let the user know we are aborting the import. if (meshComps.Count > 0) { isAlembic = Path.GetExtension((string)meshComps[0]["path"]) == ".abc"; } hasBillboardLOD = MegascansMeshUtils.ContainsLowestLOD((JArray)objectList["lodList"], minLOD, activeLOD); if (type.ToLower().Contains("3dplant")) { plant = true; if (minLOD == activeLOD) { hasBillboardLODOnly = true; } } try { LoadPreferences(); shaderType = MegascansUtilities.GetShaderType(); MegascansUtilities.CalculateNumberOfOperations(objectList, dispType, texPack, shaderType, hasBillboardLODOnly); path = ConstructPath(objectList); if (path == null || path == "") { Debug.Log("Asset: " + (string)objectList["name"] + " already exist in the Project. Please delete/rename the existing folder and re-import this asset."); AssetDatabase.Refresh(); return(null); } } catch (Exception ex) { Debug.Log("Error setting import path."); Debug.Log(ex.ToString()); MegascansUtilities.HideProgressBar(); } try { //process textures ProcessTextures(objectList); if (finalMat == null && !(plant && hasBillboardLODOnly)) { Debug.Log("Could not import the textures and create the material."); return(null); } else { if (type.ToLower().Contains("surface") && applyToSelection) { foreach (MeshRenderer render in MegascansUtilities.GetSelectedMeshRenderers()) { render.material = finalMat; } } } } catch (Exception ex) { Debug.Log("Error importing textures."); Debug.Log(ex.ToString()); MegascansUtilities.HideProgressBar(); } //process meshes if (meshComps == null && !type.Contains("surface")) { Debug.LogError("No meshes found. Please double check your export settings."); Debug.Log("Import failed."); return(null); } if (meshComps.Count > 0) { if (activeLOD == "high") { //detect if we're trying to import a high poly mesh... string msg = "You are about to import a high poly mesh. \nThese meshes are usually millions of polygons and can cause instability to your project. \nWould you like to proceed?"; highPoly = EditorUtility.DisplayDialog("WARNING!", msg, "Yes", "No"); } try { //process meshes and prefabs PrefabData prefData = new PrefabData(path, assetName, folderNamingConvention, lodFadeMode, highPoly, addAssetToScene, setupCollision, hasBillboardLOD, isAlembic, false, false, finalMat, billboardMat, new List <string>(), new List <List <string> >()); MegascansMeshUtils.ProcessMeshes(objectList, path, highPoly, plant, prefData); } catch (Exception ex) { Debug.Log("Error importing meshes."); Debug.Log(ex.ToString()); MegascansUtilities.HideProgressBar(); } } var endTime = System.DateTime.Now; var totalTime = endTime - startTime; Debug.Log("Asset Import Time: " + totalTime); AssetDatabase.Refresh(); MegascansUtilities.HideProgressBar(); Resources.UnloadUnusedAssets(); GC.Collect(); return(path); }
/// <summary> /// Returns the final directory for our asset, creating subfolders where necessary in the 'Assets' directory. /// </summary> string ConstructPath(JObject objectList) { /// Make sure path is "Assets/...." not "D:/Unity Projects/My Project/Assets/...." otherwise the AssetDatabase cannot write files to it. /// Lastly I also match the path with the Application DataPath in order to make sure this is the right path selected from the Bridge. AssetDatabase.Refresh(); string defPath = ""; bool addNextPathPart = false; if ((string)objectList["exportPath"] != "") { path = (string)objectList["exportPath"]; } else { defPath = "Assets"; addNextPathPart = true; } string[] pathParts = MegascansUtilities.FixSlashes(path).Split('/'); List <string> finalPathParts = new List <string> (); foreach (string part in pathParts) { if (part == "Assets" && !addNextPathPart) { addNextPathPart = true; } if (addNextPathPart) { finalPathParts.Add(part); } } if (!addNextPathPart) { return(null); } //First, create the user specified path from the importer settings. if (finalPathParts.Count > 0) { for (int i = 0; i < finalPathParts.Count; i++) { defPath = MegascansUtilities.ValidateFolderCreate(defPath, finalPathParts[i]); //FixSlashes(Path.Combine(defPath, finalPathParts[i]));//ValidateFolderCreate(defPath, finalPathParts[i]); } } if (!AssetDatabase.IsValidFolder(defPath)) { return(null); } //then create check to see if the asset type subfolder exists, create it if it doesn't. defPath = MegascansUtilities.ValidateFolderCreate(defPath, MegascansUtilities.GetAssetType((string)objectList["path"])); defPath = MegascansUtilities.ValidateFolderCreate(defPath, folderNamingConvention); return(defPath); }
/// <summary> /// Returns the final directory for our asset, creating subfolders where necessary in the 'Assets' directory. /// </summary> /// <param name="jsonPath"></param> /// <returns></returns> string ConstructPath(JObject objectList) { /// /// Unity doesn't allow you to create objects in directories which don't exist. /// So in this function, we create any and all necessary subdirectories that are required. /// We return the final subdirectory, which is used later in the asset creation too. /// A ton of project path validation /// Make sure path is "Assets/...." not "D:/Unity Projects/My Project/Assets/...." otherwise the AssetDatabase cannot write files to it. /// Lastly I also match the path with the Application DataPath in order to make sure this is the right path selected from the Bridge. /// AssetDatabase.Refresh(); string defPath = ""; bool addNextPathPart = false; if ((string)objectList["exportPath"] != "") { path = (string)objectList["exportPath"]; } else { defPath = "Assets"; addNextPathPart = true; } string[] pathParts = MegascansUtilities.FixSlashes(path).Split('/'); List <string> finalPathParts = new List <string> (); foreach (string part in pathParts) { if (part == "Assets" && !addNextPathPart) { addNextPathPart = true; } if (addNextPathPart) { finalPathParts.Add(part); } } if (!addNextPathPart) { return(null); } //First, create the user specified path from the importer settings. if (finalPathParts.Count > 0) { for (int i = 0; i < finalPathParts.Count; i++) { defPath = MegascansUtilities.ValidateFolderCreate(defPath, finalPathParts[i]); //FixSlashes(Path.Combine(defPath, finalPathParts[i]));//ValidateFolderCreate(defPath, finalPathParts[i]); } } if (!AssetDatabase.IsValidFolder(defPath)) { return(null); } //then create check to see if the asset type subfolder exists, create it if it doesn't. defPath = MegascansUtilities.ValidateFolderCreate(defPath, MegascansUtilities.GetAssetType((string)objectList["path"])); GetAssetFolderName(objectList); string finalFolderName = finalName.Replace("$mapName", "").Replace("$resolution", "").Replace("$lod", "").Replace("$variation", ""); defPath = MegascansUtilities.ValidateFolderCreate(defPath, finalFolderName); return(defPath); }
void ImportAllTextures(Material mat, JArray texturesList) { try { List <string> typesOfTexturesAvailable = new List <string>(); for (int i = 0; i < texturesList.Count; i++) { typesOfTexturesAvailable.Add((string)texturesList[i]["type"]); } string destTexPath; Texture2D tex; for (int i = 0; i < texturesList.Count; i++) { mapName = (string)texturesList[i]["type"]; MegascansUtilities.UpdateProgressBar(1.0f, "Processing Asset " + assetName, "Importing texture: " + mapName); if ((string)texturesList[i]["type"] == "albedo" || ((string)texturesList[i]["type"] == "diffuse" && !typesOfTexturesAvailable.Contains("albedo"))) { destTexPath = Path.Combine(texPath, (string)texturesList[i]["nameOverride"]); MegascansTextureProcessor texPrcsr = new MegascansTextureProcessor((string)texturesList[i]["path"], destTexPath); tex = texPrcsr.ImportTexture(); mat.SetTexture("_MainTex", tex); mat.SetTexture("_BaseColorMap", tex); if (shaderType == 1) { mat.SetTexture("_BaseMap", tex); mat.SetColor("_BaseColor", Color.white); } if (MegascansUtilities.AlbedoHasOpacity((JObject)texturesList[i]["channelsData"])) { float alphaCutoff = 0.33f; texPrcsr.AdjustAlphaCutoff(); if (shaderType > 0) { mat.SetFloat("_AlphaClip", 1); mat.SetFloat("_Cutoff", 0.1f); mat.SetFloat("_Mode", 1); mat.SetFloat("_Cull", 0); mat.EnableKeyword("_ALPHATEST_ON"); } else { mat.SetInt("_AlphaCutoffEnable", 1); mat.SetFloat("_AlphaCutoff", alphaCutoff); mat.SetInt("_DoubleSidedEnable", 1); mat.SetOverrideTag("RenderType", "TransparentCutout"); mat.SetInt("_ZTestGBuffer", (int)UnityEngine.Rendering.CompareFunction.Equal); mat.SetInt("_CullMode", (int)UnityEngine.Rendering.CullMode.Off); mat.SetInt("_CullModeForward", (int)UnityEngine.Rendering.CullMode.Back); mat.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); mat.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); mat.SetInt("_ZWrite", 1); mat.renderQueue = 2450; mat.SetInt("_ZTestGBuffer", (int)UnityEngine.Rendering.CompareFunction.Equal); mat.EnableKeyword("_ALPHATEST_ON"); mat.EnableKeyword("_DOUBLESIDED_ON"); mat.DisableKeyword("_BLENDMODE_ALPHA"); mat.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); } } } else if ((string)texturesList[i]["type"] == "specular") { if (texPack > 0) { destTexPath = Path.Combine(texPath, (string)texturesList[i]["nameOverride"]); MegascansTextureProcessor texPrcsr = new MegascansTextureProcessor((string)texturesList[i]["path"], destTexPath); tex = texPrcsr.ImportTexture(); mat.SetTexture("_SpecGlossMap", tex); mat.SetTexture("_SpecularColorMap", tex); mat.SetColor("_SpecColor", new UnityEngine.Color(1.0f, 1.0f, 1.0f)); mat.SetColor("_SpecularColor", new UnityEngine.Color(1.0f, 1.0f, 1.0f)); mat.SetFloat("_WorkflowMode", 0); mat.SetFloat("_MaterialID", 4); mat.EnableKeyword("_METALLICSPECGLOSSMAP"); mat.EnableKeyword("_SPECGLOSSMAP"); mat.EnableKeyword("_SPECULAR_SETUP"); mat.EnableKeyword("_SPECULARCOLORMAP"); mat.EnableKeyword("_MATERIAL_FEATURE_SPECULAR_COLOR"); } } else if ((string)texturesList[i]["type"] == "masks") { if (texPack < 1 || shaderType < 1) { destTexPath = Path.Combine(texPath, (string)texturesList[i]["nameOverride"]); MegascansTextureProcessor texPrcsr = new MegascansTextureProcessor((string)texturesList[i]["path"], destTexPath, false, false); tex = texPrcsr.ImportTexture(); mat.SetTexture("_MaskMap", tex); mat.SetTexture("_MetallicGlossMap", tex); mat.EnableKeyword("_MASKMAP"); mat.SetFloat("_MaterialID", 1); mat.EnableKeyword("_METALLICSPECGLOSSMAP"); mat.EnableKeyword("_METALLICGLOSSMAP"); bool hasMetalness; bool hasAO; bool hasGloss; MegascansUtilities.MaskMapComponents((JObject)texturesList[i]["channelsData"], out hasMetalness, out hasAO, out hasGloss); if (!hasMetalness) { mat.SetFloat("_Metallic", 1.0f); } if (hasAO) { mat.SetTexture("_OcclusionMap", tex); mat.EnableKeyword("_OCCLUSIONMAP"); } } } else if ((string)texturesList[i]["type"] == "normal") { string normalMapPath = (string)texturesList[i]["path"]; if (activeLOD == "high" && !normalMapPath.Contains("NormalBump")) { for (int x = 0; x < 10; x++) { string n = normalMapPath.Replace("_LOD" + x.ToString(), "Bump"); if (File.Exists(n)) { normalMapPath = n; break; } } if (normalMapPath.Contains("NormalBump")) { continue; } } destTexPath = Path.Combine(texPath, (string)texturesList[i]["nameOverride"]); MegascansTextureProcessor texPrcsr = new MegascansTextureProcessor(normalMapPath, destTexPath, true, false); tex = texPrcsr.ImportTexture(); mat.SetTexture("_BumpMap", tex); mat.SetTexture("_NormalMap", tex); mat.EnableKeyword("_NORMALMAP_TANGENT_SPACE"); mat.EnableKeyword("_NORMALMAP"); } else if ((string)texturesList[i]["type"] == "ao" && texPack > 0) { destTexPath = Path.Combine(texPath, (string)texturesList[i]["nameOverride"]); MegascansTextureProcessor texPrcsr = new MegascansTextureProcessor((string)texturesList[i]["path"], destTexPath, false, false); tex = texPrcsr.ImportTexture(); mat.SetTexture("_OcclusionMap", tex); mat.EnableKeyword("_OCCLUSIONMAP"); } else if ((string)texturesList[i]["type"] == "displacement") { if (dispType > 0) { destTexPath = Path.Combine(texPath, (string)texturesList[i]["nameOverride"]); MegascansTextureProcessor texPrcsr = new MegascansTextureProcessor((string)texturesList[i]["path"], destTexPath, false, false); tex = texPrcsr.ImportTexture(); mat.SetTexture("_HeightMap", tex); mat.SetTexture("_ParallaxMap", tex); mat.EnableKeyword("_DISPLACEMENT_LOCK_TILING_SCALE"); if (shaderType == 0) { mat.EnableKeyword("_HEIGHTMAP"); } if (dispType == 1) { mat.EnableKeyword("_VERTEX_DISPLACEMENT"); mat.EnableKeyword("_VERTEX_DISPLACEMENT_LOCK_OBJECT_SCALE"); } else if (dispType == 2) { mat.EnableKeyword("_PARALLAXMAP"); mat.EnableKeyword("_PIXEL_DISPLACEMENT"); mat.EnableKeyword("_PIXEL_DISPLACEMENT_LOCK_OBJECT_SCALE"); } } } else if ((string)texturesList[i]["type"] == "translucency") { destTexPath = Path.Combine(texPath, (string)texturesList[i]["nameOverride"]); MegascansTextureProcessor texPrcsr = new MegascansTextureProcessor((string)texturesList[i]["path"], destTexPath); tex = texPrcsr.ImportTexture(); mat.SetTexture("_SubsurfaceMaskMap", tex); mat.EnableKeyword("_SUBSURFACE_MASK_MAP"); mat.SetInt("_DiffusionProfile", 1); mat.SetFloat("_EnableSubsurfaceScattering", 1); if (!typesOfTexturesAvailable.Contains("transmission")) { mat.SetTexture("_ThicknessMap", tex); mat.EnableKeyword("_THICKNESSMAP"); } if (plant) { mat.SetInt("_DiffusionProfile", 2); mat.SetFloat("_CoatMask", 0.0f); mat.SetInt("_EnableWind", 1); mat.EnableKeyword("_VERTEX_WIND"); } MegascansMaterialUtils.AddSSSSettings(mat, shaderType); } else if ((string)texturesList[i]["type"] == "transmission") { destTexPath = Path.Combine(texPath, (string)texturesList[i]["nameOverride"]); MegascansTextureProcessor texPrcsr = new MegascansTextureProcessor((string)texturesList[i]["path"], destTexPath, false, false); tex = texPrcsr.ImportTexture(); mat.SetTexture("_ThicknessMap", tex); mat.EnableKeyword("_THICKNESSMAP"); mat.SetInt("_DiffusionProfile", 2); MegascansMaterialUtils.AddSSSSettings(mat, shaderType); } else if (importAllTextures) { mapName = (string)texturesList[i]["type"]; string mapPath = (string)texturesList[i]["path"]; string otherTexFolder = MegascansUtilities.ValidateFolderCreate(texPath, "Others"); destTexPath = Path.Combine(otherTexFolder, (string)texturesList[i]["nameOverride"]); MegascansTextureProcessor texPrcsr = new MegascansTextureProcessor(mapPath, destTexPath); tex = texPrcsr.ImportTexture(); } } } catch (Exception ex) { Debug.Log("Exception::MegascansImporter::ImportAllTextures:: " + ex.ToString()); MegascansUtilities.HideProgressBar(); } }
void OnGUI() { GUI.DrawTexture(new Rect(0, 0, maxSize.x, maxSize.y), MSBackground, ScaleMode.StretchToFill); GUILayout.BeginHorizontal(); GUILayout.Box("Bridge Plugin v" + version, MSHeadingTextStyle, GUILayout.Height(textHeadingSize.y)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button(MSLogo, MSLogoStyle, GUILayout.Height(logoSize.y), GUILayout.Width(logoSize.x))) { Application.OpenURL("https://quixel.com/megascans/library/latest"); } if (GUILayout.Button(BridgeLogo, MSLogoStyle, GUILayout.Height(logoSize.y), GUILayout.Width(logoSize.x))) { Application.OpenURL("https://quixel.com/bridge"); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); tab = GUILayout.Toolbar(tab, new string[] { "Settings", "Utilities" }, MSTabsStyle, GUILayout.Height(textSize.y)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); Handles.color = Color.white; Handles.DrawLine(new Vector3(0f, lineYLoc), new Vector3(maxSize.x, lineYLoc)); GUILayout.EndHorizontal(); if (tab == 0) { GUILayout.BeginHorizontal(); GUILayout.Label("Workflow", MSText, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); texPack = EditorGUILayout.Popup(texPack, texPacking, MSPopup, GUILayout.Height(fieldSize.y)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Label("Displacement", MSText, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); dispType = EditorGUILayout.Popup(dispType, dispTypes, MSPopup, GUILayout.Height(fieldSize.y)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Box("Shader Type", MSText, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); shaderType = EditorGUILayout.Popup(shaderType, shaderTypes, MSPopup, GUILayout.Height(fieldSize.y)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Box("Import Resolution", MSText, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); importResolution = EditorGUILayout.Popup(importResolution, importResolutions, MSPopup, GUILayout.Height(fieldSize.y)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Box("LOD Fade Mode", MSText, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); lodFadeMode = EditorGUILayout.Popup(lodFadeMode, lodFadeModeSettings, MSPopup, GUILayout.Height(fieldSize.y)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Box("Import Path", MSText, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); path = EditorGUILayout.TextField(path, MSField, GUILayout.Height(fieldSize.y)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); setupCollision = EditorGUI.Toggle(collisionLoc, setupCollision, MSCheckBox); GUILayout.Box("Setup Collision", MSNormalTextStyle, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); applyToSelection = EditorGUI.Toggle(applyToSelectionLoc, applyToSelection, MSCheckBox); GUILayout.Box("Apply To Selection (2D Surfaces)", MSNormalTextStyle, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); addAssetToScene = EditorGUI.Toggle(addAssetToSceneLoc, addAssetToScene, MSCheckBox); GUILayout.Box("Add Asset to the Scene", MSNormalTextStyle, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); setupPrefabs = EditorGUI.Toggle(setupPrefabsLoc, setupPrefabs, MSCheckBox); GUILayout.Box("Create Prefabs", MSNormalTextStyle, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); importLODs = EditorGUI.Toggle(importLODsLoc, importLODs, MSCheckBox); GUILayout.Box("Import Lower LODs", MSNormalTextStyle, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); setupLOD = EditorGUI.Toggle(setupLODLoc, setupLOD, MSCheckBox); GUILayout.Box("Create LOD Groups", MSNormalTextStyle, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); importAllTextures = EditorGUI.Toggle(importAllTexturesLoc, importAllTextures, MSCheckBox); GUILayout.Box("Import All Textures", MSNormalTextStyle, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); connection = EditorGUI.Toggle(connectionLoc, connection, MSCheckBox); GUILayout.Box("Enable Plugin", MSNormalTextStyle, GUILayout.Height(textSize.y)); if (GUILayout.Button("Help...", MSHelpStyle, GUILayout.Width(textSize.x))) { Application.OpenURL("https://docs.google.com/document/d/1NUAh2vQ9UgK-c1J-yhVnqkTgqZxMVm77rRK-X1ukWw0/"); } GUILayout.EndHorizontal(); } else { #if (UNITY_2018 || UNITY_2019 || UNITY_2020) GUILayout.BeginHorizontal(); GUILayout.Box("Terrain Tools (Beta)", MSHeadingTextStyle, GUILayout.Height(textHeadingSize.y)); GUILayout.EndHorizontal(); if (MegascansUtilities.isLegacy()) { GUILayout.BeginHorizontal(); GUILayout.Box("Material Name", MSText, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); terrainMaterialName = EditorGUILayout.TextField(terrainMaterialName, MSField, GUILayout.Height(fieldSize.y), GUILayout.Width(fieldSize.x)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Box("Material Path", MSText, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); terrainMaterialPath = EditorGUILayout.TextField(terrainMaterialPath, MSField, GUILayout.Height(fieldSize.y), GUILayout.Width(fieldSize.x)); GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(); GUILayout.Box("Texture Tiling", MSText, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); tiling = EditorGUILayout.TextField(tiling, MSField, GUILayout.Height(fieldSize.y)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Setup Paint Layers", MSStrechedWidthStyle, GUILayout.Height(textSize.y))) { MegascansTerrainTools.SetupTerrain(); } GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); string warningMsg = "Warning: This feature works properly with the metallic workflow only."; if (MegascansUtilities.isLegacy()) { warningMsg += "This feature requires HD Render Pipeline."; } GUI.skin.label.wordWrap = true; GUILayout.Label(warningMsg, MSWarningTextStyle, GUILayout.Height(textSize.y)); GUILayout.EndHorizontal(); #endif #if (UNITY_2018_3 || UNITY_2018_4 || UNITY_2019 || UNITY_2020) GUILayout.BeginHorizontal(); GUILayout.Box("Material Tools (Beta)", MSHeadingTextStyle, GUILayout.Height(textHeadingSize.y)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); if (GUILayout.Button("Create Terrain Paint Layer", MSStrechedWidthStyle, GUILayout.Height(textSize.y))) { MegascansTerrainTools.CreateTerrainLayerFromMat(); } GUILayout.EndHorizontal(); #endif #if HDRP && (UNITY_2018_2 || UNITY_2018_3 || UNITY_2018_4 || UNITY_2019 || UNITY_2020) GUILayout.BeginHorizontal(); GUILayout.Box("Decal Setup (Beta)", MSHeadingTextStyle, GUILayout.Height(textHeadingSize.y)); GUILayout.EndHorizontal(); GUILayout.BeginHorizontal(); GUILayout.Box("Global Opacity (%)", MSText, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); decalBlend = EditorGUILayout.TextField(decalBlend, MSField, GUILayout.Height(fieldSize.y)); GUILayout.EndHorizontal(); if (!MegascansUtilities.isLegacy()) { GUILayout.BeginHorizontal(); GUILayout.Box("Scale", MSText, GUILayout.Height(textSize.y), GUILayout.Width(textSize.x)); decalSize = EditorGUILayout.TextField(decalSize, MSField, GUILayout.Height(fieldSize.y)); GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(); if (GUILayout.Button("Create Decal Projector", MSStrechedWidthStyle, GUILayout.Height(textSize.y))) { MegascansDecalTools.SetupDecalProjector(); } GUILayout.EndHorizontal(); #endif } if (!MSLogo) { InitStyle(); Repaint(); } }
/// <summary> /// Takes an imported JSON object, and breaks it into relevant components and data. /// Then calls relevant functions for actual import of asset. /// </summary> /// <param name="objectList"></param> public string ImportMegascansAssets(JObject objectList) { var startTime = System.DateTime.Now; string activeLOD = (string)objectList["activeLOD"]; string minLOD = (string)objectList["minLOD"]; isAlembic = false; plant = false; highPoly = false; hasBillboardLOD = false; hasBillboardLODOnly = false; mapName = ""; //get texture components from the current object. JArray textureComps = (JArray)objectList["components"]; //get mesh components from the current object. JArray meshComps = (JArray)objectList["meshList"]; //Map name overrides. mapNames = (JObject)objectList["mapNameOverride"]; //run a check to see if we're using Unity 5 or below, and then if we're trying to import a high poly mesh. if so, let the user know we are aborting the import. if (meshComps.Count > 0) { isAlembic = Path.GetExtension((string)meshComps[0]["path"]) == ".abc"; } hasBillboardLOD = MegascansMeshUtils.ContainsLowestLOD((JArray)objectList["lodList"], minLOD); assetType = (int)objectList["meshVersion"]; type = (string)objectList["type"]; if (type.ToLower().Contains("3dplant")) { plant = true; if (minLOD == activeLOD) { hasBillboardLODOnly = true; } } try { LoadPreferences(); MegascansUtilities.CalculateNumberOfOperations(objectList, dispType, texPack, shaderType, generateTerrainNormal, hasBillboardLODOnly); path = ConstructPath(objectList); if (path == null || path == "") { Debug.Log("Asset: " + (string)objectList["name"] + " already exist in the Project. Please delete/rename the existing folder and re-import this asset."); AssetDatabase.Refresh(); return(null); } GetShaderType(); } catch (Exception ex) { Debug.Log("Error setting import path."); Debug.Log(ex.ToString()); MegascansUtilities.HideProgressBar(); } try { //process textures ProcessTextures(textureComps); if (finalMat == null && !(plant && hasBillboardLODOnly)) { Debug.Log("The import path is incorrect. Asset import aborted."); return(null); } else { if (type.ToLower().Contains("surface") && applyToSelection) { foreach (MeshRenderer render in MegascansUtilities.GetSelectedMeshRenderers()) { render.material = finalMat; } } } } catch (Exception ex) { Debug.Log("Error importing textures."); Debug.Log(ex.ToString()); MegascansUtilities.HideProgressBar(); } //process meshes if (meshComps == null && !type.Contains("surface")) { Debug.LogError("No meshes found. Please double check your export settings."); Debug.Log("Import failed."); return(null); } if (meshComps.Count > 0) { if (activeLOD == "high") { //detect if we're trying to import a high poly mesh... string msg = "You are about to import a high poly mesh. \nThese meshes are usually millions of polygons and can cause instability to your project. \nWould you like to proceed?"; if (EditorUtility.DisplayDialog("WARNING!", msg, "Yes", "No")) { #if UNITY_EDITOR_WIN hpMat = new Material(finalMat.shader); hpMat.CopyPropertiesFromMaterial(finalMat); hpMat.SetTexture("_NormalMap", null); hpMat.SetTexture("_BumpMap", null); hpMat.DisableKeyword("_NORMALMAP_TANGENT_SPACE"); hpMat.DisableKeyword("_NORMALMAP"); hpMat.name = MegascansUtilities.FixSpaces(new string[] { hpMat.name, "HighPoly" }); string hpMatDir = MegascansUtilities.FixSpaces(new string[] { matPath, "HighPoly.mat" }); AssetDatabase.CreateAsset(hpMat, hpMatDir); #endif highPoly = true; } } try { //process meshes and prefabs PrefabData prefData = new PrefabData(path, finalName, lodFadeMode, highPoly, addAssetToScene, setupCollision, hasBillboardLOD, isAlembic, false, finalMat, hpMat, billboardMat, new List <string>(), new List <List <string> >()); MegascansMeshUtils.ProcessMeshes(objectList, path, highPoly, plant, prefData); } catch (Exception ex) { Debug.Log("Error importing meshes."); Debug.Log(ex.ToString()); MegascansUtilities.HideProgressBar(); } } var endTime = System.DateTime.Now; var totalTime = endTime - startTime; Debug.Log("Asset Import Time: " + totalTime); AssetDatabase.Refresh(); MegascansUtilities.HideProgressBar(); //Application.GarbageCollectUnusedAssets(); return(path); }