private void PaintAlphamap(Rect writeBrushRect, Terrain terrain, Material mat) { // paint each layer from the sample to the clone location (adds layer if not present already) for (int i = 0; i < m_Sample.m_Terrain.terrainData.terrainLayers.Length; ++i) { TerrainPaintUtility.PaintContext write = TerrainPaintUtility.BeginPaintTexture(terrain, writeBrushRect, m_Sample.m_Terrain.terrainData.terrainLayers[i]); if (write == null) { continue; } // read created manually to force read to not add the layer if it wasnt already on the terrain, and to use write's rect with offset TerrainPaintUtility.PaintContext read = new TerrainPaintUtility.PaintContext(); read.brushRect = new RectInt(write.brushRect.position + m_CloneRectPixelOffsetFromStampRect, write.brushRect.size); // TODO(wyatt): Uncomment this once Andrew's API changes make it to trunk read.CreateTerrainTiles(m_Sample.m_Terrain, m_Sample.m_Terrain.terrainData.alphamapWidth, m_Sample.m_Terrain.terrainData.alphamapHeight); read.CreateRenderTargets(RenderTextureFormat.R8); read.GatherAlphamap(m_Sample.m_Terrain, m_Sample.m_Terrain.terrainData.terrainLayers[i], false); // render mix of clone and stamp areas StampRender(read, write, mat, (int)ShaderPasses.CloneAlphamap); TerrainPaintUtility.ReleaseContextResources(read); TerrainPaintUtility.EndPaintTexture(write, "Terrain Paint - Clone Stamp Tool (Alphamap layer " + i + ")"); } }
private bool PaintTexture(Terrain terrain, IOnPaint editContext, Vector2 currUV) { // the brush size is relative to the main brush size float brushSize = editContext.brushSize * paintBrushSize / 100f; BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, currUV, brushSize, 0.0f); PaintContext paintContext = TerrainPaintUtility.BeginPaintTexture(terrain, brushXform.GetBrushXYBounds(), m_SelectedInnerTerrainLayer); if (paintContext == null) { return(false); } Material mat = TerrainPaintUtility.GetBuiltinPaintMaterial(); float targetAlpha = 1.0f; // always 1.0 now -- no subtractive painting (we assume this in the ScatterAlphaMap) float brushStrength = paintBrushStrength / 100f; // editContext.brushStrength // apply brush Vector4 brushParams = new Vector4(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); }
/// <summary> /// Executes the modifiers in order and generates the necessary splatmaps /// </summary> /// <param name="layer"></param> /// <param name="modifiers"></param> /// <param name="output"></param> public static void Execute(Terrain terrain, TerrainLayer layer, List <Modifier> modifiers) { Graphics.ClearRandomWriteTargets(); Graphics.SetRenderTarget(alphaMap); //Start with a full white base Graphics.Blit(Texture2D.whiteTexture, alphaMap); //Reverse order for (int i = modifiers.Count - 1; i >= 0; i--) { modifiers[i].Configure(filterMat); modifiers[i].Execute(alphaMap); } //Scale splatmap to fit in terrain Vector2 scaledSplatmapSize = new Vector2((terrain.terrainData.size.x / m_resolution) * m_resolution, (terrain.terrainData.size.z / m_resolution) * m_resolution); //PaintContext handles creation of splatmaps. Subtracting the weights of a splatmap, from the ones before it. //A single pixels of all combined alpha maps must not exceed a value of one. The 2nd pass of Hidden/TerrainEngine/TerrainLayerUtils is used internally to do this //Note: Paintcontext must use a serialized terrain reference, otherwise breaks when executing "ApplyDelayedActions" when the project is saved! PaintContext c = TerrainPaintUtility.BeginPaintTexture(terrain, new Rect(0, 0, scaledSplatmapSize.x, scaledSplatmapSize.y), layer); Graphics.Blit(alphaMap, c.destinationRenderTexture); TerrainPaintUtility.EndPaintTexture(c, "Painted terrain"); }
public override bool OnPaint(Terrain terrain, IOnPaint editContext) { if (splatPaintRules == null) { return(false); } Material mat = GetPaintMaterial(); mat.SetTexture("_BrushTex", editContext.brushTexture); // gathering heightmap BrushTransform brushXformForGatheringHeightmap = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 0.0f); PaintContext paintContextForGatheringHeightmap = TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXformForGatheringHeightmap.GetBrushXYBounds(), 1); if (paintContextForGatheringHeightmap == null) { return(false); } RenderTexture gatheredHeightmap = RenderTexture.GetTemporary(terrain.terrainData.heightmapTexture.descriptor); Graphics.Blit(paintContextForGatheringHeightmap.sourceRenderTexture, gatheredHeightmap); //, TerrainPaintUtility.GetBlitMaterial(), 0); TerrainPaintUtility.ReleaseContextResources(paintContextForGatheringHeightmap); // painting alphamap 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); } float targetAlpha = 1.0f; // always 1.0 now -- no subtractive painting (we assume this in the ScatterAlphaMap) Vector4 brushParams = new Vector4(editContext.brushStrength, targetAlpha, splatPaintRules.useHeightTransition ? 1f : 0f, splatPaintRules.useAngleTransition ? 1f : 0f); Vector4 paintRulesParametersHeight = new Vector4(splatPaintRules.minHeightStart, splatPaintRules.minHeightEnd, splatPaintRules.maxHeightStart, splatPaintRules.maxHeightEnd); Vector4 paintRulesParametersAngle = new Vector4(splatPaintRules.minAngleStart, splatPaintRules.minAngleEnd, splatPaintRules.maxAngleStart, splatPaintRules.maxAngleEnd); Vector4 paintRulesInversionAndUsage = new Vector4(splatPaintRules.inverseHeightRule ? 1f : 0f, splatPaintRules.inverseAngleRule ? 1f : 0f, splatPaintRules.applyHeightRule ? 1f : 0f, splatPaintRules.applyAngleRule ? 1f : 0f); mat.SetVector("_BrushParams", brushParams); mat.SetVector("_TerrainSize", (Vector4)terrain.terrainData.size); mat.SetVector("_PaintRulesParametersHeight", paintRulesParametersHeight); mat.SetVector("_PaintRulesParametersAngle", paintRulesParametersAngle); mat.SetVector("_PaintRulesInversionAndUsage", paintRulesInversionAndUsage); mat.SetTexture("_Heightmap", gatheredHeightmap); TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, 0); TerrainPaintUtility.EndPaintTexture(paintContext, "Terrain Paint - Texture"); RenderTexture.ReleaseTemporary(gatheredHeightmap); return(true); }
public override bool OnPaint(Terrain terrain, IOnPaint editContext) { BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 0.0f); Rect rect = brushXform.GetBrushXYBounds(); PaintContext paintContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, rect); Material mat = GetPaintMaterial(); PaintContext maskContext = null; if (m_TextureMask || m_TextureStencil) { TerrainLayer maskTerrainLayer = terrain.terrainData.terrainLayers[m_TextureMask ? m_maskIndex : m_stencilIndex]; maskContext = TerrainPaintUtility.BeginPaintTexture(terrain, rect, maskTerrainLayer); if (maskContext == null) { return(false); } mat.SetTexture("_MaskTex", maskContext.sourceRenderTexture); } mat.SetInt("_MaskStencil", m_TextureMask ? 1 : (m_TextureStencil ? 2 : 0)); ApplyBrushInternal(paintContext, editContext.brushStrength, editContext.brushTexture, brushXform, mat); if (maskContext != null) { TerrainPaintUtility.ReleaseContextResources(maskContext); } TerrainPaintUtility.EndPaintHeightmap(paintContext, "Terrain Paint - Masked Terrace Erosion"); return(false); }
/// <summary> /// Executes the modifiers in order and generates the necessary splatmaps /// </summary> /// <param name="layer"></param> /// <param name="modifiers"></param> /// <param name="output"></param> public static void ProcessSingleLayer(Terrain terrain, LayerSettings settings) { //Disable or with no settings (result in a fill with black) if (settings.enabled == false) { return; } Graphics.SetRenderTarget(alphaMap); //Start with a full white base Graphics.Blit(Texture2D.whiteTexture, alphaMap); //Reverse order for (int i = settings.modifierStack.Count - 1; i >= 0; i--) { settings.modifierStack[i].Configure(filterMat); settings.modifierStack[i].Execute(alphaMap); } //Scale splatmap to fit in terrain Vector2 scaledSplatmapSize = new Vector2((terrain.terrainData.size.x / m_resolution) * m_resolution, (terrain.terrainData.size.z / m_resolution) * m_resolution); //PaintContext handles creation of splatmaps. Subtracting the weights of a splatmap, from the ones before it. //A single pixels of all combined alpha maps must not exceed a value of one. The 2nd pass of Hidden/TerrainEngine/TerrainLayerUtils is used internally to do this //Note: Paintcontext must use a serialized terrain reference, otherwise breaks when executing "ApplyDelayedActions" when the project is saved! PaintContext c = TerrainPaintUtility.BeginPaintTexture(terrain, new Rect(0, 0, scaledSplatmapSize.x, scaledSplatmapSize.y), settings.layer); Graphics.Blit(alphaMap, c.destinationRenderTexture); TerrainPaintUtility.EndPaintTexture(c, UndoActionName); }
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 bool OnPaint(Terrain terrain, IOnPaint editContext) { 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); }
public PaintContext AcquireTexture(bool writable, Terrain terrain, Rect boundsInTerrainSpace, TerrainLayer layer, int extraBorderPixels = 0) { m_WriteToTexture = writable; m_TextureContext = TerrainPaintUtility.BeginPaintTexture(terrain, boundsInTerrainSpace, layer, extraBorderPixels); if (m_TextureContext == null) { return(null); } m_TextureContext.sourceRenderTexture.name = $"{m_Name}::TextureContext::SourceRT"; m_TextureContext.destinationRenderTexture.name = $"{m_Name}::TextureContext::DestRT"; return(m_TextureContext); }
public override bool OnPaint(Terrain terrain, IOnPaint editContext) { if (Event.current.type == EventType.MouseDown) { m_PrevBrushPos = editContext.uv; return(false); } if (Event.current.type == EventType.MouseDrag && m_PreviousEvent == EventType.MouseDrag) { BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 0.0f); PaintContext paintContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXform.GetBrushXYBounds(), 1); Vector2 smudgeDir = editContext.uv - m_PrevBrushPos; paintContext.sourceRenderTexture.filterMode = FilterMode.Bilinear; Material mat = GetPaintMaterial(); PaintContext maskContext = null; if (m_TextureMask || m_TextureStencil) { TerrainLayer maskTerrainLayer = terrain.terrainData.terrainLayers[m_TextureMask ? m_maskIndex : m_stencilIndex]; maskContext = TerrainPaintUtility.BeginPaintTexture(terrain, brushXform.GetBrushXYBounds(), maskTerrainLayer); if (maskContext == null) { return(false); } mat.SetTexture("_MaskTex", maskContext.sourceRenderTexture); } mat.SetInt("_MaskStencil", m_TextureMask ? 1 : (m_TextureStencil ? 2 : 0)); Vector4 brushParams = new Vector4(editContext.brushStrength, smudgeDir.x, smudgeDir.y, 0); mat.SetTexture("_BrushTex", editContext.brushTexture); mat.SetVector("_BrushParams", brushParams); TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, 0); TerrainPaintUtility.EndPaintHeightmap(paintContext, "Terrain Paint - Masked Smudge"); if (maskContext != null) { TerrainPaintUtility.ReleaseContextResources(maskContext); } m_PrevBrushPos = editContext.uv; } m_PreviousEvent = Event.current.type; return(false); }
private bool DoPaint(Terrain terrain, float brushStrength, Texture brushTexture, BrushTransform brushXform) { Rect rect = brushXform.GetBrushXYBounds(); PaintContext paintContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXform.GetBrushXYBounds(), 1); if (paintContext == null) { return(false); } paintContext.sourceRenderTexture.filterMode = FilterMode.Bilinear; Material mat = GetPaintMaterial(); PaintContext maskContext = null; if (m_TextureMask || m_TextureStencil) { TerrainLayer maskTerrainLayer = terrain.terrainData.terrainLayers[m_TextureMask ? m_maskIndex : m_stencilIndex]; maskContext = TerrainPaintUtility.BeginPaintTexture(terrain, rect, maskTerrainLayer); if (maskContext == null) { return(false); } mat.SetTexture("_MaskTex", maskContext.sourceRenderTexture); } mat.SetInt("_MaskStencil", m_TextureMask ? 1 : (m_TextureStencil ? 2 : 0)); Vector4 brushParams = new Vector4(brushStrength, 0.0f, m_FeatureSize, 0); mat.SetTexture("_BrushTex", brushTexture); mat.SetVector("_BrushParams", brushParams); TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, 0); TerrainPaintUtility.EndPaintHeightmap(paintContext, "Terrain Paint - Masked Smooth Sharpen"); if (maskContext != null) { TerrainPaintUtility.ReleaseContextResources(maskContext); } return(true); }
public override bool OnPaint(Terrain terrain, IOnPaint editContext) { BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 0.0f); Rect rect = brushXform.GetBrushXYBounds(); PaintContext paintContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, rect, 1); Material mat = GetPaintMaterial(); PaintContext maskContext = null; if (m_TextureMask || m_TextureStencil) { TerrainLayer maskTerrainLayer = terrain.terrainData.terrainLayers[m_TextureMask ? m_maskIndex : m_stencilIndex]; maskContext = TerrainPaintUtility.BeginPaintTexture(terrain, rect, maskTerrainLayer); if (maskContext == null) { return(false); } mat.SetTexture("_MaskTex", maskContext.sourceRenderTexture); } mat.SetInt("_MaskStencil", m_TextureMask ? 1 : (m_TextureStencil ? 2 : 0)); // apply brush Vector4 brushParams = new Vector4( editContext.brushStrength, m_ErosionStrength, m_MixStrength, 0.0f); mat.SetTexture("_BrushTex", editContext.brushTexture); mat.SetVector("_BrushParams", brushParams); TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, 0); TerrainPaintUtility.EndPaintHeightmap(paintContext, "Masked Ridge Erode"); if (maskContext != null) { TerrainPaintUtility.ReleaseContextResources(maskContext); } return(false); }
public override bool OnPaint(Terrain terrain, IOnPaint editContext) { Rect brushRect = TerrainPaintUtility.CalculateBrushRectInTerrainUnits(terrain, editContext.uv, editContext.brushSize); TerrainPaintUtility.PaintContext paintContext = TerrainPaintUtility.BeginPaintTexture(terrain, brushRect, m_SelectedTerrainLayer); if (paintContext == null) { return(false); } Material mat = TerrainPaintUtility.GetBuiltinPaintMaterial(); // apply brush Vector4 brushParams = new Vector4(editContext.brushStrength, m_SplatAlpha, 0.0f, 0.0f); mat.SetTexture("_BrushTex", editContext.brushTexture); mat.SetVector("_BrushParams", brushParams); Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, (int)TerrainPaintUtility.BuiltinPaintMaterialPasses.PaintTexture); TerrainPaintUtility.EndPaintTexture(paintContext, "Terrain Paint - Texture"); return(true); }
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) { if (Event.current.type == EventType.MouseDown) { m_PrevBrushPos = editContext.uv; } float min = Mathf.Min(terrain.terrainData.size.x, terrain.terrainData.size.z); float extent = editContext.brushSize * Mathf.Lerp(1.2f, 1.0f, 1.0f - m_Extent) + min * Mathf.Lerp(0.1f, 1.0f, m_Extent); m_brushStrength = editContext.brushStrength; Vector2 waterVel = (editContext.uv - m_PrevBrushPos) * m_BrushVel * -10000.0f; m_PrevBrushPos = editContext.uv; GetPaintMaterials(); m_Material.SetVector("_WaterVel", waterVel); if (continuing && editContext.brushSize == oldBrushSize && terrain == oldTerrain) { Vector2 shift = BrushUVDelta(editContext.uv, terrain, soilWater[0].width, soilWater[0].height); if (Mathf.Max(Mathf.Abs(shift.x), Mathf.Abs(shift.y)) < 0.5f) { m_Material.SetVector("_WaterShift", shift); return(true); } } oldTerrain = terrain; oldBrushSize = editContext.brushSize; continuing = true; m_Material.SetFloat("_HeightScale", terrain.terrainData.size.y); BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, extent, 0.0f); Rect rect = brushXform.GetBrushXYBounds(); Vector2 oldUV = rect.center; oldUV.x *= 0.5f / terrain.terrainData.bounds.extents.x; oldUV.y *= 0.5f / terrain.terrainData.bounds.extents.z; if (terrain.leftNeighbor == null) { rect.x = Mathf.Max(0.0f, rect.x); } if (terrain.bottomNeighbor == null) { rect.y = Mathf.Max(0.0f, rect.y); } if (terrain.leftNeighbor == null && terrain.rightNeighbor == null) { rect.width = Mathf.Min(rect.width, terrain.terrainData.bounds.extents.x * 2.0f); } if (terrain.topNeighbor == null && terrain.bottomNeighbor == null) { rect.height = Mathf.Min(rect.height, terrain.terrainData.bounds.extents.z * 2.0f); } if (terrain.rightNeighbor == null) { rect.x = Mathf.Min(rect.x, terrain.terrainData.bounds.extents.x * 2.0f - rect.width); } if (terrain.topNeighbor == null) { rect.y = Mathf.Min(rect.y, terrain.terrainData.bounds.extents.z * 2.0f - rect.height); } Vector2 uv = rect.center; uv.x *= 0.5f / terrain.terrainData.bounds.extents.x; uv.y *= 0.5f / terrain.terrainData.bounds.extents.z; if (m_TextureMask || m_TextureStencil) { TerrainLayer maskTerrainLayer = terrain.terrainData.terrainLayers[m_TextureMask ? m_maskIndex : m_stencilIndex]; maskContext = TerrainPaintUtility.BeginPaintTexture(terrain, rect, maskTerrainLayer); if (maskContext == null) { return(false); } } SetMaterial(m_Material, editContext); src = 0; InitHeightTextures(terrain, rect); TerrainPaintUtility.SetupTerrainToolMaterialProperties(heightContext, brushXform, m_Material); InitWaterSim(heightContext.sourceRenderTexture.width, heightContext.sourceRenderTexture.height); InitDisplay(terrain, new Vector2(rect.width, rect.height), uv); float interp = editContext.brushSize / extent; uvBase = uv * (1.0f - interp) + oldUV * interp; Vector2 shiftStart = BrushUVDelta(editContext.uv, terrain, soilWater[0].width, soilWater[0].height); m_Material.SetVector("_WaterShift", shiftStart); m_Material.SetFloat("_Extent", extent / editContext.brushSize); return(false); }
public PaintContext AcquireTexture(bool writable, Terrain terrain, Rect boundsInTerrainSpace, TerrainLayer layer, int extraBorderPixels = 0) { m_WriteToTexture = writable; m_TextureContext = TerrainPaintUtility.BeginPaintTexture(terrain, boundsInTerrainSpace, layer, extraBorderPixels); return(m_TextureContext); }
public override bool OnPaint(Terrain terrain, IOnPaint editContext) { commonUI.OnPaint(terrain, editContext); if (!commonUI.allowPaint) { return(true); } if (Event.current.type == EventType.MouseDown) { m_PrevBrushPos = editContext.uv; return(false); } if (Event.current.type == EventType.MouseDrag && m_PreviousEvent == EventType.MouseDrag) { Vector2 uv = editContext.uv; if (commonUI.ScatterBrushStamp(ref terrain, ref uv)) { Material mat = GetPaintMaterial(); Vector2 smudgeDir = uv - m_PrevBrushPos; BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, uv, commonUI.brushSize, commonUI.brushRotation); Vector4 brushParams = new Vector4(commonUI.brushStrength, smudgeDir.x, smudgeDir.y, 0); mat.SetTexture("_BrushTex", editContext.brushTexture); mat.SetVector("_BrushParams", brushParams); //smudge splat map if (m_AffectMaterials) { for (int i = 0; i < terrain.terrainData.terrainLayers.Length; i++) { TerrainLayer layer = terrain.terrainData.terrainLayers[i]; if (layer == null) { continue; // nothing to paint if the layer is NULL } PaintContext sampleContext = TerrainPaintUtility.BeginPaintTexture(terrain, brushXform.GetBrushXYBounds(), layer); Graphics.Blit(sampleContext.sourceRenderTexture, sampleContext.destinationRenderTexture, mat, 0); TerrainPaintUtility.EndPaintTexture(sampleContext, "Terrain Paint - Twist Brush (Texture)"); } } //smudge the height map if (m_AffectHeight) { PaintContext paintContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXform.GetBrushXYBounds(), 1); TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, 0); TerrainPaintUtility.EndPaintHeightmap(paintContext, "Terrain Paint - Twist Brush (Height)"); } m_PrevBrushPos = uv; } } m_PreviousEvent = Event.current.type; return(false); }
private bool DoPaint(Terrain terrain, float brushStrength, Texture brushTexture, Rect rect, BrushTransform brushXform) { if (disablePaint) { return(false); } m_SelectedTerrainLayer = terrain.terrainData.terrainLayers[m_textureIndex]; PaintContext paintContext = TerrainPaintUtility.BeginPaintTexture(terrain, rect, m_SelectedTerrainLayer); if (paintContext == null) { return(false); } PaintContext heightContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, rect, 1); if (heightContext == null) { return(false); } if (terrain.normalmapTexture == null) { Debug.Log("Please check the Draw Instanced option under terrain settings to use this tool"); return(false); } PaintContext normalContext = TerrainPaintUtility.CollectNormals(terrain, rect, 0); Material mat = GetPaintMaterial(); float extent = textureParams[m_textureIndex].heightExtent; float blend = textureParams[m_textureIndex].heightBlend; float height = textureParams[m_textureIndex].heightMaxPoint; if (textureParams[m_textureIndex].heightRelative) { extent /= relativeHeightMult; height /= relativeHeightMult; } else { extent /= terrain.terrainData.size.y; height /= terrain.terrainData.size.y; } Vector4 brushParams = new Vector4(brushStrength, height, textureParams[m_textureIndex].heightMask ? extent * (1.0f - blend) : 10000.0f, extent * blend); extent = textureParams[m_textureIndex].slopeExtent; blend = textureParams[m_textureIndex].slopeBlend; Vector4 slopeParams = new Vector4(textureParams[m_textureIndex].slopeMaxPoint, textureParams[m_textureIndex].slopeMask ? extent * (1.0f - blend) : 1.0f, extent * blend, textureParams[m_textureIndex].maxValue); PaintContext maskContext = null; if (textureParams[m_textureIndex].textureMask || textureParams[m_textureIndex].textureStencil) { TerrainLayer maskTerrainLayer = terrain.terrainData.terrainLayers[textureParams[m_textureIndex].textureMask ? textureParams[m_textureIndex].maskIndex : textureParams[m_textureIndex].stencilIndex]; maskContext = TerrainPaintUtility.BeginPaintTexture(terrain, rect, maskTerrainLayer); if (maskContext == null) { return(false); } mat.SetTexture("_MaskTex", maskContext.sourceRenderTexture); } mat.SetInt("_MaskStencil", textureParams[m_textureIndex].textureMask ? 1 : (textureParams[m_textureIndex].textureStencil ? 2 : 0)); mat.SetTexture("_BrushTex", brushTexture); mat.SetTexture("_HeightTex", heightContext.sourceRenderTexture); mat.SetTexture("_NormalTex", normalContext.sourceRenderTexture); mat.SetVector("_BrushParams", brushParams); mat.SetVector("_SlopeParams", slopeParams); mat.SetFloat("_FeatureSize", textureParams[m_textureIndex].heightRelative?textureParams[m_textureIndex].heightFeatureSize:0.0f); if (brushTexture == null) { mat.SetFloat("_AspectRatio", terrain.terrainData.size.x / terrain.terrainData.size.z); } else { mat.SetFloat("_AspectRatio", (float)paintContext.sourceRenderTexture.height / (float)paintContext.sourceRenderTexture.width); } TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, 0); TerrainPaintUtility.EndPaintTexture(paintContext, "Terrain Paint - Masked Texture"); TerrainPaintUtility.ReleaseContextResources(heightContext); TerrainPaintUtility.ReleaseContextResources(normalContext); if (maskContext != null) { TerrainPaintUtility.ReleaseContextResources(maskContext); } return(true); }
public static PaintContext BeginFillTexture(Terrain terrain, TerrainLayer inputLayer) { return(TerrainPaintUtility.BeginPaintTexture(terrain, GetTerrainBounds(terrain), inputLayer)); }