private void PaintAlphamap(Terrain sampleTerrain, Terrain targetTerrain, BrushTransform sampleXform, BrushTransform targetXform, Material mat) { Rect sampleRect = sampleXform.GetBrushXYBounds(); Rect targetRect = targetXform.GetBrushXYBounds(); int numSampleTerrainLayers = sampleTerrain.terrainData.terrainLayers.Length; for (int i = 0; i < numSampleTerrainLayers; ++i) { TerrainLayer layer = sampleTerrain.terrainData.terrainLayers[i]; if (layer == null) { continue; // nothing to paint if the layer is NULL } PaintContext sampleContext = TerrainPaintUtility.BeginPaintTexture(sampleTerrain, sampleRect, layer); // manually create target context since we are possibly applying another terrain's layers and not its own int layerIndex = TerrainPaintUtility.FindTerrainLayerIndex(sampleTerrain, layer); Texture2D layerTexture = TerrainPaintUtility.GetTerrainAlphaMapChecked(sampleTerrain, layerIndex >> 2); PaintContext targetContext = PaintContext.CreateFromBounds(targetTerrain, targetRect, layerTexture.width, layerTexture.height); targetContext.CreateRenderTargets(RenderTextureFormat.R8); targetContext.GatherAlphamap(layer, true); sampleContext.sourceRenderTexture.filterMode = FilterMode.Point; mat.SetTexture("_CloneTex", sampleContext.sourceRenderTexture); Graphics.Blit(targetContext.sourceRenderTexture, targetContext.destinationRenderTexture, mat, (int)ShaderPasses.CloneAlphamap); // apply texture modifications and perform cleanup. same thing as calling TerrainPaintUtility.EndPaintTexture targetContext.ScatterAlphamap("Terrain Paint - Clone Brush (Texture)"); targetContext.Cleanup(); } }
public override void OnInspectorGUI(Terrain terrain, IOnInspectorGUI editContext) { GUILayout.Label("Settings", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); EditorGUILayout.Space(); Editor.DrawFoldoutInspector(terrain.materialTemplate, ref m_TemplateMaterialEditor); EditorGUILayout.Space(); if (m_SelectedTerrainLayerIndex == -1) { m_SelectedTerrainLayerIndex = TerrainPaintUtility.FindTerrainLayerIndex(terrain, m_SelectedTerrainLayer); } m_SelectedTerrainLayerIndex = TerrainLayerUtility.ShowTerrainLayersSelectionHelper(terrain, m_SelectedTerrainLayerIndex); EditorGUILayout.Space(); if (EditorGUI.EndChangeCheck()) { m_SelectedTerrainLayer = m_SelectedTerrainLayerIndex != -1 ? terrain.terrainData.terrainLayers[m_SelectedTerrainLayerIndex] : null; Save(true); } terrain.materialTemplate.SetFloat("_NumLayersCount", terrain.terrainData.terrainLayers.Length); TerrainLayerUtility.ShowTerrainLayerGUI(terrain, m_SelectedTerrainLayer, ref m_SelectedTerrainLayerInspector, (m_TemplateMaterialEditor as MaterialEditor)?.customShaderGUI as ITerrainLayerCustomUI); EditorGUILayout.Space(); int textureRez = terrain.terrainData.alphamapResolution; editContext.ShowBrushesGUI(5, BrushGUIEditFlags.All, textureRez); }
public override void OnInspectorGUI(Terrain terrain, IOnInspectorGUI editContext) { GUILayout.Label("Settings", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); EditorGUILayout.Space(); Editor.DrawFoldoutInspector(terrain.materialTemplate, ref m_TemplateMaterialEditor); EditorGUILayout.Space(); int layerIndex = TerrainPaintUtility.FindTerrainLayerIndex(terrain, m_SelectedTerrainLayer); layerIndex = TerrainLayerUtility.ShowTerrainLayersSelectionHelper(terrain, layerIndex); EditorGUILayout.Space(); if (EditorGUI.EndChangeCheck()) { m_SelectedTerrainLayer = layerIndex != -1 ? terrain.terrainData.terrainLayers[layerIndex] : null; Save(true); } TerrainLayerUtility.ShowTerrainLayerGUI(terrain, m_SelectedTerrainLayer, ref m_SelectedTerrainLayerInspector, (m_TemplateMaterialEditor as MaterialEditor)?.customShaderGUI as ITerrainLayerCustomUI); EditorGUILayout.Space(); editContext.ShowBrushesGUI(5); }
public override bool OnPaint(Terrain terrain, IOnPaint editContext) { BrushTransform targetBrushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 1); Material mat = GetPaintMaterial(); Vector4 brushParams = new Vector4(editContext.brushStrength, 0, 0, 0f); mat.SetTexture("_BrushTex", editContext.brushTexture); mat.SetVector("_BrushParams", brushParams); Rect targetRect = targetBrushXform.GetBrushXYBounds(); int numSampleTerrainLayers = terrain.terrainData.terrainLayers.Length; for (int i = 0; i < numSampleTerrainLayers; ++i) { TerrainLayer layer = terrain.terrainData.terrainLayers[i]; if (layer == null) { continue; } int layerIndex = TerrainPaintUtility.FindTerrainLayerIndex(terrain, layer); Texture2D layerTexture = TerrainPaintUtility.GetTerrainAlphaMapChecked(terrain, layerIndex >> 2); PaintContext targetContext = PaintContext.CreateFromBounds(terrain, targetRect, layerTexture.width, layerTexture.height); targetContext.CreateRenderTargets(RenderTextureFormat.R8); targetContext.GatherAlphamap(layer, true); Graphics.Blit(targetContext.sourceRenderTexture, targetContext.destinationRenderTexture, mat, 0); TerrainPaintUtility.EndPaintTexture(targetContext, "Terrain Paint - Smooth Splatmaps"); } return(false); }
public override void OnInspectorGUI(Terrain terrain, IOnInspectorGUI editContext) { GUILayout.Label("Settings", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); EditorGUILayout.Space(); var cacheFieldWidth = EditorGUIUtility.fieldWidth; var cacheLabelWIdth = EditorGUIUtility.labelWidth; Editor.DrawFoldoutInspector(terrain.materialTemplate, ref m_TemplateMaterialEditor); EditorGUIUtility.fieldWidth = cacheFieldWidth; EditorGUIUtility.labelWidth = cacheLabelWIdth; EditorGUILayout.Space(); if (m_SelectedTerrainLayerIndex == -1) { m_SelectedTerrainLayerIndex = TerrainPaintUtility.FindTerrainLayerIndex(terrain, m_SelectedTerrainLayer); } m_SelectedTerrainLayerIndex = TerrainLayerUtility.ShowTerrainLayersSelectionHelper(terrain, m_SelectedTerrainLayerIndex); EditorGUILayout.Space(); if (EditorGUI.EndChangeCheck()) { m_SelectedTerrainLayer = m_SelectedTerrainLayerIndex != -1 ? terrain.terrainData.terrainLayers[m_SelectedTerrainLayerIndex] : null; Save(true); } TerrainLayerUtility.ShowTerrainLayerGUI(terrain, m_SelectedTerrainLayer, ref m_SelectedTerrainLayerInspector, (m_TemplateMaterialEditor as MaterialEditor)?.customShaderGUI as ITerrainLayerCustomUI); EditorGUILayout.Space(); // Texture painting needs to know the largest of the splat map and the height map, as the result goes to // the splat map, but the height map is used for previewing. int resolution = Mathf.Max(terrain.terrainData.heightmapResolution, terrain.terrainData.alphamapResolution); editContext.ShowBrushesGUI(5, BrushGUIEditFlags.All, resolution); }
private void PaintAlphamap(Terrain sampleTerrain, Terrain targetTerrain, BrushTransform sampleXform, BrushTransform targetXform, Material mat) { Rect sampleRect = sampleXform.GetBrushXYBounds(); Rect targetRect = targetXform.GetBrushXYBounds(); int numSampleTerrainLayers = sampleTerrain.terrainData.terrainLayers.Length; for (int i = 0; i < numSampleTerrainLayers; ++i) { TerrainLayer layer = sampleTerrain.terrainData.terrainLayers[i]; if (layer == null) { continue; // nothing to paint if the layer is NULL } PaintContext sampleContext = TerrainPaintUtility.BeginPaintTexture(sampleTerrain, sampleRect, layer); int layerIndex = TerrainPaintUtility.FindTerrainLayerIndex(sampleTerrain, layer); Texture2D layerTexture = TerrainPaintUtility.GetTerrainAlphaMapChecked(sampleTerrain, layerIndex >> 2); PaintContext targetContext = PaintContext.CreateFromBounds(targetTerrain, targetRect, layerTexture.width, layerTexture.height); targetContext.CreateRenderTargets(RenderTextureFormat.R8); targetContext.GatherAlphamap(layer, true); sampleContext.sourceRenderTexture.filterMode = FilterMode.Point; mat.SetTexture("_CloneTex", sampleContext.sourceRenderTexture); mat.SetVector("_SampleUVScaleOffset", ComputeSampleUVScaleOffset(sampleContext, targetContext)); var brushMask = RTUtils.GetTempHandle(targetContext.sourceRenderTexture.width, targetContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, targetContext.sourceRenderTexture, brushMask, mat); TerrainPaintUtility.SetupTerrainToolMaterialProperties(targetContext, targetXform, mat); Graphics.Blit(targetContext.sourceRenderTexture, targetContext.destinationRenderTexture, mat, (int)ShaderPasses.CloneAlphamap); // apply texture modifications and perform cleanup. same thing as calling TerrainPaintUtility.EndPaintTexture targetContext.ScatterAlphamap("Terrain Paint - Clone Brush (Texture)"); // Restores RenderTexture.active targetContext.Cleanup(); RTUtils.Release(brushMask); } }
public override void OnInspectorGUI(Terrain terrain, IOnInspectorGUI editContext) { GUILayout.Label("Settings", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); m_SplatAlpha = EditorGUILayout.Slider("Target Strength", m_SplatAlpha, 0.0F, 1.0F); EditorGUILayout.Space(); if (m_TemplateMaterialEditor != null && m_TemplateMaterialEditor.target != terrain.materialTemplate) { UnityEngine.Object.DestroyImmediate(m_TemplateMaterialEditor); m_TemplateMaterialEditor = null; } if (m_TemplateMaterialEditor == null && terrain.materialTemplate != null) { m_TemplateMaterialEditor = Editor.CreateEditor(terrain.materialTemplate) as MaterialEditor; m_TemplateMaterialEditor.firstInspectedEditor = true; } if (m_TemplateMaterialEditor != null) { DrawFoldoutEditor(m_TemplateMaterialEditor, kTemplateMaterialEditorControl, ref m_ShowMaterialEditor); EditorGUILayout.Space(); } int layerIndex = TerrainPaintUtility.FindTerrainLayerIndex(terrain, m_SelectedTerrainLayer); layerIndex = TerrainLayerUtility.ShowTerrainLayersSelectionHelper(terrain, layerIndex); EditorGUILayout.Space(); if (EditorGUI.EndChangeCheck()) { if (layerIndex != -1) { m_SelectedTerrainLayer = terrain.terrainData.terrainLayers[layerIndex]; } else { m_SelectedTerrainLayer = null; } if (m_SelectedTerrainLayerInspector != null) { UnityEngine.Object.DestroyImmediate(m_SelectedTerrainLayerInspector); m_SelectedTerrainLayerInspector = null; } if (m_SelectedTerrainLayer != null) { m_SelectedTerrainLayerInspector = Editor.CreateEditor(m_SelectedTerrainLayer) as TerrainLayerInspector; } Save(true); } if (m_SelectedTerrainLayerInspector != null) { var terrainLayerCustomUI = m_TemplateMaterialEditor?.m_CustomShaderGUI as ITerrainLayerCustomUI; if (terrainLayerCustomUI != null) { m_SelectedTerrainLayerInspector.SetCustomUI(terrainLayerCustomUI, terrain); } DrawFoldoutEditor(m_SelectedTerrainLayerInspector, kSelectedTerrainLayerEditorControl, ref m_ShowLayerEditor); EditorGUILayout.Space(); } editContext.ShowBrushesGUI(5); }
public override void OnInspectorGUI(Terrain terrain, IOnInspectorGUI editContext) { GUILayout.Label("Settings", EditorStyles.boldLabel); EditorGUI.BeginChangeCheck(); EditorGUILayout.Space(); Editor.DrawFoldoutInspector(terrain.materialTemplate, ref m_TemplateMaterialEditor); EditorGUILayout.Space(); int layerIndex = TerrainPaintUtility.FindTerrainLayerIndex(terrain, m_SelectedTerrainLayer); layerIndex = TerrainLayerUtility.ShowTerrainLayersSelectionHelper(terrain, layerIndex); EditorGUILayout.Space(); if (EditorGUI.EndChangeCheck()) { m_SelectedTerrainLayer = layerIndex != -1 ? terrain.terrainData.terrainLayers[layerIndex] : null; Save(true); } TerrainLayerUtility.ShowTerrainLayerGUI(terrain, m_SelectedTerrainLayer, ref m_SelectedTerrainLayerInspector, (m_TemplateMaterialEditor as MaterialEditor)?.customShaderGUI as ITerrainLayerCustomUI); EditorGUILayout.Space(); editContext.ShowBrushesGUI(5); if (layerIndex < 0) { return; } // load SplatPaintRules (ScriptableObeject) // { string name = "SplatPaintRules_" + terrain.terrainData.terrainLayers[layerIndex].name + ".asset"; string folder = "Assets/Terrain Tool Extender/SplatPaintRules"; if (!AssetDatabase.IsValidFolder("Assets/Terrain Tool Extender")) { AssetDatabase.CreateFolder("Assets", "Terrain Tool Extender"); AssetDatabase.CreateFolder("Assets/Terrain Tool Extender", "SplatPaintRules"); splatPaintRules = (CustomTerrainTools_SplatPaintRules)ScriptableObject.CreateInstance("CustomTerrainTools_SplatPaintRules"); AssetDatabase.CreateAsset(splatPaintRules, folder + "/" + name); } if (!AssetDatabase.IsValidFolder("Assets/Terrain Tool Extender/SplatPaintRules")) { AssetDatabase.CreateFolder("Assets/Terrain Tool Extender", "SplatPaintRules"); splatPaintRules = (CustomTerrainTools_SplatPaintRules)ScriptableObject.CreateInstance("CustomTerrainTools_SplatPaintRules"); AssetDatabase.CreateAsset(splatPaintRules, folder + "/" + name); } splatPaintRules = (CustomTerrainTools_SplatPaintRules)AssetDatabase.LoadAssetAtPath(folder + "/" + name, typeof(CustomTerrainTools_SplatPaintRules)); if (splatPaintRules == null) { splatPaintRules = (CustomTerrainTools_SplatPaintRules)ScriptableObject.CreateInstance("CustomTerrainTools_SplatPaintRules"); AssetDatabase.CreateAsset(splatPaintRules, folder + "/" + name);; splatPaintRules.SetMaxHeights(terrain.terrainData.size.y); splatPaintRules.SetDirty(); MarkSceneDirty(terrain.gameObject); } } EditorGUI.BeginChangeCheck(); EditorGUILayout.Space(); EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.BeginHorizontal(); splatPaintRules.applyHeightRule = EditorGUILayout.Toggle("Apply Height Rule", splatPaintRules.applyHeightRule); EditorGUILayout.EndHorizontal(); if (splatPaintRules.applyHeightRule) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Height : Min(start - end) -- Max(start - end)"); splatPaintRules.minHeightStart = EditorGUILayout.DelayedFloatField(splatPaintRules.minHeightStart); if (splatPaintRules.useHeightTransition) { splatPaintRules.minHeightEnd = EditorGUILayout.DelayedFloatField(splatPaintRules.minHeightEnd); splatPaintRules.maxHeightStart = EditorGUILayout.DelayedFloatField(splatPaintRules.maxHeightStart); } splatPaintRules.maxHeightEnd = EditorGUILayout.DelayedFloatField(splatPaintRules.maxHeightEnd); EditorGUILayout.EndHorizontal(); if (splatPaintRules.useHeightTransition) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.MinMaxSlider(ref splatPaintRules.minHeightEnd, ref splatPaintRules.maxHeightStart, 0f, terrain.terrainData.size.y); EditorGUILayout.EndHorizontal(); splatPaintRules.minHeightEnd = Mathf.Max(splatPaintRules.minHeightEnd, splatPaintRules.minHeightStart); splatPaintRules.maxHeightStart = Mathf.Min(splatPaintRules.maxHeightStart, splatPaintRules.maxHeightEnd); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.MinMaxSlider(ref splatPaintRules.minHeightStart, ref splatPaintRules.maxHeightEnd, 0f, terrain.terrainData.size.y); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); splatPaintRules.inverseHeightRule = EditorGUILayout.Toggle("Inverse Height", splatPaintRules.inverseHeightRule); splatPaintRules.useHeightTransition = EditorGUILayout.Toggle("Height Transition", splatPaintRules.useHeightTransition); EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); EditorGUILayout.Space(); EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.BeginHorizontal(); splatPaintRules.applyAngleRule = EditorGUILayout.Toggle("Apply Angle Rule", splatPaintRules.applyAngleRule); EditorGUILayout.EndHorizontal(); if (splatPaintRules.applyAngleRule) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Angle : Min(start - end) -- Max(start - end)"); splatPaintRules.minAngleStart = EditorGUILayout.DelayedFloatField(splatPaintRules.minAngleStart); if (splatPaintRules.useAngleTransition) { splatPaintRules.minAngleEnd = EditorGUILayout.DelayedFloatField(splatPaintRules.minAngleEnd); splatPaintRules.maxAngleStart = EditorGUILayout.DelayedFloatField(splatPaintRules.maxAngleStart); } splatPaintRules.maxAngleEnd = EditorGUILayout.DelayedFloatField(splatPaintRules.maxAngleEnd); EditorGUILayout.EndHorizontal(); if (splatPaintRules.useAngleTransition) { EditorGUILayout.BeginHorizontal(); EditorGUILayout.MinMaxSlider(ref splatPaintRules.minAngleEnd, ref splatPaintRules.maxAngleStart, 0f, 90f); EditorGUILayout.EndHorizontal(); splatPaintRules.minAngleEnd = Mathf.Max(splatPaintRules.minAngleEnd, splatPaintRules.minAngleStart); splatPaintRules.maxAngleStart = Mathf.Min(splatPaintRules.maxAngleStart, splatPaintRules.maxAngleEnd); } EditorGUILayout.BeginHorizontal(); EditorGUILayout.MinMaxSlider(ref splatPaintRules.minAngleStart, ref splatPaintRules.maxAngleEnd, 0f, 90f); EditorGUILayout.EndHorizontal(); EditorGUILayout.BeginHorizontal(); splatPaintRules.inverseAngleRule = EditorGUILayout.Toggle("Inverse Angle", splatPaintRules.inverseAngleRule); splatPaintRules.useAngleTransition = EditorGUILayout.Toggle("Angle Transition", splatPaintRules.useAngleTransition); EditorGUILayout.EndHorizontal(); } EditorGUILayout.EndVertical(); if (EditorGUI.EndChangeCheck()) { splatPaintRules.SetDirty(); MarkSceneDirty(terrain.gameObject); } selectedTerrainLayerIndex = layerIndex; splatPaintRules = (CustomTerrainTools_SplatPaintRules)EditorGUILayout.ObjectField(splatPaintRules, typeof(CustomTerrainTools_SplatPaintRules), true); }