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); }
void RevertTerrainSplats(MicroSplatTerrain t) { MicroSplatKeywords keywords = MicroSplatUtilities.FindOrCreateKeywords(t.templateMaterial); if (keywords.IsKeywordEnabled("_CUSTOMSPLATTEXTURES")) { if (t.customControl0 == null) { Debug.LogError("Could not revert terrain because textures are missing!"); return; } UncompressTexture(t.customControl0); UncompressTexture(t.customControl1); UncompressTexture(t.customControl2); UncompressTexture(t.customControl3); UncompressTexture(t.customControl4); UncompressTexture(t.customControl5); UncompressTexture(t.customControl6); UncompressTexture(t.customControl7); int size = t.customControl0.width; int layers = t.terrain.terrainData.alphamapLayers; t.terrain.terrainData.alphamapResolution = size; var maps = t.terrain.terrainData.GetAlphamaps(0, 0, size, size); ExtractSplats(ref maps, t.customControl0, 0, layers); ExtractSplats(ref maps, t.customControl1, 4, layers); ExtractSplats(ref maps, t.customControl2, 8, layers); ExtractSplats(ref maps, t.customControl3, 12, layers); ExtractSplats(ref maps, t.customControl4, 16, layers); ExtractSplats(ref maps, t.customControl5, 20, layers); ExtractSplats(ref maps, t.customControl6, 24, layers); ExtractSplats(ref maps, t.customControl7, 28, layers); t.terrain.terrainData.SetAlphamaps(0, 0, maps); EditorUtility.SetDirty(t.terrain.terrainData); keywords.DisableKeyword("_CUSTOMSPLATTEXTURES"); MicroSplatShaderGUI.MicroSplatCompiler compiler = new MicroSplatShaderGUI.MicroSplatCompiler(); compiler.Compile(t.templateMaterial); t.customControl0 = null; t.customControl1 = null; t.customControl2 = null; t.customControl3 = null; t.customControl4 = null; t.customControl5 = null; t.customControl6 = null; t.customControl7 = null; EditorUtility.SetDirty(t); MicroSplatTerrain.SyncAll(); } }
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(); }