private void OnEnable() { script = (GrassColorMapRenderer)target; colorMap = serializedObject.FindProperty("colorMap"); resIdx = serializedObject.FindProperty("resIdx"); resolution = serializedObject.FindProperty("resolution"); renderLayer = serializedObject.FindProperty("renderLayer"); useLayers = serializedObject.FindProperty("useLayers"); terrainObjects = serializedObject.FindProperty("terrainObjects"); if (!script.colorMap) { script.colorMap = ColorMapEditor.NewColorMap(); } }
public override void OnInspectorGUI() { serializedObject.Update(); EditorGUI.BeginChangeCheck(); using (new EditorGUILayout.HorizontalScope()) { EditorGUILayout.PropertyField(colorMap); if (colorMap.objectReferenceValue) { /* * if (GUILayout.Button(new GUIContent(" Edit", EditorGUIUtility.IconContent(EditorGUIUtility.isProSkin ? "d_editicon.sml" : "editicon.sml").image), GUILayout.MaxWidth(70f))) * { * Selection.activeObject = colorMap.objectReferenceValue; * } */ if (GUILayout.Button(new GUIContent(" New", EditorGUIUtility.IconContent(EditorGUIUtility.isProSkin ? "d_editicon.sml" : "editicon.sml").image), GUILayout.MaxWidth(70f))) { colorMap.objectReferenceValue = ColorMapEditor.NewColorMap(); } } } if (!colorMap.objectReferenceValue) { EditorGUILayout.HelpBox("No color map assigned", MessageType.Error); return; } if (colorMap.objectReferenceValue) { //EditorGUILayout.LabelField(string.Format("Area size: {0}x{1}", script.colorMap.bounds.size.x, script.colorMap.bounds.size.z)); if (EditorUtility.IsPersistent(script.colorMap) == false) { Action saveColorMap = new Action(SaveColorMap); StylizedGrassGUI.DrawActionBox(" The color map asset has not been saved to a file\n and can only be used in this scene", "Save", MessageType.Warning, saveColorMap); } if (script.colorMap.overrideTexture) { EditorGUILayout.HelpBox("The assigned color map uses a texture override. Rendering a new/updated color map will revert this.", MessageType.Warning); } } EditorGUILayout.Space(); StylizedGrassGUI.ParameterGroup.DrawHeader(new GUIContent("Render area")); using (new EditorGUILayout.VerticalScope(StylizedGrassGUI.ParameterGroup.Section)) { EditorGUI.indentLevel++; EditorGUILayout.PropertyField(terrainObjects); EditorGUI.indentLevel--; using (new EditorGUILayout.HorizontalScope()) { GUILayout.FlexibleSpace(); #if VEGETATION_STUDIO_PRO if (GUILayout.Button("Add VSP mesh terrains")) { AwesomeTechnologies.MeshTerrains.MeshTerrain[] terrains = GameObject.FindObjectsOfType <AwesomeTechnologies.MeshTerrains.MeshTerrain>(); for (int i = 0; i < terrains.Length; i++) { if (script.terrainObjects.Contains(terrains[i].gameObject) == false) { script.terrainObjects.Add(terrains[i].gameObject); } } } #endif if (GUILayout.Button("Add active terrains")) { Terrain[] terrains = Terrain.activeTerrains; for (int i = 0; i < terrains.Length; i++) { if (script.terrainObjects.Contains(terrains[i].gameObject) == false) { script.terrainObjects.Add(terrains[i].gameObject); } } RefreshLayerNames(); } if (GUILayout.Button("Add child meshes")) { //All childs, recursive MeshRenderer[] children = script.gameObject.GetComponentsInChildren <MeshRenderer>(); for (int i = 0; i < children.Length; i++) { if (script.terrainObjects.Contains(children[i].gameObject) == false) { script.terrainObjects.Add(children[i].gameObject); } } } if (GUILayout.Button("Clear")) { terrainObjects.ClearArray(); } } EditorGUILayout.Space(); EditMode.DoEditModeInspectorModeButton(EditMode.SceneViewEditMode.Collider, "Edit Volume", EditorGUIUtility.IconContent("EditCollider"), GetBounds, this); script.colorMap.bounds.size = EditorGUILayout.Vector3Field("Size", script.colorMap.bounds.size); script.colorMap.bounds.center = EditorGUILayout.Vector3Field("Center", script.colorMap.bounds.center); if (script.colorMap.bounds.size == Vector3.zero && terrainObjects.arraySize == 0) { EditorGUILayout.HelpBox("The render area cannot be zero", MessageType.Error); } if (script.colorMap.bounds.size == Vector3.zero && terrainObjects.arraySize > 0) { EditorGUILayout.HelpBox("The render area will be automatically calculate based on terrain size", MessageType.Info); } using (new EditorGUI.DisabledGroupScope(script.terrainObjects.Count == 0)) { using (new EditorGUILayout.HorizontalScope()) { GUILayout.FlexibleSpace(); if (GUILayout.Button("Calculate from terrain(s)")) { ColorMapEditor.ApplyUVFromTerrainBounds(colorMap.objectReferenceValue as GrassColorMap, script); SceneView.RepaintAll(); } } } } EditorGUILayout.Space(); StylizedGrassGUI.ParameterGroup.DrawHeader(new GUIContent("Layer-based grass scale (experimental)")); using (new EditorGUILayout.VerticalScope(StylizedGrassGUI.ParameterGroup.Section)) { DrawLayerHeightSettings(); } EditorGUILayout.Space(); StylizedGrassGUI.ParameterGroup.DrawHeader(new GUIContent("Rendering")); using (new EditorGUILayout.VerticalScope(StylizedGrassGUI.ParameterGroup.Section)) { EditorGUILayout.PropertyField(useLayers); if (useLayers.boolValue) { EditorGUILayout.PropertyField(renderLayer); if (renderLayer.intValue == 0) { EditorGUILayout.HelpBox("The render layer is set to \"Nothing\", no objects will be rendered into the color map", MessageType.Error); } } using (new EditorGUILayout.HorizontalScope()) { resIdx.intValue = EditorGUILayout.Popup("Resolution", resIdx.intValue, ColorMapEditor.reslist, new GUILayoutOption[0]); if (GUILayout.Button("Render")) { ColorMapEditor.RenderColorMap((GrassColorMapRenderer)target); } } } if (EditorGUI.EndChangeCheck()) { resolution.intValue = ColorMapEditor.IndexToResolution(resIdx.intValue); serializedObject.ApplyModifiedProperties(); } EditorGUILayout.LabelField("- Staggart Creations -", EditorStyles.centeredGreyMiniLabel); }
private void SaveColorMap() { ColorMapEditor.SaveColorMapToAsset(colorMap.objectReferenceValue as GrassColorMap); }
public override void OnPreviewGUI(Rect r, GUIStyle background) { if (script.colorMap.texture == null) { return; } if (previewColor) { GUI.DrawTexture(r, script.colorMap.texture, ScaleMode.ScaleToFit, false); } else { EditorGUI.DrawTextureAlpha(r, script.colorMap.texture, ScaleMode.ScaleToFit); } Rect btnRect = r; btnRect.x += 10f; btnRect.y += 10f; btnRect.width = 50f; btnRect.height = 20f; previewColor = GUI.Toggle(btnRect, previewColor, new GUIContent("Color"), "Button"); btnRect.x += 49f; previewColor = !GUI.Toggle(btnRect, !previewColor, new GUIContent("Scale"), "Button"); GUI.Label(new Rect(r.width * 0.5f - (175 * 0.5f), r.height - 5, 175, 25), string.Format("{0} texel(s) per meter", ColorMapEditor.GetTexelSize(script.colorMap.texture.height, script.colorMap.bounds.size.x)), EditorStyles.toolbarButton); }
private void DrawLayerHeightSettings() { if (layerNames == null) { EditorGUILayout.HelpBox("This feature only works with Unity terrains (The first item in the Terrain Objects list isn't a terrain)", MessageType.Info); return; } if (script.layerScaleSettings != null && script.layerScaleSettings.Count > 0) { EditorGUILayout.HelpBox("Currently ALL terrain layers have to be configured", MessageType.Info); using (new EditorGUILayout.VerticalScope()) { EditorGUI.BeginChangeCheck(); for (int i = 0; i < script.layerScaleSettings.Count; i++) { GrassColorMapRenderer.LayerScaleSettings s = script.layerScaleSettings[i]; using (new EditorGUILayout.HorizontalScope()) { /* * if (GUILayout.Button("▲")) * { * script.layerHeightSettings.RemoveAt(i); * script.layerHeightSettings.Insert(i - 1, s); * } * if (GUILayout.Button("▼")) * { * script.layerHeightSettings.RemoveAt(i); * script.layerHeightSettings.Insert(i + 1, s); * } */ s.layerID = EditorGUILayout.Popup(s.layerID, layerNames, GUILayout.MaxWidth(150f)); float strength = s.strength * 100f; strength = EditorGUILayout.Slider(strength, 1f, 100f); s.strength = strength * 0.01f; EditorGUILayout.LabelField("%", GUILayout.MaxWidth(20f)); if (GUILayout.Button(new GUIContent("", EditorGUIUtility.IconContent("d_TreeEditor.Trash").image, "Delete item"))) { script.layerScaleSettings.RemoveAt(i); } } } if (EditorGUI.EndChangeCheck()) { ColorMapEditor.RenderColorMap((GrassColorMapRenderer)target); } } } else { EditorGUILayout.LabelField("No height settings for terrain layers, grass will stay a uniform scale"); } using (new EditorGUI.DisabledScope(script.layerScaleSettings.Count == terrainLayerCount)) { using (new EditorGUILayout.HorizontalScope()) { GUILayout.FlexibleSpace(); if (GUILayout.Button(new GUIContent("Add layer setting", EditorGUIUtility.IconContent(EditorGUIUtility.isProSkin ? "d_Toolbar Plus" : "Toolbar Plus").image))) { GrassColorMapRenderer.LayerScaleSettings s = new GrassColorMapRenderer.LayerScaleSettings(); s.layerID = script.layerScaleSettings.Count; script.layerScaleSettings.Add(s); ColorMapEditor.RenderColorMap((GrassColorMapRenderer)target); } } } }
public override void OnPreviewGUI(Rect r, GUIStyle background) { if (!script.vectorRT) { return; } GUI.DrawTexture(r, script.vectorRT, ScaleMode.ScaleToFit); Rect btnRect = r; btnRect.x += 5f; btnRect.y += 5f; btnRect.width = 150f; btnRect.height = 20f; script.debug = GUI.Toggle(btnRect, script.debug, new GUIContent(" Pin to viewport")); GUI.Label(new Rect(r.width * 0.5f - (175 * 0.5f), r.height - 5, 175, 25), string.Format("{0} texel(s) per meter", ColorMapEditor.GetTexelSize(script.vectorRT.height, script.resolution)), EditorStyles.toolbarButton); }
private static void GenerateScalemap(List <Terrain> terrains, GrassColorMapRenderer renderer, RenderTexture rgb) { if (terrains.Count == 0) { return; } if (renderer.layerScaleSettings.Count > 0) { Material originalMaterial = terrains[0].materialTemplate; splatExtractionMat = new Material(Shader.Find("Hidden/TerrainSplatmask")); //Temporarily override terrain material foreach (Terrain t in terrains) { t.materialTemplate = splatExtractionMat; } RenderTexture alphaBuffer = new RenderTexture(renderer.resolution, renderer.resolution, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); RenderTexture heightmapBuffer = new RenderTexture(renderer.resolution, renderer.resolution, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); RenderTexture heightmap = new RenderTexture(renderer.resolution, renderer.resolution, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); Shader.SetGlobalTexture("_InputAlphamap", alphaBuffer); Shader.SetGlobalTexture("_InputHeightmap", heightmap); MaterialPropertyBlock props = new MaterialPropertyBlock(); //Sort by strength List <GrassColorMapRenderer.LayerScaleSettings> settings = renderer.layerScaleSettings.OrderByDescending(o => o.strength).ToList(); int currentSplatIndex = 0; foreach (GrassColorMapRenderer.LayerScaleSettings layer in renderer.layerScaleSettings) { int splatmapID = GetSplatmapID(layer.layerID); Shader.SetGlobalVector("_SplatMask", ColorMapEditor.GetVectorMask(layer.layerID)); Shader.SetGlobalFloat("_SplatChannelStrength", layer.strength); //Terrain render splatmap 0 by default, force to render next splatmap in base pass if (splatmapID != currentSplatIndex) { //Debug.Log("layer.layerID requres splatmap switch to " + splatmapID); foreach (Terrain t in terrains) { props.SetTexture("_Control", t.terrainData.GetAlphamapTexture(splatmapID)); t.SetSplatMaterialPropertyBlock(props); } currentSplatIndex = splatmapID; } //Render now visible alpha weight into buffer renderer.renderCam.targetTexture = alphaBuffer; renderer.renderCam.Render(); //Max blending copy here! Graphics.Blit(alphaBuffer, heightmapBuffer, splatExtractionMat, (int)Pass.MaxBlend); Graphics.Blit(heightmapBuffer, heightmap); } //Fill any black pixels with white (taking into account blank splatmap channels) Shader.SetGlobalTexture("_InputHeightmap", heightmapBuffer); Graphics.Blit(null, heightmap, splatExtractionMat, (int)Pass.FillWhite); //Restore materials foreach (Terrain t in terrains) { t.materialTemplate = originalMaterial; t.SetSplatMaterialPropertyBlock(null); } //Add heightmap to alpha channel of rgb map RenderTexture colorBuffer = new RenderTexture(rgb); Graphics.Blit(rgb, colorBuffer); Shader.SetGlobalTexture("_InputColormap", rgb); Shader.SetGlobalTexture("_InputHeightmap", heightmap); Graphics.Blit(null, colorBuffer, splatExtractionMat, (int)Pass.AlphaMerge); Graphics.Blit(colorBuffer, rgb); //Graphics.Blit(heightmap, rgb); renderer.colorMap.hasScalemap = true; } else { renderer.colorMap.hasScalemap = false; } }
public static void ApplyUVFromTerrainBounds(GrassColorMap colorMap, GrassColorMapRenderer renderer) { colorMap.bounds = ColorMapEditor.GetTerrainBounds(renderer.terrainObjects); colorMap.uv = ColorMapEditor.BoundsToUV(renderer.colorMap.bounds); }
public override void OnPreviewGUI(Rect r, GUIStyle background) { if (script.colorMap.texture == null) { return; } GUI.DrawTexture(r, script.colorMap.texture, ScaleMode.ScaleToFit); GUI.Label(new Rect(r.width * 0.5f - (175 * 0.5f), r.height - 5, 175, 25), string.Format("{0} texel(s) per meter", ColorMapEditor.GetTexelSize(script.colorMap.texture.height, script.colorMap.bounds.size.x)), EditorStyles.toolbarButton); }