public override bool OnPaint(Terrain terrain, IOnPaint editContext) { Texture brushTexture = editContext.brushTexture; commonUI.OnPaint(terrain, editContext); if (!commonUI.allowPaint) { return(true); } using (IBrushRenderUnderCursor brushRender = new BrushRenderUIGroupUnderCursor(commonUI, "ContrastTool", brushTexture)) { if (brushRender.CalculateBrushTransform(out BrushTransform brushXform)) { PaintContext paintContext = brushRender.AcquireHeightmap(true, brushXform.GetBrushXYBounds(), 1); Material mat = GetPaintMaterial(); var brushMask = RTUtils.GetTempHandle(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, paintContext.sourceRenderTexture, brushMask, mat); paintContext.sourceRenderTexture.filterMode = FilterMode.Bilinear; ApplyBrushInternal(brushRender, paintContext, commonUI.brushStrength, editContext.brushTexture, brushXform); RTUtils.Release(brushMask); } } return(false); }
public override bool OnPaint(Terrain terrain, IOnPaint editContext) { commonUI.OnPaint(terrain, editContext); if (commonUI.allowPaint) { using (IBrushRenderUnderCursor brushRender = new BrushRenderUIGroupUnderCursor(commonUI, "SlopeFlatten", editContext.brushTexture)) { if (brushRender.CalculateBrushTransform(out BrushTransform brushXform)) { PaintContext paintContext = brushRender.AcquireHeightmap(true, brushXform.GetBrushXYBounds(), 1); Material mat = GetPaintMaterial(); var brushMask = RTUtils.GetTempHandle(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, paintContext.sourceRenderTexture, brushMask, mat); paintContext.sourceRenderTexture.filterMode = FilterMode.Bilinear; Vector4 brushParams = new Vector4(commonUI.brushStrength, 0.0f, commonUI.brushSize, 0); mat.SetTexture("_BrushTex", editContext.brushTexture); mat.SetVector("_BrushParams", brushParams); brushRender.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); brushRender.RenderBrush(paintContext, mat, 0); RTUtils.Release(brushMask); } } } return(false); }
public void RTHandleRW_Has_RW_Flag_Set() { var handle = RTUtils.GetTempHandle(descriptorRW); Assert.True(handle.RT.enableRandomWrite); RTUtils.Release(handle); }
public override bool OnPaint(Terrain terrain, IOnPaint editContext) { commonUI.OnPaint(terrain, editContext); if (commonUI.allowPaint) { Texture brushTexture = editContext.brushTexture; using (IBrushRenderUnderCursor brushRender = new BrushRenderUIGroupUnderCursor(commonUI, "PaintHoles", brushTexture)) { Vector2 halfTexelOffset = new Vector2(0.5f / terrain.terrainData.holesResolution, 0.5f / terrain.terrainData.holesResolution); BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv - halfTexelOffset, commonUI.brushSize, commonUI.brushRotation); PaintContext paintContext = brushRender.AquireHolesTexture(true, brushXform.GetBrushXYBounds()); PaintContext paintContextHeight = brushRender.AcquireHeightmap(false, brushXform.GetBrushXYBounds()); // filter stack Material mat = Utility.GetPaintHeightMaterial(); var brushMask = RTUtils.GetTempHandle(paintContextHeight.sourceRenderTexture.width, paintContextHeight.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, paintContextHeight.sourceRenderTexture, brushMask, mat); // hold control key to erase float brushStrength = Event.current.control ? commonUI.brushStrength : -commonUI.brushStrength; Vector4 brushParams = new Vector4(brushStrength, 0.0f, 0.0f, 0.0f); mat.SetTexture("_BrushTex", editContext.brushTexture); mat.SetVector("_BrushParams", brushParams); brushRender.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); brushRender.RenderBrush(paintContext, mat, (int)TerrainBuiltinPaintMaterialPasses.PaintHoles); TerrainPaintUtility.EndPaintHoles(paintContext, "Terrain Paint - Paint Holes"); RTUtils.Release(brushMask); } } return(true); }
public void Add_Filter() { // setup float addValue = 9000f; var addFilter = FilterUtility.CreateInstance <AddFilter>(); addFilter.value = addValue; var prevRT = RenderTexture.active; var src = RTUtils.GetTempHandle(RTUtils.GetDescriptor(1, 1, 0, GraphicsFormat.R16G16B16A16_SFloat, 0, false)); var dest = RTUtils.GetTempHandle(RTUtils.GetDescriptor(1, 1, 0, GraphicsFormat.R16G16B16A16_SFloat, 0, false)); Graphics.Blit(Texture2D.blackTexture, src); Graphics.Blit(Texture2D.blackTexture, dest); // eval addFilter.Eval(m_Context, src, dest); var tex = new Texture2D(1, 1, TextureFormat.RGBAFloat, false, true); RenderTexture.active = dest; tex.ReadPixels(new Rect(0, 0, 1, 1), 0, 0, false); var check = tex.GetPixel(0, 0).r; // clean up RenderTexture.active = prevRT; UObject.DestroyImmediate(tex); RTUtils.Release(src); RTUtils.Release(dest); UObject.DestroyImmediate(addFilter); Assert.That(check, Is.EqualTo(addValue)); }
public void Values_Can_Be_Negative() { // setup float addValue = -10; var addFilter = FilterUtility.CreateInstance <AddFilter>(); addFilter.value = addValue; m_Stack.Add(addFilter); var prevRT = RenderTexture.active; var dest = RTUtils.GetTempHandle(RTUtils.GetDescriptor(1, 1, 0, GraphicsFormat.R16G16B16A16_SFloat, 0, false)); Graphics.Blit(Texture2D.blackTexture, dest); // init to black // eval m_Stack.Eval(m_Context, null, dest); // source isn't actually used yet var tex = new Texture2D(1, 1, TextureFormat.RGBAFloat, false, true); RenderTexture.active = dest; tex.ReadPixels(new Rect(0, 0, 1, 1), 0, 0, false); var check = tex.GetPixel(0, 0).r - 1; // minus 1 because we start off with a white texture within FilterStack.Eval // clean up RenderTexture.active = prevRT; UObject.DestroyImmediate(tex); RTUtils.Release(dest); Assert.That(check, Is.EqualTo(addValue)); }
void Flatten(Terrain terrain) { Undo.RegisterCompleteObjectUndo(terrain.terrainData, "Set Height - Flatten Tile"); var ctx = TerrainPaintUtility.BeginPaintHeightmap(terrain, new Rect(0, 0, terrain.terrainData.size.x, terrain.terrainData.size.z), 1); Material mat = GetPaintMaterial(); float terrainHeight = Mathf.Clamp01((m_TargetHeight - terrain.transform.position.y) / terrain.terrainData.size.y); Vector4 brushParams = new Vector4(0, 0.5f * terrainHeight, 0.0f, 0.0f); mat.SetVector("_BrushParams", brushParams); var size = terrain.terrainData.size; size.y = 0; var brushMask = RTUtils.GetTempHandle(ctx.sourceRenderTexture.width, ctx.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); commonUI.GetBrushMask(terrain, ctx.sourceRenderTexture, brushMask, terrain.transform.position, Mathf.Min(size.x, size.z), 0f); // TODO(wyatt): need to handle seams mat.SetTexture("_FilterTex", brushMask); mat.SetTexture("_MainTex", ctx.sourceRenderTexture); Graphics.Blit(ctx.sourceRenderTexture, ctx.destinationRenderTexture, mat, 1); TerrainPaintUtility.EndPaintHeightmap(ctx, "Set Height - Flatten Tile"); RTUtils.Release(brushMask); PaintContext.ApplyDelayedActions(); }
public void RTHandleRW_Temporary_Is_Not_Null() { var handle = RTUtils.GetTempHandle(descriptorRW); Assert.True(handle != null); Assert.True(handle.RT != null); RTUtils.Release(handle); }
public void RTHandle_Release_New() { var handle = RTUtils.GetNewHandle(descriptor); Assert.True(RTUtils.GetHandleCount() == m_PrevRTHandleCount + 1); RTUtils.Release(handle); Assert.True(RTUtils.GetHandleCount() == m_PrevRTHandleCount); }
public override bool OnPaint(Terrain terrain, IOnPaint editContext) { commonUI.OnPaint(terrain, editContext); if (commonUI.allowPaint) { Texture brushTexture = editContext.brushTexture; using (IBrushRenderUnderCursor brushRender = new BrushRenderUIGroupUnderCursor(commonUI, "Twist", brushTexture)) { if (brushRender.CalculateBrushTransform(out BrushTransform brushXform)) { float finalTwistAmount = m_TwistAmount * -0.001f; //scale to a reasonable value and negate so default mode is clockwise if (Event.current.shift) { finalTwistAmount *= -1.0f; } Material mat = GetPaintMaterial(); Vector4 brushParams = new Vector4(commonUI.brushStrength, 0.0f, finalTwistAmount, 0.0f); mat.SetTexture("_BrushTex", editContext.brushTexture); mat.SetVector("_BrushParams", brushParams); //twist splat map if (m_AffectMaterials) { for (int i = 0; i < terrain.terrainData.terrainLayers.Length; i++) { TerrainLayer layer = terrain.terrainData.terrainLayers[i]; PaintContext paintContext = brushRender.AcquireTexture(true, brushXform.GetBrushXYBounds(), layer); var brushMask = RTUtils.GetTempHandle(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, paintContext.sourceRenderTexture, brushMask, mat); paintContext.sourceRenderTexture.filterMode = FilterMode.Bilinear; brushRender.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); brushRender.RenderBrush(paintContext, mat, 0); brushRender.Release(paintContext); RTUtils.Release(brushMask); } } //twist height map if (m_AffectHeight) { PaintContext paintContext = brushRender.AcquireHeightmap(true, brushXform.GetBrushXYBounds(), 1); var brushMask = RTUtils.GetTempHandle(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, paintContext.sourceRenderTexture, brushMask, mat); paintContext.sourceRenderTexture.filterMode = FilterMode.Bilinear; ApplyBrushInternal(brushRender, paintContext, commonUI.brushStrength, finalTwistAmount, brushTexture, brushXform); brushRender.Release(paintContext); RTUtils.Release(brushMask); } } } } return(false); }
public override bool OnPaint(Terrain terrain, IOnPaint editContext) { commonUI.OnPaint(terrain, editContext); if (!commonUI.allowPaint) { return(true); } Vector2 uv = editContext.uv; if (commonUI.ScatterBrushStamp(ref terrain, ref uv)) { using (IBrushRenderUnderCursor brushRender = new BrushRenderUIGroupUnderCursor(commonUI, "WindErosion", editContext.brushTexture)) { if (brushRender.CalculateBrushTransform(out BrushTransform brushXform)) { var brushBounds = brushXform.GetBrushXYBounds(); PaintContext paintContext = brushRender.AcquireHeightmap(true, brushBounds, 4); paintContext.sourceRenderTexture.filterMode = FilterMode.Bilinear; //paintContext.sourceRenderTexture = input heightmap //Add Velocity (user wind direction and strength, or texture input, noise, forces, drag etc...) float angle = commonUI.brushRotation; //m_WindAngleDegrees + r; float r = 0.5f * (2.0f * UnityEngine.Random.value - 1.0f) * 0.01f * m_Eroder.m_WindSpeedJitter; float speed = m_Eroder.m_WindSpeed.value + r; float rad = angle * Mathf.Deg2Rad; m_Eroder.m_WindVel = speed * (new Vector4(-Mathf.Sin(rad), Mathf.Cos(rad), 0.0f, 0.0f)); m_Eroder.inputTextures["Height"] = paintContext.sourceRenderTexture; var heightRT = RTUtils.GetTempHandle(RTUtils.GetDescriptorRW((int)brushBounds.width, (int)brushBounds.height, 0, RenderTextureFormat.RFloat)); Vector2 texelSize = new Vector2(terrain.terrainData.size.x / terrain.terrainData.heightmapResolution, terrain.terrainData.size.z / terrain.terrainData.heightmapResolution); m_Eroder.ErodeHeightmap(heightRT, terrain.terrainData.size, brushBounds, texelSize); //Blit the result onto the new height map Material mat = GetPaintMaterial(); var brushMask = RTUtils.GetTempHandle(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, paintContext.sourceRenderTexture, brushMask, mat); Vector4 brushParams = new Vector4(commonUI.brushStrength, 0.0f, 0.0f, 0.0f); mat.SetTexture("_BrushTex", editContext.brushTexture); mat.SetTexture("_NewHeightTex", heightRT); mat.SetVector("_BrushParams", brushParams); brushRender.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); brushRender.RenderBrush(paintContext, mat, 0); brushRender.Release(paintContext); RTUtils.Release(brushMask); RTUtils.Release(heightRT); } } } return(true); }
private void ApplyBrushInternal(Terrain terrain, PaintContext paintContext, float brushStrength, Texture brushTexture, BrushTransform brushXform) { /* * ComputeShader cs = GetDiffusionShader(); * * int kernel = cs.FindKernel("Diffuse"); * cs.SetFloat("dt", 0.1f); * cs.SetFloat("diff", 0.01f); * cs.SetVector("texDim", new Vector4(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0.0f, 0.0f)); * cs.SetTexture(kernel, "InputTex", paintContext.sourceRenderTexture); * cs.SetTexture(kernel, "OutputTex", paintContext.destinationRenderTexture); * cs.Dispatch(kernel, paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 1); */ RenderTexture prev = RenderTexture.active; Material mat = GetMaterial(); var brushMask = RTUtils.GetTempHandle(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, paintContext.sourceRenderTexture, brushMask, mat); Vector4 brushParams = new Vector4(Mathf.Clamp(brushStrength, 0.0f, 1.0f), 0.0f, 0.0f, 0.0f); mat.SetTexture("_BrushTex", brushTexture); mat.SetVector("_BrushParams", brushParams); Vector4 smoothWeights = new Vector4( Mathf.Clamp01(1.0f - Mathf.Abs(m_direction)), // centered Mathf.Clamp01(-m_direction), // min Mathf.Clamp01(m_direction), // max 0); mat.SetInt("_KernelSize", (int)Mathf.Max(1, m_KernelSize)); // kernel size mat.SetVector("_SmoothWeights", smoothWeights); var texelCtx = Utility.CollectTexelValidity(terrain, brushXform.GetBrushXYBounds()); Utility.SetupMaterialForPaintingWithTexelValidityContext(paintContext, texelCtx, brushXform, mat); paintContext.sourceRenderTexture.wrapMode = TextureWrapMode.Clamp; paintContext.destinationRenderTexture.wrapMode = TextureWrapMode.Clamp; // Two pass blur (first horizontal, then vertical) var tmpRT = RTUtils.GetTempHandle(paintContext.destinationRenderTexture.descriptor); tmpRT.RT.wrapMode = TextureWrapMode.Clamp; mat.SetVector("_BlurDirection", Vector2.right); Graphics.Blit(paintContext.sourceRenderTexture, tmpRT, mat); mat.SetVector("_BlurDirection", Vector2.up); Graphics.Blit(tmpRT, paintContext.destinationRenderTexture, mat); RTUtils.Release(tmpRT); RTUtils.Release(brushMask); texelCtx.Cleanup(); RenderTexture.active = prev; RenderTexture.ReleaseTemporary(brushMask); }
/// <summary> /// Release the RTHandle resources that have been gathered /// </summary> public void ReleaseRTHandles() { foreach (int key in m_Hashes) { if (m_Handles[key] != null) { var handle = m_Handles[key]; RTUtils.Release(handle); m_Handles[key] = null; } } }
private void ReleaseRTHandles() { for (int i = 0; i < 2; i++) { RTUtils.Release(m_HeightmapRT[i]); RTUtils.Release(m_WaterRT[i]); RTUtils.Release(m_WaterVelRT[i]); RTUtils.Release(m_FluxRT[i]); RTUtils.Release(m_SedimentRT[i]); } RTUtils.Release(m_ErodedRT); RTUtils.Release(m_HardnessRT); }
private void ApplyBrushInternal(Terrain terrain, IPaintContextRender renderer, PaintContext paintContext, float brushStrength, Texture brushTexture, BrushTransform brushTransform) { Material mat = Utility.GetPaintHeightMaterial(); var brushMask = RTUtils.GetTempHandle(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, paintContext.sourceRenderTexture, brushMask, mat); Vector4 brushParams = new Vector4(0.05f * brushStrength, 0.0f, 0.0f, 0.0f); mat.SetTexture("_BrushTex", brushTexture); mat.SetVector("_BrushParams", brushParams); renderer.SetupTerrainToolMaterialProperties(paintContext, brushTransform, mat); renderer.RenderBrush(paintContext, mat, (int)TerrainBuiltinPaintMaterialPasses.RaiseLowerHeight); RTUtils.Release(brushMask); }
/// <summary> /// Evaluate the FilterStack. Composited result will be copied into fc.destinationRenderTexture /// <param name="fc">The FilterContext that should be used for composition</param> /// <exception>Throws an exception if source or destination RenderTexture is null</exception> /// </summary> public void Eval(FilterContext fc, RenderTexture source, RenderTexture dest) { if (dest == null) { throw new InvalidOperationException("FilterContext::Eval: Source and destination RenderTextures are not properly set up"); } using (new ActiveRenderTextureScope(RenderTexture.active)) { int count = filters.Count; int srcIndex = 0; int destIndex = 1; var descriptor = RTUtils.GetDescriptor(dest.width, dest.height, 0, FilterUtility.defaultFormat); swapBuffer[0] = RTUtils.GetTempHandle(descriptor).WithName(k_BufferName0); swapBuffer[1] = RTUtils.GetTempHandle(descriptor).WithName(k_BufferName1); // ensure the textures are created for compute usage swapBuffer[0].RT.Create(); swapBuffer[1].RT.Create(); //don't remove this! needed for compute shaders to work correctly. Graphics.Blit(Texture2D.whiteTexture, swapBuffer[0]); // TODO: change this to black or source. should build up the mask instead of always multiply Graphics.Blit(Texture2D.blackTexture, swapBuffer[1]); for (int i = 0; i < count; ++i) { var filter = filters[i]; if (!filter.enabled) { continue; } filter.Eval(fc, swapBuffer[srcIndex], swapBuffer[destIndex]); // swap indices destIndex += srcIndex; srcIndex = destIndex - srcIndex; destIndex = destIndex - srcIndex; } Graphics.Blit(swapBuffer[srcIndex], dest); RTUtils.Release(swapBuffer[0]); RTUtils.Release(swapBuffer[1]); swapBuffer[0] = null; swapBuffer[1] = null; } }
public void RTHandle_Count_Is_Correct() { var handles = new RTHandle[10]; for (int i = 0; i < handles.Length; ++i) { handles[i] = RTUtils.GetTempHandle(descriptor); } Assert.True(RTUtils.GetHandleCount() == m_PrevRTHandleCount + handles.Length); for (int i = 0; i < handles.Length; ++i) { RTUtils.Release(handles[i]); } }
private void ApplyBrushInternal(Terrain terrain, IPaintContextRender renderer, PaintContext paintContext, float brushStrength, Texture brushTexture, BrushTransform brushXform) { Material mat = GetPaintMaterial(); var brushMask = RTUtils.GetTempHandle(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, paintContext.sourceRenderTexture, brushMask, mat); float delta = terraceToolProperties.m_JitterTerraceCount * 50.0f; float jitteredFeatureSize = terraceToolProperties.m_FeatureSize + Random.Range(terraceToolProperties.m_FeatureSize - delta, terraceToolProperties.m_FeatureSize + delta); Vector4 brushParams = new Vector4(brushStrength, jitteredFeatureSize, terraceToolProperties.m_BevelAmountInterior, 0.0f); mat.SetTexture("_BrushTex", brushTexture); mat.SetVector("_BrushParams", brushParams); renderer.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); renderer.RenderBrush(paintContext, mat, 0); RTUtils.Release(brushMask); }
public override bool OnPaint(Terrain terrain, IOnPaint editContext) { commonUI.OnPaint(terrain, editContext); if (!commonUI.allowPaint) { return(false); } int[] numWorkGroups = { 8, 8, 1 }; using (IBrushRenderUnderCursor brushRender = new BrushRenderUIGroupUnderCursor(commonUI, "ThermalErosion", editContext.brushTexture)) { if (brushRender.CalculateBrushTransform(out BrushTransform brushXform)) { PaintContext paintContext = brushRender.AcquireHeightmap(true, brushXform.GetBrushXYBounds(), 1); paintContext.sourceRenderTexture.filterMode = FilterMode.Bilinear; //figure out what size we need our render targets to be Rect brushRect = brushXform.GetBrushXYBounds(); m_Eroder.inputTextures["Height"] = paintContext.sourceRenderTexture; var heightRT = RTUtils.GetTempHandle(RTUtils.GetDescriptorRW((int)brushRect.width, (int)brushRect.height, 0, RenderTextureFormat.RFloat)); Vector2 texelSize = new Vector2(terrain.terrainData.size.x / terrain.terrainData.heightmapResolution, terrain.terrainData.size.z / terrain.terrainData.heightmapResolution); m_Eroder.ErodeHeightmap(heightRT, terrain.terrainData.size, brushRect, texelSize); Material mat = GetPaintMaterial(); var brushMask = RTUtils.GetTempHandle(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, paintContext.sourceRenderTexture, brushMask, mat); Vector4 brushParams = new Vector4(commonUI.brushStrength, 0.0f, 0.0f, 0.0f); mat.SetTexture("_BrushTex", editContext.brushTexture); mat.SetTexture("_NewHeightTex", heightRT); mat.SetVector("_BrushParams", brushParams); brushRender.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); brushRender.RenderBrush(paintContext, mat, 0); RTUtils.Release(brushMask); RTUtils.Release(heightRT); } } return(true); }
private void ApplyHeightmap(PaintContext sampleContext, PaintContext targetContext, BrushTransform targetXform, Terrain targetTerrain, Texture brushTexture, float brushStrength) { Material paintMat = GetPaintMaterial(); Vector4 brushParams = new Vector4(brushStrength, cloneToolProperties.m_StampingOffsetFromClone * 0.5f, targetTerrain.terrainData.size.y, 0f); paintMat.SetTexture("_BrushTex", brushTexture); paintMat.SetVector("_BrushParams", brushParams); paintMat.SetTexture("_CloneTex", sampleContext.sourceRenderTexture); paintMat.SetVector("_SampleUVScaleOffset", ComputeSampleUVScaleOffset(sampleContext, targetContext)); var brushMask = RTUtils.GetTempHandle(sampleContext.sourceRenderTexture.width, sampleContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, sampleContext.sourceRenderTexture, brushMask, paintMat); TerrainPaintUtility.SetupTerrainToolMaterialProperties(targetContext, targetXform, paintMat); Graphics.Blit(targetContext.sourceRenderTexture, targetContext.destinationRenderTexture, paintMat, (int)ShaderPasses.CloneHeightmap); RTUtils.Release(brushMask); }
private void ApplyBrushInternal(IPaintContextRender renderer, PaintContext paintContext, float brushStrength, Texture brushTexture, BrushTransform brushXform, Terrain terrain) { Vector3 prevHandlePosWS = commonUI.raycastHitUnderCursor.point; float HeightUnderCursor = terrain.SampleHeight(prevHandlePosWS) / (terrain.terrainData.size.y * 2.0f); float height = stampToolProperties.stampHeight * brushStrength / (terrain.terrainData.size.y * 2.0f); Material mat = Utility.GetPaintHeightMaterial(); Vector4 brushParams = new Vector4((int)this.stampToolProperties.behavior, HeightUnderCursor, height, stampToolProperties.preserveDetails); mat.SetTexture("_BrushTex", brushTexture); mat.SetVector("_BrushParams", brushParams); var brushMask = RTUtils.GetTempHandle(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, paintContext.sourceRenderTexture, brushMask, mat); renderer.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); renderer.RenderBrush(paintContext, mat, (int)TerrainBuiltinPaintMaterialPasses.StampHeight); RTUtils.Release(brushMask); }
public bool OnPaint(Terrain terrain, IOnPaint editContext, float brushSize, float brushRotation, float brushStrength, Vector2 uv) { if (Event.current != null && Event.current.shift) { BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, uv, brushSize, brushRotation); PaintContext paintContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXform.GetBrushXYBounds()); Material mat = GetMaterial(); //TerrainPaintUtility.GetBuiltinPaintMaterial(); float m_direction = 0.0f; //TODO: UI for this Vector4 brushParams = new Vector4(brushStrength, 0.0f, 0.0f, 0.0f); mat.SetTexture("_BrushTex", editContext.brushTexture); mat.SetVector("_BrushParams", brushParams); Vector4 smoothWeights = new Vector4( Mathf.Clamp01(1.0f - Mathf.Abs(m_direction)), // centered Mathf.Clamp01(-m_direction), // min Mathf.Clamp01(m_direction), // max 0); mat.SetInt("_KernelSize", (int)Mathf.Max(1, kernelSize)); // kernel size mat.SetVector("_SmoothWeights", smoothWeights); var texelCtx = Utility.CollectTexelValidity(paintContext.originTerrain, brushXform.GetBrushXYBounds(), 1); Utility.SetupMaterialForPaintingWithTexelValidityContext(paintContext, texelCtx, brushXform, mat); paintContext.sourceRenderTexture.wrapMode = TextureWrapMode.Clamp; var temp = RTUtils.GetTempHandle(paintContext.destinationRenderTexture.descriptor); temp.RT.wrapMode = TextureWrapMode.Clamp; mat.SetVector("_BlurDirection", Vector2.right); Graphics.Blit(paintContext.sourceRenderTexture, temp, mat); mat.SetVector("_BlurDirection", Vector2.up); Graphics.Blit(temp, paintContext.destinationRenderTexture, mat); TerrainPaintUtility.EndPaintHeightmap(paintContext, "Terrain Paint - Smooth Height"); texelCtx.Cleanup(); RTUtils.Release(temp); return(true); } return(false); }
public override bool OnPaint(Terrain terrain, IOnPaint editContext) { commonUI.OnPaint(terrain, editContext); if (!commonUI.allowPaint) { return(true); } using (IBrushRenderUnderCursor brushRender = new BrushRenderUIGroupUnderCursor(commonUI, "HydroErosion", editContext.brushTexture)) { if (brushRender.CalculateBrushTransform(out BrushTransform brushXform)) { var brushBounds = brushXform.GetBrushXYBounds(); PaintContext paintContext = brushRender.AcquireHeightmap(true, brushBounds, 1); paintContext.sourceRenderTexture.filterMode = FilterMode.Bilinear; m_Eroder.inputTextures["Height"] = paintContext.sourceRenderTexture; var heightRT = RTUtils.GetTempHandle(RTUtils.GetDescriptorRW((int)brushBounds.width, (int)brushBounds.height, 0, RenderTextureFormat.RFloat)); Vector2 texelSize = new Vector2(terrain.terrainData.size.x / terrain.terrainData.heightmapResolution, terrain.terrainData.size.z / terrain.terrainData.heightmapResolution); m_Eroder.ErodeHeightmap(heightRT, terrain.terrainData.size, brushXform.GetBrushXYBounds(), texelSize, Event.current.control); // TODO(wyatt): commonUI.ModifierActive(BrushModifierKey.BRUSH_MOD_INVERT) Material mat = GetPaintMaterial(); var brushMask = RTUtils.GetTempHandle(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, paintContext.sourceRenderTexture, brushMask, mat); Vector4 brushParams = new Vector4(commonUI.brushStrength, 0.0f, 0.0f, 0.0f); mat.SetTexture("_BrushTex", editContext.brushTexture); mat.SetTexture("_NewHeightTex", heightRT); mat.SetVector("_BrushParams", brushParams); brushRender.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); brushRender.RenderBrush(paintContext, mat, 0); RTUtils.Release(brushMask); RTUtils.Release(heightRT); } } return(true); }
public void Noise_Filter_Can_Be_Rotated(int dim) { var noiseFilter = FilterUtility.CreateInstance <NoiseFilter>(); noiseFilter.SetLocalSpace(true); m_Stack.Add(noiseFilter); var dest = RTUtils.GetTempHandle(RTUtils.GetDescriptor(dim, dim, 0, GraphicsFormat.R16G16B16A16_SFloat, 0, false)); Graphics.Blit(Texture2D.blackTexture, dest); // init to black m_Context.brushRotation = 0; m_Context.brushPos = Vector3.zero; m_Context.brushSize = dim; m_Stack.Eval(m_Context, null, dest); // source isn't actually used yet var unrotatedColors = GetColorsFromRT(dest); m_Context.brushRotation = 180; m_Stack.Eval(m_Context, null, dest); // source isn't actually used yet var rotatedColors = GetColorsFromRT(dest); RTUtils.Release(dest); int failureCount = 0; var difference = new Color[rotatedColors.Length]; for (int x = 0; x < dim; x++) { for (int y = 0; y < dim; y++) { int rotatedIndex = (dim - 1 - x) + (dim - 1 - y) * dim; var index = x + y * dim; difference[index] = new Color(Mathf.Abs(rotatedColors[rotatedIndex].r - unrotatedColors[index].r), 0, 0, 1); // comparing with a small value to eliminate issues coming from floating point offset if (Mathf.Abs(rotatedColors[rotatedIndex].r - unrotatedColors[index].r) > 0.001f) { failureCount++; } } } Assert.That(failureCount, Is.Zero); }
protected override void OnEval(FilterContext filterContext, RenderTexture source, RenderTexture dest) { var mat = Material; Vector4 smoothWeights = new Vector4( Mathf.Clamp01(1.0f - Mathf.Abs(m_Direction)), // centered Mathf.Clamp01(-m_Direction), // min Mathf.Clamp01(m_Direction), // max 0); mat.SetVector("_SmoothWeights", smoothWeights); mat.SetInt("_KernelSize", Mathf.Max(1, m_Amount)); // kernel size // Two pass blur (first horizontal, then vertical) var tmpRT = RTUtils.GetTempHandle(dest.descriptor); tmpRT.RT.wrapMode = TextureWrapMode.Clamp; mat.SetVector("_BlurDirection", Vector2.right); Graphics.Blit(source, tmpRT, mat); mat.SetVector("_BlurDirection", Vector2.up); Graphics.Blit(tmpRT, dest, mat); RTUtils.Release(tmpRT); }
public void RTHandle_Cleanup_Throws_Exception_On_Non_RTHandle_RenderTexture() { var handle = new RTHandle(); handle.SetRenderTexture(RenderTexture.GetTemporary(descriptor), true); var pass = false; try { RTUtils.Release(handle); } catch (InvalidOperationException e) { pass = String.Compare(e.Message, "Attemping to release a RTHandle that is not currently tracked by the system. This should never happen", StringComparison.Ordinal) == 0; } // manual cleanup for test purposes RenderTexture.ReleaseTemporary(handle.RT); Assert.True(pass); }
private void ApplyBrushInternal(IPaintContextRender renderer, PaintContext paintContext, float brushStrength, Texture brushTexture, BrushTransform brushXform, Terrain terrain) { Material mat = TerrainPaintUtility.GetBuiltinPaintMaterial(); float height = stampToolProperties.m_StampHeight / (terrain.terrainData.size.y * 2.0f); if (stampToolProperties.stampDown) { height = -height; } Vector4 brushParams = new Vector4(brushStrength, 0.0f, height, stampToolProperties.m_MaxBlendAdd); mat.SetTexture("_BrushTex", brushTexture); mat.SetVector("_BrushParams", brushParams); var brushMask = RTUtils.GetTempHandle(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); Utility.SetFilterRT(commonUI, paintContext.sourceRenderTexture, brushMask, mat); renderer.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat); renderer.RenderBrush(paintContext, mat, (int)TerrainPaintUtility.BuiltinPaintMaterialPasses.StampHeight); RTUtils.Release(brushMask); }
private void ApplyBrushInternal(PaintContext paintContext, IBrushRenderUnderCursor brushRender, float brushStrength, Texture brushTexture, BrushTransform brushTransform, Terrain terrain) { Material mat = GetPaintMaterial(); #if UNITY_2019_3_OR_NEWER float brushTargetHeight = Mathf.Clamp01((m_TargetHeight - paintContext.heightWorldSpaceMin) / paintContext.heightWorldSpaceSize); Vector4 brushParams = new Vector4(brushStrength * 0.01f, PaintContext.kNormalizedHeightScale * brushTargetHeight, 0.0f, 0.0f); #else float terrainHeight = Mathf.Clamp01((m_TargetHeight - terrain.transform.position.y) / terrain.terrainData.size.y); Vector4 brushParams = new Vector4(brushStrength * 0.01f, 0.5f * terrainHeight, 0.0f, 0.0f); #endif var brushMask = RTUtils.GetTempHandle(paintContext.sourceRenderTexture.width, paintContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat); commonUI.GetBrushMask(paintContext.sourceRenderTexture, brushMask); mat.SetTexture("_FilterTex", brushMask); mat.SetTexture("_BrushTex", brushTexture); mat.SetVector("_BrushParams", brushParams); brushRender.SetupTerrainToolMaterialProperties(paintContext, brushTransform, mat); brushRender.RenderBrush(paintContext, mat, 0); RTUtils.Release(brushMask); }
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); } }
protected override void OnEval(FilterContext fc, RenderTexture sourceRenderTexture, RenderTexture destinationRenderTexture) { if (m_noiseSettings == null) { m_noiseSettings = ScriptableObject.CreateInstance <NoiseSettings>(); } m_noiseSettings.useTextureForPositions = m_useHeightmap; if (m_useHeightmap) { m_noiseSettings.positionTexture = fc.rtHandleCollection[FilterContext.Keywords.Heightmap]; } Vector3 brushPosWS = fc.brushPos - m_lastBrushPosition; brushPosWS.y = 0; m_lastBrushPosition = fc.brushPos; float brushSize = fc.brushSize; float brushRotation = fc.brushRotation - m_lastRotation; m_lastRotation = fc.brushRotation; // TODO(wyatt): remove magic number and tie it into NoiseSettingsGUI preview size somehow float previewSize = 1 / 512f; // get proper noise material from current noise settings NoiseSettings noiseSettings = m_noiseSettings; Material mat = NoiseUtils.GetDefaultBlitMaterial(noiseSettings); // setup the noise material with values in noise settings noiseSettings.SetupMaterial(mat); // change pos and scale so they match the noiseSettings preview bool isWorldSpace = false == m_isLocalSpace; brushSize = isWorldSpace ? brushSize * previewSize : 1; brushPosWS = isWorldSpace ? brushPosWS * previewSize : Vector3.zero; // compensate for the difference between the size of the rotated brush and the square noise RT var brushTransform = GetBrushTransform(fc); var scaleMultiplier = new Vector2( 1.0f / (fc.brushSize / brushTransform.GetBrushXYBounds().width), 1.0f / (fc.brushSize / brushTransform.GetBrushXYBounds().height)); Quaternion rotQ = Quaternion.AngleAxis(-brushRotation, Vector3.up); // accumulate transformation delta m_noiseToWorld *= Matrix4x4.TRS(brushPosWS, rotQ, Vector3.one); mat.SetMatrix(NoiseSettings.ShaderStrings.transform, noiseSettings.trs * m_noiseToWorld * Matrix4x4.Scale(new Vector3(scaleMultiplier.x, 1.0f, scaleMultiplier.y) * brushSize)); int pass = NoiseUtils.kNumBlitPasses * NoiseLib.GetNoiseIndex(noiseSettings.domainSettings.noiseTypeName); var desc = destinationRenderTexture.descriptor; desc.graphicsFormat = NoiseUtils.singleChannelFormat; desc.sRGB = false; RTHandle rt = RTUtils.GetTempHandle(desc); Graphics.Blit(sourceRenderTexture, rt, mat, pass); Material blendMat = FilterUtility.blendModesMaterial; blendMat.SetTexture("_BlendTex", rt); Graphics.Blit(sourceRenderTexture, destinationRenderTexture, blendMat, 1); RTUtils.Release(rt); }