예제 #1
0
        private void PaintAlphamap(Rect writeBrushRect, Terrain terrain, Material mat)
        {
            // paint each layer from the sample to the clone location (adds layer if not present already)
            for (int i = 0; i < m_Sample.m_Terrain.terrainData.terrainLayers.Length; ++i)
            {
                TerrainPaintUtility.PaintContext write = TerrainPaintUtility.BeginPaintTexture(terrain,
                                                                                               writeBrushRect,
                                                                                               m_Sample.m_Terrain.terrainData.terrainLayers[i]);

                if (write == null)
                {
                    continue;
                }

                // read created manually to force read to not add the layer if it wasnt already on the terrain, and to use write's rect with offset
                TerrainPaintUtility.PaintContext read = new TerrainPaintUtility.PaintContext();

                read.brushRect = new RectInt(write.brushRect.position + m_CloneRectPixelOffsetFromStampRect, write.brushRect.size);

                // TODO(wyatt): Uncomment this once Andrew's API changes make it to trunk
                read.CreateTerrainTiles(m_Sample.m_Terrain,
                                        m_Sample.m_Terrain.terrainData.alphamapWidth,
                                        m_Sample.m_Terrain.terrainData.alphamapHeight);
                read.CreateRenderTargets(RenderTextureFormat.R8);
                read.GatherAlphamap(m_Sample.m_Terrain, m_Sample.m_Terrain.terrainData.terrainLayers[i], false);

                // render mix of clone and stamp areas
                StampRender(read, write, mat, (int)ShaderPasses.CloneAlphamap);

                TerrainPaintUtility.ReleaseContextResources(read);
                TerrainPaintUtility.EndPaintTexture(write, "Terrain Paint - Clone Stamp Tool (Alphamap layer " + i + ")");
            }
        }
예제 #2
0
        private bool PaintTexture(Terrain terrain, IOnPaint editContext, Vector2 currUV)
        {
            // the brush size is relative to the main brush size
            float brushSize = editContext.brushSize * paintBrushSize / 100f;

            BrushTransform brushXform   = TerrainPaintUtility.CalculateBrushTransform(terrain, currUV, brushSize, 0.0f);
            PaintContext   paintContext = TerrainPaintUtility.BeginPaintTexture(terrain, brushXform.GetBrushXYBounds(), m_SelectedInnerTerrainLayer);

            if (paintContext == null)
            {
                return(false);
            }


            Material mat = TerrainPaintUtility.GetBuiltinPaintMaterial();

            float targetAlpha   = 1.0f;                      // always 1.0 now -- no subtractive painting (we assume this in the ScatterAlphaMap)
            float brushStrength = paintBrushStrength / 100f; // editContext.brushStrength

            // apply brush
            Vector4 brushParams = new Vector4(brushStrength, targetAlpha, 0.0f, 0.0f);

            mat.SetTexture("_BrushTex", editContext.brushTexture);
            mat.SetVector("_BrushParams", brushParams);

            TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat);

            Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, (int)TerrainPaintUtility.BuiltinPaintMaterialPasses.PaintTexture);

            TerrainPaintUtility.EndPaintTexture(paintContext, "Terrain Paint - Texture");

            return(true);
        }
예제 #3
0
        /// <summary>
        /// Executes the modifiers in order and generates the necessary splatmaps
        /// </summary>
        /// <param name="layer"></param>
        /// <param name="modifiers"></param>
        /// <param name="output"></param>
        public static void Execute(Terrain terrain, TerrainLayer layer, List <Modifier> modifiers)
        {
            Graphics.ClearRandomWriteTargets();
            Graphics.SetRenderTarget(alphaMap);

            //Start with a full white base
            Graphics.Blit(Texture2D.whiteTexture, alphaMap);

            //Reverse order
            for (int i = modifiers.Count - 1; i >= 0; i--)
            {
                modifiers[i].Configure(filterMat);
                modifiers[i].Execute(alphaMap);
            }

            //Scale splatmap to fit in terrain
            Vector2 scaledSplatmapSize = new Vector2((terrain.terrainData.size.x / m_resolution) * m_resolution, (terrain.terrainData.size.z / m_resolution) * m_resolution);

            //PaintContext handles creation of splatmaps. Subtracting the weights of a splatmap, from the ones before it.
            //A single pixels of all combined alpha maps must not exceed a value of one. The 2nd pass of Hidden/TerrainEngine/TerrainLayerUtils is used internally to do this
            //Note: Paintcontext must use a serialized terrain reference, otherwise breaks when executing "ApplyDelayedActions" when the project is saved!
            PaintContext c = TerrainPaintUtility.BeginPaintTexture(terrain, new Rect(0, 0, scaledSplatmapSize.x, scaledSplatmapSize.y), layer);

            Graphics.Blit(alphaMap, c.destinationRenderTexture);

            TerrainPaintUtility.EndPaintTexture(c, "Painted terrain");
        }
        public override bool OnPaint(Terrain terrain, IOnPaint editContext)
        {
            if (splatPaintRules == null)
            {
                return(false);
            }


            Material mat = GetPaintMaterial();

            mat.SetTexture("_BrushTex", editContext.brushTexture);



            // gathering heightmap
            BrushTransform brushXformForGatheringHeightmap   = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 0.0f);
            PaintContext   paintContextForGatheringHeightmap = TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXformForGatheringHeightmap.GetBrushXYBounds(), 1);

            if (paintContextForGatheringHeightmap == null)
            {
                return(false);
            }

            RenderTexture gatheredHeightmap = RenderTexture.GetTemporary(terrain.terrainData.heightmapTexture.descriptor);

            Graphics.Blit(paintContextForGatheringHeightmap.sourceRenderTexture, gatheredHeightmap); //, TerrainPaintUtility.GetBlitMaterial(), 0);
            TerrainPaintUtility.ReleaseContextResources(paintContextForGatheringHeightmap);


            // painting alphamap
            BrushTransform brushXform   = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 0.0f);
            PaintContext   paintContext = TerrainPaintUtility.BeginPaintTexture(terrain, brushXform.GetBrushXYBounds(), m_SelectedTerrainLayer);

            if (paintContext == null)
            {
                return(false);
            }


            float   targetAlpha = 1.0f;     // always 1.0 now -- no subtractive painting (we assume this in the ScatterAlphaMap)
            Vector4 brushParams = new Vector4(editContext.brushStrength, targetAlpha, splatPaintRules.useHeightTransition ? 1f : 0f, splatPaintRules.useAngleTransition ? 1f : 0f);
            Vector4 paintRulesParametersHeight  = new Vector4(splatPaintRules.minHeightStart, splatPaintRules.minHeightEnd, splatPaintRules.maxHeightStart, splatPaintRules.maxHeightEnd);
            Vector4 paintRulesParametersAngle   = new Vector4(splatPaintRules.minAngleStart, splatPaintRules.minAngleEnd, splatPaintRules.maxAngleStart, splatPaintRules.maxAngleEnd);
            Vector4 paintRulesInversionAndUsage = new Vector4(splatPaintRules.inverseHeightRule ? 1f : 0f, splatPaintRules.inverseAngleRule ? 1f : 0f, splatPaintRules.applyHeightRule ? 1f : 0f, splatPaintRules.applyAngleRule ? 1f : 0f);

            mat.SetVector("_BrushParams", brushParams);
            mat.SetVector("_TerrainSize", (Vector4)terrain.terrainData.size);
            mat.SetVector("_PaintRulesParametersHeight", paintRulesParametersHeight);
            mat.SetVector("_PaintRulesParametersAngle", paintRulesParametersAngle);
            mat.SetVector("_PaintRulesInversionAndUsage", paintRulesInversionAndUsage);
            mat.SetTexture("_Heightmap", gatheredHeightmap);
            TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat);
            Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, 0);
            TerrainPaintUtility.EndPaintTexture(paintContext, "Terrain Paint - Texture");



            RenderTexture.ReleaseTemporary(gatheredHeightmap);
            return(true);
        }
        public override bool OnPaint(Terrain terrain, IOnPaint editContext)
        {
            BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 0.0f);
            Rect           rect       = brushXform.GetBrushXYBounds();

            PaintContext paintContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, rect);
            Material     mat          = GetPaintMaterial();

            PaintContext maskContext = null;

            if (m_TextureMask || m_TextureStencil)
            {
                TerrainLayer maskTerrainLayer = terrain.terrainData.terrainLayers[m_TextureMask ? m_maskIndex : m_stencilIndex];
                maskContext = TerrainPaintUtility.BeginPaintTexture(terrain, rect, maskTerrainLayer);
                if (maskContext == null)
                {
                    return(false);
                }
                mat.SetTexture("_MaskTex", maskContext.sourceRenderTexture);
            }
            mat.SetInt("_MaskStencil", m_TextureMask ? 1 : (m_TextureStencil ? 2 : 0));

            ApplyBrushInternal(paintContext, editContext.brushStrength, editContext.brushTexture, brushXform, mat);

            if (maskContext != null)
            {
                TerrainPaintUtility.ReleaseContextResources(maskContext);
            }

            TerrainPaintUtility.EndPaintHeightmap(paintContext, "Terrain Paint - Masked Terrace Erosion");
            return(false);
        }
예제 #6
0
        /// <summary>
        /// Executes the modifiers in order and generates the necessary splatmaps
        /// </summary>
        /// <param name="layer"></param>
        /// <param name="modifiers"></param>
        /// <param name="output"></param>
        public static void ProcessSingleLayer(Terrain terrain, LayerSettings settings)
        {
            //Disable or with no settings (result in a fill with black)
            if (settings.enabled == false)
            {
                return;
            }

            Graphics.SetRenderTarget(alphaMap);

            //Start with a full white base
            Graphics.Blit(Texture2D.whiteTexture, alphaMap);

            //Reverse order
            for (int i = settings.modifierStack.Count - 1; i >= 0; i--)
            {
                settings.modifierStack[i].Configure(filterMat);
                settings.modifierStack[i].Execute(alphaMap);
            }

            //Scale splatmap to fit in terrain
            Vector2 scaledSplatmapSize = new Vector2((terrain.terrainData.size.x / m_resolution) * m_resolution, (terrain.terrainData.size.z / m_resolution) * m_resolution);

            //PaintContext handles creation of splatmaps. Subtracting the weights of a splatmap, from the ones before it.
            //A single pixels of all combined alpha maps must not exceed a value of one. The 2nd pass of Hidden/TerrainEngine/TerrainLayerUtils is used internally to do this
            //Note: Paintcontext must use a serialized terrain reference, otherwise breaks when executing "ApplyDelayedActions" when the project is saved!
            PaintContext c = TerrainPaintUtility.BeginPaintTexture(terrain, new Rect(0, 0, scaledSplatmapSize.x, scaledSplatmapSize.y), settings.layer);

            Graphics.Blit(alphaMap, c.destinationRenderTexture);

            TerrainPaintUtility.EndPaintTexture(c, UndoActionName);
        }
예제 #7
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);

                // manually create target context since we are possibly applying another terrain's layers and not its own
                int          layerIndex    = TerrainPaintUtility.FindTerrainLayerIndex(sampleTerrain, layer);
                Texture2D    layerTexture  = TerrainPaintUtility.GetTerrainAlphaMapChecked(sampleTerrain, layerIndex >> 2);
                PaintContext targetContext = PaintContext.CreateFromBounds(targetTerrain, targetRect, layerTexture.width, layerTexture.height);
                targetContext.CreateRenderTargets(RenderTextureFormat.R8);
                targetContext.GatherAlphamap(layer, true);
                sampleContext.sourceRenderTexture.filterMode = FilterMode.Point;
                mat.SetTexture("_CloneTex", sampleContext.sourceRenderTexture);
                Graphics.Blit(targetContext.sourceRenderTexture, targetContext.destinationRenderTexture, mat, (int)ShaderPasses.CloneAlphamap);
                // apply texture modifications and perform cleanup. same thing as calling TerrainPaintUtility.EndPaintTexture
                targetContext.ScatterAlphamap("Terrain Paint - Clone Brush (Texture)");
                targetContext.Cleanup();
            }
        }
예제 #8
0
        public override bool OnPaint(Terrain terrain, IOnPaint editContext)
        {
            BrushTransform brushXform   = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 0.0f);
            PaintContext   paintContext = TerrainPaintUtility.BeginPaintTexture(terrain, brushXform.GetBrushXYBounds(), m_SelectedTerrainLayer);

            if (paintContext == null)
            {
                return(false);
            }

            Material mat = TerrainPaintUtility.GetBuiltinPaintMaterial();

            // apply brush
            float   targetAlpha = 1.0f;     // always 1.0 now -- no subtractive painting (we assume this in the ScatterAlphaMap)
            Vector4 brushParams = new Vector4(editContext.brushStrength, targetAlpha, 0.0f, 0.0f);

            mat.SetTexture("_BrushTex", editContext.brushTexture);
            mat.SetVector("_BrushParams", brushParams);

            TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat);

            Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, (int)TerrainPaintUtility.BuiltinPaintMaterialPasses.PaintTexture);

            TerrainPaintUtility.EndPaintTexture(paintContext, "Terrain Paint - Texture");
            return(true);
        }
예제 #9
0
        public PaintContext AcquireTexture(bool writable, Terrain terrain, Rect boundsInTerrainSpace, TerrainLayer layer, int extraBorderPixels = 0)
        {
            m_WriteToTexture = writable;
            m_TextureContext = TerrainPaintUtility.BeginPaintTexture(terrain, boundsInTerrainSpace, layer, extraBorderPixels);

            if (m_TextureContext == null)
            {
                return(null);
            }

            m_TextureContext.sourceRenderTexture.name      = $"{m_Name}::TextureContext::SourceRT";
            m_TextureContext.destinationRenderTexture.name = $"{m_Name}::TextureContext::DestRT";
            return(m_TextureContext);
        }
예제 #10
0
        public override bool OnPaint(Terrain terrain, IOnPaint editContext)
        {
            if (Event.current.type == EventType.MouseDown)
            {
                m_PrevBrushPos = editContext.uv;
                return(false);
            }

            if (Event.current.type == EventType.MouseDrag && m_PreviousEvent == EventType.MouseDrag)
            {
                BrushTransform brushXform   = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 0.0f);
                PaintContext   paintContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXform.GetBrushXYBounds(), 1);

                Vector2 smudgeDir = editContext.uv - m_PrevBrushPos;

                paintContext.sourceRenderTexture.filterMode = FilterMode.Bilinear;

                Material mat = GetPaintMaterial();

                PaintContext maskContext = null;
                if (m_TextureMask || m_TextureStencil)
                {
                    TerrainLayer maskTerrainLayer = terrain.terrainData.terrainLayers[m_TextureMask ? m_maskIndex : m_stencilIndex];
                    maskContext = TerrainPaintUtility.BeginPaintTexture(terrain, brushXform.GetBrushXYBounds(), maskTerrainLayer);
                    if (maskContext == null)
                    {
                        return(false);
                    }
                    mat.SetTexture("_MaskTex", maskContext.sourceRenderTexture);
                }
                mat.SetInt("_MaskStencil", m_TextureMask ? 1 : (m_TextureStencil ? 2 : 0));

                Vector4 brushParams = new Vector4(editContext.brushStrength, smudgeDir.x, smudgeDir.y, 0);
                mat.SetTexture("_BrushTex", editContext.brushTexture);
                mat.SetVector("_BrushParams", brushParams);

                TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat);
                Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, 0);

                TerrainPaintUtility.EndPaintHeightmap(paintContext, "Terrain Paint - Masked Smudge");
                if (maskContext != null)
                {
                    TerrainPaintUtility.ReleaseContextResources(maskContext);
                }

                m_PrevBrushPos = editContext.uv;
            }
            m_PreviousEvent = Event.current.type;
            return(false);
        }
        private bool DoPaint(Terrain terrain, float brushStrength, Texture brushTexture, BrushTransform brushXform)
        {
            Rect rect = brushXform.GetBrushXYBounds();

            PaintContext paintContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXform.GetBrushXYBounds(), 1);

            if (paintContext == null)
            {
                return(false);
            }

            paintContext.sourceRenderTexture.filterMode = FilterMode.Bilinear;

            Material mat = GetPaintMaterial();

            PaintContext maskContext = null;

            if (m_TextureMask || m_TextureStencil)
            {
                TerrainLayer maskTerrainLayer = terrain.terrainData.terrainLayers[m_TextureMask ? m_maskIndex : m_stencilIndex];
                maskContext = TerrainPaintUtility.BeginPaintTexture(terrain, rect, maskTerrainLayer);
                if (maskContext == null)
                {
                    return(false);
                }
                mat.SetTexture("_MaskTex", maskContext.sourceRenderTexture);
            }
            mat.SetInt("_MaskStencil", m_TextureMask ? 1 : (m_TextureStencil ? 2 : 0));

            Vector4 brushParams = new Vector4(brushStrength, 0.0f, m_FeatureSize, 0);

            mat.SetTexture("_BrushTex", brushTexture);
            mat.SetVector("_BrushParams", brushParams);

            TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat);

            Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, 0);

            TerrainPaintUtility.EndPaintHeightmap(paintContext, "Terrain Paint - Masked Smooth Sharpen");
            if (maskContext != null)
            {
                TerrainPaintUtility.ReleaseContextResources(maskContext);
            }

            return(true);
        }
예제 #12
0
        public override bool OnPaint(Terrain terrain, IOnPaint editContext)
        {
            BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 0.0f);

            Rect rect = brushXform.GetBrushXYBounds();

            PaintContext paintContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, rect, 1);

            Material mat = GetPaintMaterial();

            PaintContext maskContext = null;

            if (m_TextureMask || m_TextureStencil)
            {
                TerrainLayer maskTerrainLayer = terrain.terrainData.terrainLayers[m_TextureMask ? m_maskIndex : m_stencilIndex];
                maskContext = TerrainPaintUtility.BeginPaintTexture(terrain, rect, maskTerrainLayer);
                if (maskContext == null)
                {
                    return(false);
                }
                mat.SetTexture("_MaskTex", maskContext.sourceRenderTexture);
            }
            mat.SetInt("_MaskStencil", m_TextureMask ? 1 : (m_TextureStencil ? 2 : 0));

            // apply brush
            Vector4 brushParams = new Vector4(
                editContext.brushStrength,
                m_ErosionStrength,
                m_MixStrength,
                0.0f);

            mat.SetTexture("_BrushTex", editContext.brushTexture);
            mat.SetVector("_BrushParams", brushParams);
            TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat);
            Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, 0);

            TerrainPaintUtility.EndPaintHeightmap(paintContext, "Masked Ridge Erode");

            if (maskContext != null)
            {
                TerrainPaintUtility.ReleaseContextResources(maskContext);
            }

            return(false);
        }
예제 #13
0
        public override bool OnPaint(Terrain terrain, IOnPaint editContext)
        {
            Rect brushRect = TerrainPaintUtility.CalculateBrushRectInTerrainUnits(terrain, editContext.uv, editContext.brushSize);

            TerrainPaintUtility.PaintContext paintContext = TerrainPaintUtility.BeginPaintTexture(terrain, brushRect, m_SelectedTerrainLayer);
            if (paintContext == null)
            {
                return(false);
            }

            Material mat = TerrainPaintUtility.GetBuiltinPaintMaterial();
            // apply brush
            Vector4 brushParams = new Vector4(editContext.brushStrength, m_SplatAlpha, 0.0f, 0.0f);

            mat.SetTexture("_BrushTex", editContext.brushTexture);
            mat.SetVector("_BrushParams", brushParams);
            Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, (int)TerrainPaintUtility.BuiltinPaintMaterialPasses.PaintTexture);

            TerrainPaintUtility.EndPaintTexture(paintContext, "Terrain Paint - Texture");
            return(true);
        }
예제 #14
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);
            }
        }
        public override bool OnPaint(Terrain terrain, IOnPaint editContext)
        {
            if (Event.current.type == EventType.MouseDown)
            {
                m_PrevBrushPos = editContext.uv;
            }

            float min = Mathf.Min(terrain.terrainData.size.x, terrain.terrainData.size.z);

            float extent = editContext.brushSize * Mathf.Lerp(1.2f, 1.0f, 1.0f - m_Extent) + min * Mathf.Lerp(0.1f, 1.0f, m_Extent);

            m_brushStrength = editContext.brushStrength;

            Vector2 waterVel = (editContext.uv - m_PrevBrushPos) * m_BrushVel * -10000.0f;

            m_PrevBrushPos = editContext.uv;

            GetPaintMaterials();

            m_Material.SetVector("_WaterVel", waterVel);

            if (continuing && editContext.brushSize == oldBrushSize && terrain == oldTerrain)
            {
                Vector2 shift = BrushUVDelta(editContext.uv, terrain, soilWater[0].width, soilWater[0].height);

                if (Mathf.Max(Mathf.Abs(shift.x), Mathf.Abs(shift.y)) < 0.5f)
                {
                    m_Material.SetVector("_WaterShift", shift);
                    return(true);
                }
            }

            oldTerrain = terrain;

            oldBrushSize = editContext.brushSize;
            continuing   = true;

            m_Material.SetFloat("_HeightScale", terrain.terrainData.size.y);

            BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, extent, 0.0f);
            Rect           rect       = brushXform.GetBrushXYBounds();

            Vector2 oldUV = rect.center;

            oldUV.x *= 0.5f / terrain.terrainData.bounds.extents.x;
            oldUV.y *= 0.5f / terrain.terrainData.bounds.extents.z;

            if (terrain.leftNeighbor == null)
            {
                rect.x = Mathf.Max(0.0f, rect.x);
            }
            if (terrain.bottomNeighbor == null)
            {
                rect.y = Mathf.Max(0.0f, rect.y);
            }
            if (terrain.leftNeighbor == null && terrain.rightNeighbor == null)
            {
                rect.width = Mathf.Min(rect.width, terrain.terrainData.bounds.extents.x * 2.0f);
            }
            if (terrain.topNeighbor == null && terrain.bottomNeighbor == null)
            {
                rect.height = Mathf.Min(rect.height, terrain.terrainData.bounds.extents.z * 2.0f);
            }
            if (terrain.rightNeighbor == null)
            {
                rect.x = Mathf.Min(rect.x, terrain.terrainData.bounds.extents.x * 2.0f - rect.width);
            }
            if (terrain.topNeighbor == null)
            {
                rect.y = Mathf.Min(rect.y, terrain.terrainData.bounds.extents.z * 2.0f - rect.height);
            }

            Vector2 uv = rect.center;

            uv.x *= 0.5f / terrain.terrainData.bounds.extents.x;
            uv.y *= 0.5f / terrain.terrainData.bounds.extents.z;

            if (m_TextureMask || m_TextureStencil)
            {
                TerrainLayer maskTerrainLayer = terrain.terrainData.terrainLayers[m_TextureMask ? m_maskIndex : m_stencilIndex];
                maskContext = TerrainPaintUtility.BeginPaintTexture(terrain, rect, maskTerrainLayer);
                if (maskContext == null)
                {
                    return(false);
                }
            }

            SetMaterial(m_Material, editContext);

            src = 0;

            InitHeightTextures(terrain, rect);
            TerrainPaintUtility.SetupTerrainToolMaterialProperties(heightContext, brushXform, m_Material);

            InitWaterSim(heightContext.sourceRenderTexture.width, heightContext.sourceRenderTexture.height);
            InitDisplay(terrain, new Vector2(rect.width, rect.height), uv);

            float interp = editContext.brushSize / extent;

            uvBase = uv * (1.0f - interp) + oldUV * interp;

            Vector2 shiftStart = BrushUVDelta(editContext.uv, terrain, soilWater[0].width, soilWater[0].height);

            m_Material.SetVector("_WaterShift", shiftStart);
            m_Material.SetFloat("_Extent", extent / editContext.brushSize);

            return(false);
        }
예제 #16
0
 public PaintContext AcquireTexture(bool writable, Terrain terrain, Rect boundsInTerrainSpace, TerrainLayer layer, int extraBorderPixels = 0)
 {
     m_WriteToTexture = writable;
     m_TextureContext = TerrainPaintUtility.BeginPaintTexture(terrain, boundsInTerrainSpace, layer, extraBorderPixels);
     return(m_TextureContext);
 }
예제 #17
0
        public override bool OnPaint(Terrain terrain, IOnPaint editContext)
        {
            commonUI.OnPaint(terrain, editContext);

            if (!commonUI.allowPaint)
            {
                return(true);
            }

            if (Event.current.type == EventType.MouseDown)
            {
                m_PrevBrushPos = editContext.uv;
                return(false);
            }

            if (Event.current.type == EventType.MouseDrag && m_PreviousEvent == EventType.MouseDrag)
            {
                Vector2 uv = editContext.uv;

                if (commonUI.ScatterBrushStamp(ref terrain, ref uv))
                {
                    Material mat       = GetPaintMaterial();
                    Vector2  smudgeDir = uv - m_PrevBrushPos;

                    BrushTransform brushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, uv, commonUI.brushSize, commonUI.brushRotation);

                    Vector4 brushParams = new Vector4(commonUI.brushStrength, smudgeDir.x, smudgeDir.y, 0);
                    mat.SetTexture("_BrushTex", editContext.brushTexture);
                    mat.SetVector("_BrushParams", brushParams);

                    //smudge splat map
                    if (m_AffectMaterials)
                    {
                        for (int i = 0; i < terrain.terrainData.terrainLayers.Length; i++)
                        {
                            TerrainLayer layer = terrain.terrainData.terrainLayers[i];

                            if (layer == null)
                            {
                                continue;                // nothing to paint if the layer is NULL
                            }
                            PaintContext sampleContext = TerrainPaintUtility.BeginPaintTexture(terrain, brushXform.GetBrushXYBounds(), layer);
                            Graphics.Blit(sampleContext.sourceRenderTexture, sampleContext.destinationRenderTexture, mat, 0);
                            TerrainPaintUtility.EndPaintTexture(sampleContext, "Terrain Paint - Twist Brush (Texture)");
                        }
                    }

                    //smudge the height map
                    if (m_AffectHeight)
                    {
                        PaintContext paintContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXform.GetBrushXYBounds(), 1);
                        TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat);
                        Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, 0);
                        TerrainPaintUtility.EndPaintHeightmap(paintContext, "Terrain Paint - Twist Brush (Height)");
                    }

                    m_PrevBrushPos = uv;
                }
            }
            m_PreviousEvent = Event.current.type;
            return(false);
        }
예제 #18
0
        private bool DoPaint(Terrain terrain, float brushStrength, Texture brushTexture, Rect rect, BrushTransform brushXform)
        {
            if (disablePaint)
            {
                return(false);
            }

            m_SelectedTerrainLayer = terrain.terrainData.terrainLayers[m_textureIndex];
            PaintContext paintContext = TerrainPaintUtility.BeginPaintTexture(terrain, rect, m_SelectedTerrainLayer);

            if (paintContext == null)
            {
                return(false);
            }

            PaintContext heightContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, rect, 1);

            if (heightContext == null)
            {
                return(false);
            }

            if (terrain.normalmapTexture == null)
            {
                Debug.Log("Please check the Draw Instanced option under terrain settings to use this tool");
                return(false);
            }
            PaintContext normalContext = TerrainPaintUtility.CollectNormals(terrain, rect, 0);

            Material mat = GetPaintMaterial();

            float extent = textureParams[m_textureIndex].heightExtent;
            float blend  = textureParams[m_textureIndex].heightBlend;
            float height = textureParams[m_textureIndex].heightMaxPoint;

            if (textureParams[m_textureIndex].heightRelative)
            {
                extent /= relativeHeightMult;
                height /= relativeHeightMult;
            }
            else
            {
                extent /= terrain.terrainData.size.y;
                height /= terrain.terrainData.size.y;
            }
            Vector4 brushParams = new Vector4(brushStrength, height,
                                              textureParams[m_textureIndex].heightMask ? extent * (1.0f - blend) : 10000.0f, extent * blend);

            extent = textureParams[m_textureIndex].slopeExtent;
            blend  = textureParams[m_textureIndex].slopeBlend;
            Vector4 slopeParams = new Vector4(textureParams[m_textureIndex].slopeMaxPoint,
                                              textureParams[m_textureIndex].slopeMask ? extent * (1.0f - blend) : 1.0f, extent * blend, textureParams[m_textureIndex].maxValue);

            PaintContext maskContext = null;

            if (textureParams[m_textureIndex].textureMask || textureParams[m_textureIndex].textureStencil)
            {
                TerrainLayer maskTerrainLayer = terrain.terrainData.terrainLayers[textureParams[m_textureIndex].textureMask ? textureParams[m_textureIndex].maskIndex : textureParams[m_textureIndex].stencilIndex];
                maskContext = TerrainPaintUtility.BeginPaintTexture(terrain, rect, maskTerrainLayer);
                if (maskContext == null)
                {
                    return(false);
                }
                mat.SetTexture("_MaskTex", maskContext.sourceRenderTexture);
            }
            mat.SetInt("_MaskStencil", textureParams[m_textureIndex].textureMask ? 1 : (textureParams[m_textureIndex].textureStencil ? 2 : 0));

            mat.SetTexture("_BrushTex", brushTexture);

            mat.SetTexture("_HeightTex", heightContext.sourceRenderTexture);
            mat.SetTexture("_NormalTex", normalContext.sourceRenderTexture);

            mat.SetVector("_BrushParams", brushParams);
            mat.SetVector("_SlopeParams", slopeParams);
            mat.SetFloat("_FeatureSize", textureParams[m_textureIndex].heightRelative?textureParams[m_textureIndex].heightFeatureSize:0.0f);

            if (brushTexture == null)
            {
                mat.SetFloat("_AspectRatio", terrain.terrainData.size.x / terrain.terrainData.size.z);
            }
            else
            {
                mat.SetFloat("_AspectRatio", (float)paintContext.sourceRenderTexture.height / (float)paintContext.sourceRenderTexture.width);
            }
            TerrainPaintUtility.SetupTerrainToolMaterialProperties(paintContext, brushXform, mat);
            Graphics.Blit(paintContext.sourceRenderTexture, paintContext.destinationRenderTexture, mat, 0);
            TerrainPaintUtility.EndPaintTexture(paintContext, "Terrain Paint - Masked Texture");
            TerrainPaintUtility.ReleaseContextResources(heightContext);
            TerrainPaintUtility.ReleaseContextResources(normalContext);
            if (maskContext != null)
            {
                TerrainPaintUtility.ReleaseContextResources(maskContext);
            }

            return(true);
        }
 public static PaintContext BeginFillTexture(Terrain terrain, TerrainLayer inputLayer)
 {
     return(TerrainPaintUtility.BeginPaintTexture(terrain, GetTerrainBounds(terrain), inputLayer));
 }