public override void OnInspectorGUI() { MicroSplatTerrain t = target as MicroSplatTerrain; if (t == null) { EditorGUILayout.HelpBox("No Terrain Present, please put this component on a terrain", MessageType.Error); return; } EditorGUI.BeginChangeCheck(); t.templateMaterial = EditorGUILayout.ObjectField(CTemplateMaterial, t.templateMaterial, typeof(Material), false) as Material; if (EditorGUI.EndChangeCheck()) { MicroSplatTerrain.SyncAll(); } EditorGUI.BeginChangeCheck(); if (DoConvertGUI(t)) { return; } if (t.templateMaterial == null) { return; } if (t.propData == null) { t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); EditorUtility.SetDirty(t); MicroSplatObject.SyncAll(); } if (t.keywordSO == null) { t.keywordSO = MicroSplatUtilities.FindOrCreateKeywords(t.templateMaterial); EditorUtility.SetDirty(t); } EditorGUI.BeginChangeCheck(); #if __MICROSPLAT_PROCTEX__ if (t.keywordSO.IsKeywordEnabled("_PROCEDURALTEXTURE") || t.keywordSO.IsKeywordEnabled("_PCHEIGHTGRADIENT") || t.keywordSO.IsKeywordEnabled("_PCHEIGHTHSV")) { var old = t.procTexCfg; t.procTexCfg = MicroSplatProceduralTexture.FindOrCreateProceduralConfig(t.templateMaterial); if (old != t.procTexCfg) { EditorUtility.SetDirty(t); MicroSplatObject.SyncAll(); } } #endif #if __MICROSPLAT_TERRAINBLEND__ || __MICROSPLAT_STREAMS__ DoTerrainDescGUI(); #endif DoPerPixelNormalGUI(); #if __MICROSPLAT_PROCTEX__ if (t.keywordSO.IsKeywordEnabled(MicroSplatProceduralTexture.GetFeatureName(MicroSplatProceduralTexture.DefineFeature._PCCAVITY)) || t.keywordSO.IsKeywordEnabled(MicroSplatProceduralTexture.GetFeatureName(MicroSplatProceduralTexture.DefineFeature._PCFLOW))) { DoCavityMapGUI(); } #endif // could move this to some type of interfaced component created by the module if this becomes a thing, // but I think this will be most of the cases? MicroSplatUtilities.DrawTextureField(t, CCustomSplat0, ref t.customControl0, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat1, ref t.customControl1, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat2, ref t.customControl2, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat3, ref t.customControl3, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat4, ref t.customControl4, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat5, ref t.customControl5, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat6, ref t.customControl6, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat7, ref t.customControl7, "_CUSTOMSPLATTEXTURES"); // perpixel normal MicroSplatUtilities.DrawTextureField(t, perPixelNormal, ref t.perPixelNormal, "_PERPIXELNORMAL"); // global texture overrides #if __MICROSPLAT_GLOBALTEXTURE__ MicroSplatUtilities.DrawTextureField(t, geoTexOverride, ref t.geoTextureOverride, "_GEOMAP"); MicroSplatUtilities.DrawTextureField(t, geoTintOverride, ref t.tintMapOverride, "_GLOBALTINT"); MicroSplatUtilities.DrawTextureField(t, geoNormalOverride, ref t.globalNormalOverride, "_GLOBALNORMALS"); MicroSplatUtilities.DrawTextureField(t, geoSAOMOverride, ref t.globalSAOMOverride, "_GLOBALSMOOTHAOMETAL"); MicroSplatUtilities.DrawTextureField(t, geoEmisOverride, ref t.globalEmisOverride, "_GLOBALEMIS"); #endif #if __MICROSPLAT_SNOW__ MicroSplatUtilities.DrawTextureField(t, snowMaskOverride, ref t.snowMaskOverride, "_SNOWMASK"); #endif #if __MICROSPLAT_ALPHAHOLE__ // alpha hole override MicroSplatUtilities.DrawTextureField(t, clipMapOverride, ref t.clipMap, "_ALPHAHOLETEXTURE"); #endif #if (VEGETATION_STUDIO || VEGETATION_STUDIO_PRO) // vsstudio overrides MicroSplatUtilities.DrawTextureField(t, CVSGrassMap, ref t.vsGrassMap, "_VSGRASSMAP"); MicroSplatUtilities.DrawTextureField(t, CVSShadowMap, ref t.vsShadowMap, "_VSSHADOWMAP"); #endif #if __MICROSPLAT_PROCTEX__ MicroSplatUtilities.DrawTextureField(t, biomeOverride, ref t.procBiomeMask, "_PROCEDURALTEXTURE"); #endif #if __MICROSPLAT_STREAMS__ MicroSplatUtilities.DrawTextureField(t, streamOverride, ref t.streamTexture, "_WETNESS", "_PUDDLES", "_STREAMS", "_LAVA", false); #endif #if __MICROSPLAT_ADVANCED_DETAIL__ DrawAdvancedModuleDetailGUI(t); #endif if (t.propData == null && t.templateMaterial != null) { t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); if (t.propData == null) { // this should really never happen, but users seem to have issues with unassigned propData's a lot. I think // this is from external tools like MapMagic not creating it, but the above call should create it. EditorGUILayout.HelpBox("PropData is null, please assign", MessageType.Error); t.propData = EditorGUILayout.ObjectField("Per Texture Data", t.propData, typeof(MicroSplatPropData), false) as MicroSplatPropData; } } if (EditorGUI.EndChangeCheck()) { MicroSplatTerrain.SyncAll(); } EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Sync")) { var mgr = target as MicroSplatTerrain; mgr.Sync(); } if (GUILayout.Button("Sync All")) { MicroSplatTerrain.SyncAll(); } EditorGUILayout.EndHorizontal(); BakingGUI(t); WeightLimitingGUI(t); ImportExportGUI(); #if __MICROSPLAT_ADVANCED_DETAIL__ DrawAdvancedModuleDetailTooset(t); #endif if (MicroSplatUtilities.DrawRollup("Debug", false, true)) { EditorGUI.indentLevel += 2; EditorGUILayout.HelpBox("These should not need to be edited unless something funky has happened. They are automatically managed by MicroSplat.", MessageType.Info); t.propData = EditorGUILayout.ObjectField("Per Texture Data", t.propData, typeof(MicroSplatPropData), false) as MicroSplatPropData; #if __MICROSPLAT_PROCTEX__ t.procTexCfg = EditorGUILayout.ObjectField("Procedural Config", t.procTexCfg, typeof(MicroSplatProceduralTextureConfig), false) as MicroSplatProceduralTextureConfig; #endif t.keywordSO = EditorGUILayout.ObjectField("Keywords", t.keywordSO, typeof(MicroSplatKeywords), false) as MicroSplatKeywords; t.blendMat = EditorGUILayout.ObjectField(CBlendMat, t.blendMat, typeof(Material), false) as Material; t.addPass = EditorGUILayout.ObjectField("Add Pass", t.addPass, typeof(Shader), false) as Shader; EditorGUI.indentLevel -= 2; } if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(t); } }
public override void OnInspectorGUI() { MicroSplatTerrain t = target as MicroSplatTerrain; if (t == null) { EditorGUILayout.HelpBox("No Terrain Present, please put this component on a terrain", MessageType.Error); return; } EditorGUI.BeginChangeCheck(); t.templateMaterial = EditorGUILayout.ObjectField(CTemplateMaterial, t.templateMaterial, typeof(Material), false) as Material; if (t.templateMaterial == null) { if (GUILayout.Button("Convert to MicroSplat")) { // get all terrains in selection, not just this one, and treat as one giant terrain var objs = Selection.gameObjects; List <Terrain> terrains = new List <Terrain>(); for (int i = 0; i < objs.Length; ++i) { Terrain ter = objs[i].GetComponent <Terrain>(); if (ter != null) { terrains.Add(ter); } Terrain[] trs = objs[i].GetComponentsInChildren <Terrain>(); for (int x = 0; x < trs.Length; ++x) { if (!terrains.Contains(trs[x])) { terrains.Add(trs[x]); } } } // setup this terrain Terrain terrain = t.GetComponent <Terrain>(); t.templateMaterial = MicroSplatShaderGUI.NewShaderAndMaterial(terrain); var config = TextureArrayConfigEditor.CreateConfig(terrain); t.templateMaterial.SetTexture("_Diffuse", config.diffuseArray); t.templateMaterial.SetTexture("_NormalSAO", config.normalSAOArray); t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); #if UNITY_2018_3_OR_NEWER if (terrain.terrainData.terrainLayers.Length > 0) { var uvScale = terrain.terrainData.terrainLayers[0].tileSize; var uvOffset = terrain.terrainData.terrainLayers[0].tileOffset; uvScale = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain); uvOffset.x = uvScale.x / terrain.terrainData.size.x * 0.5f * uvOffset.x; uvOffset.y = uvScale.y / terrain.terrainData.size.x * 0.5f * uvOffset.y; Vector4 scaleOffset = new Vector4(uvScale.x, uvScale.y, uvOffset.x, uvOffset.y); t.templateMaterial.SetVector("_UVScale", scaleOffset); } #else if (terrain.terrainData.splatPrototypes.Length > 0) { var uvScale = terrain.terrainData.splatPrototypes[0].tileSize; var uvOffset = terrain.terrainData.splatPrototypes[0].tileOffset; uvScale = MicroSplatRuntimeUtil.UnityUVScaleToUVScale(uvScale, terrain); uvOffset.x = uvScale.x / terrain.terrainData.size.x * 0.5f * uvOffset.x; uvOffset.y = uvScale.y / terrain.terrainData.size.x * 0.5f * uvOffset.y; Vector4 scaleOffset = new Vector4(uvScale.x, uvScale.y, uvOffset.x, uvOffset.y); t.templateMaterial.SetVector("_UVScale", scaleOffset); } #endif // now make sure others all have the same settings as well. for (int i = 0; i < terrains.Count; ++i) { var nt = terrains[i]; var mgr = nt.GetComponent <MicroSplatTerrain>(); if (mgr == null) { mgr = nt.gameObject.AddComponent <MicroSplatTerrain>(); } mgr.templateMaterial = t.templateMaterial; if (mgr.propData == null) { mgr.propData = MicroSplatShaderGUI.FindOrCreatePropTex(mgr.templateMaterial); } } Selection.SetActiveObjectWithContext(config, config); } MicroSplatTerrain.SyncAll(); return; } if (t.propData == null) { t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); EditorUtility.SetDirty(t); } if (t.keywordSO == null) { t.keywordSO = MicroSplatUtilities.FindOrCreateKeywords(t.templateMaterial); EditorUtility.SetDirty(t); } EditorGUI.BeginChangeCheck(); #if __MICROSPLAT_PROCTEX__ if (t.keywordSO.IsKeywordEnabled("_PROCEDURALTEXTURE") || t.keywordSO.IsKeywordEnabled("_PCHEIGHTGRADIENT") || t.keywordSO.IsKeywordEnabled("_PCHEIGHTHSV")) { var old = t.procTexCfg; t.procTexCfg = MicroSplatProceduralTexture.FindOrCreateProceduralConfig(t.templateMaterial); if (old != t.procTexCfg) { EditorUtility.SetDirty(t); } } #endif #if __MICROSPLAT_TERRAINBLEND__ || __MICROSPLAT_STREAMS__ DoTerrainDescGUI(); #endif DoPerPixelNormalGUI(); #if __MICROSPLAT_PROCTEX__ if (t.keywordSO.IsKeywordEnabled(MicroSplatProceduralTexture.GetFeatureName(MicroSplatProceduralTexture.DefineFeature._PCCAVITY)) || t.keywordSO.IsKeywordEnabled(MicroSplatProceduralTexture.GetFeatureName(MicroSplatProceduralTexture.DefineFeature._PCFLOW))) { DoCavityMapGUI(); } #endif // could move this to some type of interfaced component created by the module if this becomes a thing, // but I think this will be most of the cases? MicroSplatUtilities.DrawTextureField(t, CCustomSplat0, ref t.customControl0, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat1, ref t.customControl1, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat2, ref t.customControl2, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat3, ref t.customControl3, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat4, ref t.customControl4, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat5, ref t.customControl5, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat6, ref t.customControl6, "_CUSTOMSPLATTEXTURES"); MicroSplatUtilities.DrawTextureField(t, CCustomSplat7, ref t.customControl7, "_CUSTOMSPLATTEXTURES"); // perpixel normal MicroSplatUtilities.DrawTextureField(t, perPixelNormal, ref t.perPixelNormal, "_PERPIXELNORMAL"); // global texture overrides #if __MICROSPLAT_GLOBALTEXTURE__ MicroSplatUtilities.DrawTextureField(t, geoTexOverride, ref t.geoTextureOverride, "_GEOMAP"); MicroSplatUtilities.DrawTextureField(t, geoTintOverride, ref t.tintMapOverride, "_GLOBALTINT"); MicroSplatUtilities.DrawTextureField(t, geoNormalOverride, ref t.globalNormalOverride, "_GLOBALNORMALS"); MicroSplatUtilities.DrawTextureField(t, geoSAOMOverride, ref t.globalSAOMOverride, "_GLOBALSMOOTHAOMETAL"); MicroSplatUtilities.DrawTextureField(t, geoEmisOverride, ref t.globalEmisOverride, "_GLOBALEMIS"); #endif #if __MICROSPLAT_ALPHAHOLE__ // alpha hole override MicroSplatUtilities.DrawTextureField(t, clipMapOverride, ref t.clipMap, "_ALPHAHOLETEXTURE"); #endif #if (VEGETATION_STUDIO || VEGETATION_STUDIO_PRO) // vsstudio overrides MicroSplatUtilities.DrawTextureField(t, CVSGrassMap, ref t.vsGrassMap, "_VSGRASSMAP"); MicroSplatUtilities.DrawTextureField(t, CVSShadowMap, ref t.vsShadowMap, "_VSSHADOWMAP"); #endif #if __MICROSPLAT_PROCTEX__ MicroSplatUtilities.DrawTextureField(t, biomeOverride, ref t.procBiomeMask, "_PROCEDURALTEXTURE"); #endif #if __MICROSPLAT_ADVANCED_DETAIL__ DrawAdvancedModuleDetailGUI(t); #endif if (t.propData == null && t.templateMaterial != null) { t.propData = MicroSplatShaderGUI.FindOrCreatePropTex(t.templateMaterial); if (t.propData == null) { // this should really never happen, but users seem to have issues with unassigned propData's a lot. I think // this is from external tools like MapMagic not creating it, but the above call should create it. EditorGUILayout.HelpBox("PropData is null, please assign", MessageType.Error); t.propData = EditorGUILayout.ObjectField("Per Texture Data", t.propData, typeof(MicroSplatPropData), false) as MicroSplatPropData; } } if (EditorGUI.EndChangeCheck()) { MicroSplatTerrain.SyncAll(); } EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Sync")) { var mgr = target as MicroSplatTerrain; mgr.Sync(); } if (GUILayout.Button("Sync All")) { MicroSplatTerrain.SyncAll(); } EditorGUILayout.EndHorizontal(); BakingGUI(t); WeightLimitingGUI(t); ImportExportGUI(); #if __MICROSPLAT_ADVANCED_DETAIL__ DrawAdvancedModuleDetailTooset(t); #endif if (MicroSplatUtilities.DrawRollup("Debug", false, true)) { EditorGUI.indentLevel += 2; EditorGUILayout.HelpBox("These should not need to be edited unless something funky has happened. They are automatically managed by MicroSplat.", MessageType.Info); t.propData = EditorGUILayout.ObjectField("Per Texture Data", t.propData, typeof(MicroSplatPropData), false) as MicroSplatPropData; #if __MICROSPLAT_PROCTEX__ t.procTexCfg = EditorGUILayout.ObjectField("Procedural Config", t.procTexCfg, typeof(MicroSplatProceduralTextureConfig), false) as MicroSplatProceduralTextureConfig; #endif t.keywordSO = EditorGUILayout.ObjectField("Keywords", t.keywordSO, typeof(MicroSplatKeywords), false) as MicroSplatKeywords; t.blendMat = EditorGUILayout.ObjectField(CBlendMat, t.blendMat, typeof(Material), false) as Material; t.terrainDesc = EditorGUILayout.ObjectField("Terrain Descriptor", t.terrainDesc, typeof(Texture2D), false) as Texture2D; t.perPixelNormal = EditorGUILayout.ObjectField("Normal Data", t.perPixelNormal, typeof(Texture2D), false) as Texture2D; t.addPass = EditorGUILayout.ObjectField("Add Pass", t.addPass, typeof(Shader), false) as Shader; EditorGUI.indentLevel -= 2; } if (EditorGUI.EndChangeCheck()) { EditorUtility.SetDirty(t); } }