public void Compile(Material m, string shaderName = null) { int hash = 0; MicroSplatKeywords keywords = MicroSplatUtilities.FindOrCreateKeywords(m); for (int i = 0; i < keywords.keywords.Count; ++i) { hash += 31 + keywords.keywords [i].GetHashCode(); } var path = AssetDatabase.GetAssetPath(m.shader); string nm = m.shader.name; if (!string.IsNullOrEmpty(shaderName)) { nm = shaderName; } string baseName = "Hidden/" + nm + "_Base" + hash.ToString(); string terrainShader = Compile(keywords.keywords.ToArray(), nm, baseName); if (renderLoop != null) { keywords.EnableKeyword(renderLoop.GetRenderLoopKeyword()); } GenerateAuxShaders(nm, path, keywords.keywords); MicroSplatUtilities.Checkout(path); System.IO.File.WriteAllText(path, terrainShader); if (!keywords.IsKeywordEnabled("_MICROMESH") && !keywords.IsKeywordEnabled("_MICROVERTEXMESH") && !keywords.IsKeywordEnabled("_MEGASPLAT") && !keywords.IsKeywordEnabled("_MICROTERRAINMESH")) { // generate fallback string[] oldKeywords = new string[keywords.keywords.Count]; System.Array.Copy(keywords.keywords.ToArray(), oldKeywords, keywords.keywords.Count); keywords.DisableKeyword("_TESSDISTANCE"); keywords.DisableKeyword("_PARALLAX"); keywords.DisableKeyword("_DETAILNOISE"); keywords.EnableKeyword("_MICROSPLATBASEMAP"); string fallback = Compile(keywords.keywords.ToArray(), baseName); keywords.keywords = new List <string> (oldKeywords); string fallbackPath = path.Replace(".shader", "_Base.shader"); MicroSplatUtilities.Checkout(fallbackPath); System.IO.File.WriteAllText(fallbackPath, fallback); } EditorUtility.SetDirty(m); AssetDatabase.Refresh(); #if __MICROSPLAT_MESH__ MicroSplatMesh.ClearMaterialCache(); #endif MicroSplatObject.SyncAll(); }
protected bool DrawGlobalToggle(string keyword, MicroSplatKeywords keywords) { bool b = keywords.IsKeywordEnabled(keyword); if (globalButtonPressedStyle == null) { globalButtonPressedStyle = new GUIStyle(GUI.skin.label); globalButtonPressedStyle.normal.background = new Texture2D(1, 1); globalButtonPressedStyle.normal.background.SetPixel(0, 0, Color.yellow); globalButtonPressedStyle.normal.background.Apply(); globalButtonPressedStyle.normal.textColor = Color.black; } bool pressed = (GUILayout.Button(globalButton, b ? globalButtonPressedStyle : GUI.skin.label, GUILayout.Width(14))); if (pressed) { if (b) { keywords.DisableKeyword(keyword); } else { keywords.EnableKeyword(keyword); } b = !b; EditorUtility.SetDirty(keywords); } return(b); }
static bool PerTexToggle(MicroSplatKeywords keywords, string keyword) { if (drawPertexToggle) { bool enabled = keywords.IsKeywordEnabled(keyword); bool newEnabled = EditorGUILayout.Toggle(enabled, GUILayout.Width(20)); if (enabled != newEnabled) { if (newEnabled) { keywords.EnableKeyword(keyword); } else { keywords.DisableKeyword(keyword); } } return(newEnabled); } else { EditorGUILayout.LabelField("", GUILayout.Width(noPerTexToggleWidth)); drawPertexToggle = true; return(keywords.IsKeywordEnabled(keyword)); } }
bool DrawRenderLoopGUI(MicroSplatKeywords keywords, Material targetMat) { #if UNITY_2018_1_OR_NEWER // init render loop name list if (renderLoopNames == null || renderLoopNames.Length != availableRenderLoops.Count) { var rln = new List <GUIContent>(); for (int i = 0; i < availableRenderLoops.Count; ++i) { rln.Add(new GUIContent(availableRenderLoops[i].GetDisplayName())); } renderLoopNames = rln.ToArray(); } if (renderLoopNames.Length == 1) { return(false); } int curRenderLoopIndex = 0; for (int i = 0; i < keywords.keywords.Count; ++i) { string s = keywords.keywords[i]; for (int j = 0; j < availableRenderLoops.Count; ++j) { if (s == availableRenderLoops[j].GetRenderLoopKeyword()) { curRenderLoopIndex = j; compiler.renderLoop = availableRenderLoops[j]; break; } } } int oldIdx = curRenderLoopIndex; curRenderLoopIndex = EditorGUILayout.Popup(CRenderLoop, curRenderLoopIndex, renderLoopNames); if (oldIdx != curRenderLoopIndex && curRenderLoopIndex >= 0 && curRenderLoopIndex < availableRenderLoops.Count) { if (compiler.renderLoop != null) { keywords.DisableKeyword(compiler.renderLoop.GetRenderLoopKeyword()); } compiler.renderLoop = availableRenderLoops[curRenderLoopIndex]; keywords.EnableKeyword(compiler.renderLoop.GetRenderLoopKeyword()); return(true); } #endif #if UNITY_2018_3_OR_NEWER if (targetMat != null && !targetMat.enableInstancing) { EditorUtility.SetDirty(targetMat); targetMat.enableInstancing = true; } #endif return(false); }
public void Pack(MicroSplatKeywords keywords) { var pck = Pack(); for (int i = 0; i < pck.Length; ++i) { keywords.EnableKeyword(pck[i]); } }
public void Compile(Material m, string shaderName = null) { int hash = 0; MicroSplatKeywords keywords = MicroSplatUtilities.FindOrCreateKeywords(m); for (int i = 0; i < keywords.keywords.Count; ++i) { hash += 31 + keywords.keywords [i].GetHashCode(); } var path = AssetDatabase.GetAssetPath(m.shader); string nm = m.shader.name; if (!string.IsNullOrEmpty(shaderName)) { nm = shaderName; } string baseName = "Hidden/" + nm + "_Base" + hash.ToString(); string terrainShader = Compile(keywords.keywords.ToArray(), nm, baseName); if (renderLoop != null) { keywords.EnableKeyword(renderLoop.GetRenderLoopKeyword()); } string blendShader = null; // strip extra feature from terrain blending to make it cheaper if (keywords.IsKeywordEnabled("_TERRAINBLENDING")) { List <string> blendKeywords = new List <string> (keywords.keywords); if (keywords.IsKeywordEnabled("_TBDISABLE_DETAILNOISE") && blendKeywords.Contains("_DETAILNOISE")) { blendKeywords.Remove("_DETAILNOISE"); } if (keywords.IsKeywordEnabled("_TBDISABLE_DETAILNOISE") && blendKeywords.Contains("_ANTITILEARRAYDETAIL")) { blendKeywords.Remove("_ANTITILEARRAYDETAIL"); } if (keywords.IsKeywordEnabled("_TBDISABLE_DISTANCENOISE") && blendKeywords.Contains("_DISTANCENOISE")) { blendKeywords.Remove("_DISTANCENOISE"); } if (keywords.IsKeywordEnabled("_TBDISABLE_DISTANCENOISE") && blendKeywords.Contains("_ANTITILEARRAYDISTANCE")) { blendKeywords.Remove("_ANTITILEARRAYDISTANCE"); } if (keywords.IsKeywordEnabled("_TBDISABLE_DISTANCERESAMPLE") && blendKeywords.Contains("_DISTANCERESAMPLE")) { blendKeywords.Remove("_DISTANCERESAMPLE"); } blendShader = Compile(blendKeywords.ToArray(), nm, null, true); } string meshBlendShader = null; if (keywords.IsKeywordEnabled("_MESHOVERLAYSPLATS")) { List <string> blendKeywords = new List <string> (keywords.keywords); if (blendKeywords.Contains("_TESSDISTANCE")) { blendKeywords.Remove("_TESSDISTANCE"); } meshBlendShader = Compile(blendKeywords.ToArray(), nm, null, true); } MicroSplatUtilities.Checkout(path); System.IO.File.WriteAllText(path, terrainShader); if (!keywords.IsKeywordEnabled("_MICROMESH")) { // generate fallback string[] oldKeywords = new string[keywords.keywords.Count]; System.Array.Copy(keywords.keywords.ToArray(), oldKeywords, keywords.keywords.Count); keywords.DisableKeyword("_TESSDISTANCE"); keywords.DisableKeyword("_PARALLAX"); keywords.DisableKeyword("_DETAILNOISE"); keywords.EnableKeyword("_MICROSPLATBASEMAP"); string fallback = Compile(keywords.keywords.ToArray(), baseName); keywords.keywords = new List <string> (oldKeywords); string fallbackPath = path.Replace(".shader", "_Base.shader"); MicroSplatUtilities.Checkout(fallbackPath); System.IO.File.WriteAllText(fallbackPath, fallback); } string terrainBlendPath = path.Replace(".shader", "_TerrainObjectBlend.shader"); string meshBlendPath = path.Replace(".shader", "_MeshOverlay.shader"); if (blendShader != null) { MicroSplatUtilities.Checkout(terrainBlendPath); System.IO.File.WriteAllText(terrainBlendPath, blendShader); } if (meshBlendShader != null) { MicroSplatUtilities.Checkout(meshBlendPath); System.IO.File.WriteAllText(meshBlendPath, meshBlendShader); } EditorUtility.SetDirty(m); AssetDatabase.Refresh(); MicroSplatObject.SyncAll(); }
void CompressTerrainSplats(MicroSplatTerrain t) { int splatCount = t.terrain.terrainData.alphamapTextureCount; // write out for (int i = 0; i < splatCount; ++i) { var tex = t.terrain.terrainData.GetAlphamapTexture(i); var path = MicroSplatUtilities.RelativePathFromAsset(t); path += "/" + t.name + "_splat" + i + ".tga"; System.IO.File.WriteAllBytes(path, tex.EncodeToTGA()); } AssetDatabase.Refresh(); // load and adjust importer for (int i = 0; i < splatCount; ++i) { var path = MicroSplatUtilities.RelativePathFromAsset(t); path += "/" + t.name + "_splat" + i + ".tga"; var tex = CompressTexture(path, false); if (i == 0) { t.customControl0 = tex; } else if (i == 1) { t.customControl1 = tex; } else if (i == 2) { t.customControl2 = tex; } else if (i == 3) { t.customControl3 = tex; } else if (i == 4) { t.customControl4 = tex; } else if (i == 5) { t.customControl5 = tex; } else if (i == 6) { t.customControl6 = tex; } else if (i == 7) { t.customControl7 = tex; } } EditorUtility.SetDirty(t); MicroSplatKeywords keywords = MicroSplatUtilities.FindOrCreateKeywords(t.templateMaterial); if (!keywords.IsKeywordEnabled("_CUSTOMSPLATTEXTURES")) { keywords.EnableKeyword("_CUSTOMSPLATTEXTURES"); MicroSplatShaderGUI.MicroSplatCompiler compiler = new MicroSplatShaderGUI.MicroSplatCompiler(); compiler.Compile(t.templateMaterial); MicroSplatTerrain.SyncAll(); } // destructive operation t.terrain.terrainData.alphamapResolution = 16; }