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); }
protected override void OnEval(FilterContext fc, RenderTexture source, RenderTexture dest) { var desc = dest.descriptor; desc.enableRandomWrite = true; var sourceHandle = RTUtils.GetTempHandle(desc); var destHandle = RTUtils.GetTempHandle(desc); using (sourceHandle.Scoped()) using (destHandle.Scoped()) { Graphics.Blit(source, sourceHandle); Graphics.Blit(dest, destHandle); ComputeShader cs = GetComputeShader(); int kidx = cs.FindKernel("AspectRemap"); Texture2D remapTex = GetRemapTexture(); float rotRad = (fc.brushRotation - 90.0f) * Mathf.Deg2Rad; cs.SetTexture(kidx, "In_BaseMaskTex", sourceHandle); cs.SetTexture(kidx, "In_HeightTex", fc.rtHandleCollection[FilterContext.Keywords.Heightmap]); cs.SetTexture(kidx, "OutputTex", destHandle); cs.SetTexture(kidx, "RemapTex", remapTex); cs.SetInt("RemapTexRes", remapTex.width); cs.SetFloat("EffectStrength", m_EffectStrength); cs.SetVector("TextureResolution", new Vector4(source.width, source.height, 0.0f, 0.0f)); cs.SetVector("AspectValues", new Vector4(Mathf.Cos(rotRad), Mathf.Sin(rotRad), m_Epsilon, 0.0f)); cs.Dispatch(kidx, source.width, source.height, 1); Graphics.Blit(destHandle, dest); } }
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 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); }
protected override void OnEval(FilterContext fc, RenderTexture source, RenderTexture dest) { var desc = dest.descriptor; desc.enableRandomWrite = true; var sourceHandle = RTUtils.GetTempHandle(desc); var destHandle = RTUtils.GetTempHandle(desc); using (sourceHandle.Scoped()) using (destHandle.Scoped()) { Graphics.Blit(source, sourceHandle); Graphics.Blit(dest, destHandle); ComputeShader cs = GetComputeShader(); int kidx = cs.FindKernel("HeightRemap"); Texture2D remapTex = GetRemapTexture(); cs.SetTexture(kidx, "In_BaseMaskTex", sourceHandle); cs.SetTexture(kidx, "In_HeightTex", fc.rtHandleCollection[FilterContext.Keywords.Heightmap]); cs.SetTexture(kidx, "OutputTex", destHandle); cs.SetTexture(kidx, "RemapTex", remapTex); cs.SetInt("RemapTexRes", remapTex.width); cs.SetFloat("EffectStrength", m_ConcavityStrength); cs.SetVector("HeightRange", new Vector4(m_Height.x, m_Height.y, m_HeightFeather, 0.0f)); cs.Dispatch(kidx, source.width, source.height, 1); Graphics.Blit(destHandle, dest); } }
protected override void OnEval(FilterContext fc, RenderTexture source, RenderTexture dest) { var desc = dest.descriptor; desc.enableRandomWrite = true; var sourceHandle = RTUtils.GetTempHandle(desc); var destHandle = RTUtils.GetTempHandle(desc); using (sourceHandle.Scoped()) using (destHandle.Scoped()) { Graphics.Blit(source, sourceHandle); Graphics.Blit(dest, destHandle); ComputeShader cs = GetComputeShader(); int kidx = cs.FindKernel("GradientMultiply"); Texture2D remapTex = GetRemapTexture(); cs.SetTexture(kidx, "In_BaseMaskTex", sourceHandle); cs.SetTexture(kidx, "In_HeightTex", fc.rtHandleCollection[FilterContext.Keywords.Heightmap]); cs.SetTexture(kidx, "OutputTex", destHandle); cs.SetTexture(kidx, "RemapTex", remapTex); cs.SetInt("RemapTexRes", remapTex.width); cs.SetFloat("EffectStrength", m_FilterStrength); cs.SetVector("TerrainDimensions", fc.vectorProperties.ContainsKey("_TerrainSize") ? fc.vectorProperties["_TerrainSize"] : Vector4.one); cs.SetVector("TextureResolution", new Vector4(sourceHandle.RT.width, sourceHandle.RT.height, m_Epsilon, fc.floatProperties[FilterContext.Keywords.TerrainScale])); cs.Dispatch(kidx, sourceHandle.RT.width, sourceHandle.RT.height, 1); Graphics.Blit(destHandle, dest); } }
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)); }
public void RTHandleRW_Has_RW_Flag_Set() { var handle = RTUtils.GetTempHandle(descriptorRW); Assert.True(handle.RT.enableRandomWrite); RTUtils.Release(handle); }
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_Temporary() { var handle = RTUtils.GetTempHandle(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); }
public void RTHandle_Scope_Cleanup() { var handle = RTUtils.GetTempHandle(descriptorRW); Assert.True(m_PrevRTHandleCount + 1 == RTUtils.GetHandleCount()); using (handle.Scoped()) { // keep empty } Assert.True(m_PrevRTHandleCount == RTUtils.GetHandleCount()); }
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); }
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 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 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); } }