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(); } }
private void PaintHeightmap(Terrain sampleTerrain, Terrain targetTerrain, BrushTransform sampleXform, BrushTransform targetXform, IOnPaint editContext, Material mat) { PaintContext sampleContext = TerrainPaintUtility.BeginPaintHeightmap(sampleTerrain, sampleXform.GetBrushXYBounds()); PaintContext targetContext = TerrainPaintUtility.BeginPaintHeightmap(targetTerrain, targetXform.GetBrushXYBounds()); ApplyHeightmap(sampleContext, targetContext, targetXform, targetTerrain, editContext.brushTexture, commonUI.brushStrength); TerrainPaintUtility.EndPaintHeightmap(targetContext, "Terrain Paint - Clone Brush (Heightmap)"); // Restores RenderTexture.active sampleContext.Cleanup(); targetContext.Cleanup(); }
private void DrawBrushPreviews(Terrain terrain, IOnSceneGUI editContext) { Vector2 sampleUV; BrushTransform sampleXform; PaintContext sampleContext = null; Material previewMat = Utility.GetDefaultPreviewMaterial(); // draw sample location brush and create context data to be used when drawing target brush previews if (m_SampleLocation.terrain != null) { sampleUV = TerrainUVFromBrushLocation(m_SampleLocation.terrain, m_SampleLocation.pos); sampleXform = TerrainPaintUtility.CalculateBrushTransform(m_SampleLocation.terrain, sampleUV, commonUI.brushSize, commonUI.brushRotation); sampleContext = TerrainPaintUtility.BeginPaintHeightmap(m_SampleLocation.terrain, sampleXform.GetBrushXYBounds()); var texelCtx = Utility.CollectTexelValidity(sampleContext.originTerrain, sampleXform.GetBrushXYBounds()); Utility.SetupMaterialForPaintingWithTexelValidityContext(sampleContext, texelCtx, sampleXform, previewMat); TerrainPaintUtilityEditor.DrawBrushPreview(sampleContext, TerrainBrushPreviewMode.SourceRenderTexture, editContext.brushTexture, sampleXform, previewMat, 0); texelCtx.Cleanup(); } // draw brush preview and mesh preview for current mouse position if (commonUI.isRaycastHitUnderCursorValid) { BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, commonUI.raycastHitUnderCursor.textureCoord, commonUI.brushSize, commonUI.brushRotation); PaintContext ctx = TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXform.GetBrushXYBounds(), 1); var texelCtx = Utility.CollectTexelValidity(ctx.originTerrain, brushXform.GetBrushXYBounds()); Utility.SetupMaterialForPaintingWithTexelValidityContext(ctx, texelCtx, brushXform, previewMat); TerrainPaintUtilityEditor.DrawBrushPreview(ctx, TerrainBrushPreviewMode.SourceRenderTexture, editContext.brushTexture, brushXform, previewMat, 0); if (sampleContext != null && cloneToolProperties.m_PaintHeightmap) { ApplyHeightmap(sampleContext, ctx, brushXform, terrain, editContext.brushTexture, commonUI.brushStrength); RenderTexture.active = ctx.oldRenderTexture; previewMat.SetTexture("_HeightmapOrig", ctx.sourceRenderTexture); TerrainPaintUtilityEditor.DrawBrushPreview(ctx, TerrainBrushPreviewMode.DestinationRenderTexture, editContext.brushTexture, brushXform, previewMat, 1); } // Restores RenderTexture.active ctx.Cleanup(); texelCtx.Cleanup(); } // Restores RenderTexture.active sampleContext?.Cleanup(); }
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 bool OnPaint(Terrain terrain, IOnPaint editContext) { MaterialManager mgr = terrain.GetComponent <MaterialManager>(); if (mgr != null) { // IndexMap indexMap = mgr.GetIndexMap(); // RenderTexture rt= indexMap.GetTempRenderTexture(true); paintInProgress = true; BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 0.0f); PaintContext indexCtx = PaintContext.CreateFromBounds(terrain, brushXform.GetBrushXYBounds(), 64, 64, 1); indexCtx.CreateRenderTargets(RenderTextureFormat.ARGB32); PaintContext normalCtx = TerrainPaintUtility.CollectNormals(terrain, brushXform.GetBrushXYBounds(), 2); Material blitMaterial = TerrainPaintUtility.GetBlitMaterial(); indexCtx.Gather( TerrainToIndexMapTexture, new Color(0.0f, 0.0f, 0.0f, 0.0f), blitMaterial, 0, null, // before null); // after // render source -> dest here // RenderTexture.active = ctx.oldRenderTexture; Material paintMaterial = GetPaintMaterial(); float brushStrength = Event.current.shift ? -editContext.brushStrength : editContext.brushStrength; Vector4 brushParams = new Vector4( brushStrength, 0.0f, 0.0f, 0.0f); paintMaterial.SetTexture("_BrushTex", editContext.brushTexture); paintMaterial.SetVector("_BrushParams", brushParams); paintMaterial.SetFloat("materialIndex", materialIndex); paintMaterial.SetTexture("_NormalMap", normalCtx.sourceRenderTexture); Vector4 indexToNormalXform; TerrainPaintUtility.BuildTransformPaintContextUVToPaintContextUV( indexCtx, normalCtx, out indexToNormalXform); paintMaterial.SetVector("_indexToNormalXform", indexToNormalXform); Vector4 xformParams = new Vector4(); xformParams.x = (randomRotation ? minRotation : fixedRotation) / 360.0f; xformParams.y = (randomRotation ? maxRotation : fixedRotation) / 360.0f; paintMaterial.SetVector("_xformParams", xformParams); Vector4 randoms = new Vector4( UnityEngine.Random.Range(0.0f, 1.0f), UnityEngine.Random.Range(0.0f, 1.0f), UnityEngine.Random.Range(0.0f, 1.0f), UnityEngine.Random.Range(0.0f, 1.0f)); paintMaterial.SetVector("_randoms", randoms); TerrainPaintUtility.SetupTerrainToolMaterialProperties(indexCtx, brushXform, paintMaterial); Graphics.Blit(indexCtx.sourceRenderTexture, indexCtx.destinationRenderTexture, paintMaterial, 0); // ctx.ScatterToTexture() // we should do this ... less temp render textures // and users don't have to store render textures at all... indexCtx.Scatter( TerrainToIndexMapRenderTexture, blitMaterial, 0, null, null); normalCtx.Cleanup(); indexCtx.Cleanup(); } /* * BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 0.0f); * PaintContext paintContext = TerrainPaintUtility.BeginPaintTexture(terrain, brushXform.GetBrushXYBounds(), m_SelectedTerrainLayer); * if (paintContext == null) * return false; * * Material mat = TerrainPaintUtility.GetBuiltinPaintMaterial(); * * // apply brush * float targetAlpha = 1.0f; // always 1.0 now -- no subtractive painting (we assume this in the ScatterAlphaMap) * Vector4 brushParams = new Vector4(editContext.brushStrength, targetAlpha, 0.0f, 0.0f); * mat.SetTexture("_BrushTex", editContext.brushTexture); * mat.SetVector("_BrushParams", brushParams); * * TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); * * Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, (int)TerrainPaintUtility.BuiltinPaintMaterialPasses.PaintTexture); * * TerrainPaintUtility.EndPaintTexture(paintContext, "Terrain Paint - Texture"); */ return(true); }