Exemple #1
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)
        {
            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);
        }
Exemple #3
0
        public void Release(PaintContext paintContext)
        {
            if (ReferenceEquals(paintContext, m_HeightmapContext))
            {
                if (m_WriteToHeightmap)
                {
                    TerrainPaintUtility.EndPaintHeightmap(m_HeightmapContext, $"{m_Name} - Heightmap");
                }
                else
                {
                    TerrainPaintUtility.ReleaseContextResources(m_HeightmapContext);
                }

                m_HeightmapContext = null;
            }
            else if (ReferenceEquals(paintContext, m_NormalmapContext))
            {
                TerrainPaintUtility.ReleaseContextResources(m_NormalmapContext);
                m_NormalmapContext = null;
            }
            else if (ReferenceEquals(paintContext, m_TextureContext))
            {
                if (m_WriteToTexture)
                {
                    TerrainPaintUtility.EndPaintTexture(m_TextureContext, $"{m_Name} - Texture");
                }
                else
                {
                    TerrainPaintUtility.ReleaseContextResources(m_TextureContext);
                }

                m_TextureContext = null;
            }
        }
Exemple #4
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);
        }
        public override bool OnPaint(Terrain terrain, IOnPaint editContext)
        {
            BrushTransform targetBrushXform = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.uv, editContext.brushSize, 1);

            Material mat         = GetPaintMaterial();
            Vector4  brushParams = new Vector4(editContext.brushStrength, 0, 0, 0f);

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

            Rect targetRect             = targetBrushXform.GetBrushXYBounds();
            int  numSampleTerrainLayers = terrain.terrainData.terrainLayers.Length;

            for (int i = 0; i < numSampleTerrainLayers; ++i)
            {
                TerrainLayer layer = terrain.terrainData.terrainLayers[i];
                if (layer == null)
                {
                    continue;
                }

                int          layerIndex    = TerrainPaintUtility.FindTerrainLayerIndex(terrain, layer);
                Texture2D    layerTexture  = TerrainPaintUtility.GetTerrainAlphaMapChecked(terrain, layerIndex >> 2);
                PaintContext targetContext = PaintContext.CreateFromBounds(terrain, targetRect, layerTexture.width, layerTexture.height);
                targetContext.CreateRenderTargets(RenderTextureFormat.R8);
                targetContext.GatherAlphamap(layer, true);
                Graphics.Blit(targetContext.sourceRenderTexture, targetContext.destinationRenderTexture, mat, 0);

                TerrainPaintUtility.EndPaintTexture(targetContext, "Terrain Paint - Smooth Splatmaps");
            }
            return(false);
        }
        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 + ")");
            }
        }
        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);
        }
Exemple #8
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);
        }
Exemple #9
0
        public void Release(PaintContext paintContext)
        {
            if (ReferenceEquals(paintContext, m_HeightmapContext))
            {
                if (m_WriteToHeightmap)
                {
                    TerrainPaintUtility.EndPaintHeightmap(m_HeightmapContext, $"{m_Name} - Heightmap");
                }
                else
                {
                    TerrainPaintUtility.ReleaseContextResources(m_HeightmapContext);
                }

                m_HeightmapContext = null;
            }
            else if (ReferenceEquals(paintContext, m_NormalmapContext))
            {
                TerrainPaintUtility.ReleaseContextResources(m_NormalmapContext);
                m_NormalmapContext = null;
            }
            else if (ReferenceEquals(paintContext, m_TextureContext))
            {
                if (m_WriteToTexture)
                {
                    TerrainPaintUtility.EndPaintTexture(m_TextureContext, $"{m_Name} - Texture");
                }
                else
                {
                    TerrainPaintUtility.ReleaseContextResources(m_TextureContext);
                }

                m_TextureContext = null;
            }
#if UNITY_2019_3_OR_NEWER
            else if (ReferenceEquals(paintContext, m_HolesContext))
            {
                if (m_WriteToHoles)
                {
                    TerrainPaintUtility.EndPaintHoles(m_HolesContext, "Terrain Paint - Paint Holes");
                }
                else
                {
                    TerrainPaintUtility.ReleaseContextResources(m_HolesContext);
                }

                m_HolesContext = null;
            }
#endif
        }
        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);
        }
        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);
        }
 public static void EndFillTexture(PaintContext ctx, string editorUndoString)
 {
     TerrainPaintUtility.EndPaintTexture(ctx, editorUndoString);
 }
Exemple #13
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);
        }