Example #1
0
        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);
        }
Example #2
0
        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);
                }
        }
Example #6
0
        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);
                }
        }
Example #7
0
        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));
        }
Example #8
0
        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));
        }
Example #9
0
        public void RTHandleRW_Has_RW_Flag_Set()
        {
            var handle = RTUtils.GetTempHandle(descriptorRW);

            Assert.True(handle.RT.enableRandomWrite);
            RTUtils.Release(handle);
        }
Example #10
0
        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();
        }
Example #11
0
        public void RTHandleRW_Temporary_Is_Not_Null()
        {
            var handle = RTUtils.GetTempHandle(descriptorRW);

            Assert.True(handle != null);
            Assert.True(handle.RT != null);
            RTUtils.Release(handle);
        }
Example #12
0
        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);
        }
Example #13
0
        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);
        }
Example #14
0
        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);
        }
Example #15
0
        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);
        }
Example #16
0
        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());
        }
Example #17
0
        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);
        }
Example #18
0
        /// <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;
            }
        }
Example #19
0
        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]);
            }
        }
Example #20
0
        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);
        }
Example #21
0
        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);
        }
Example #22
0
        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);
        }
Example #24
0
        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);
        }
Example #26
0
        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);
        }
Example #28
0
        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);
        }
Example #29
0
        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);
        }
Example #30
0
        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);
            }
        }