示例#1
0
        public void GatherAlphamap(TerrainLayer inputLayer, bool addLayerIfDoesntExist = true)
        {
            if (inputLayer == null)
            {
                return;
            }

            Material copyTerrainLayerMaterial = TerrainPaintUtility.GetCopyTerrainLayerMaterial();

            Vector4[] layerMasks = { new Vector4(1, 0, 0, 0), new Vector4(0, 1, 0, 0), new Vector4(0, 0, 1, 0), new Vector4(0, 0, 0, 1) };

            GatherInternal(
                t =>
            {       // return the texture to be gathered from this terrain tile
                SplatmapUserData userData = GetTerrainLayerUserData(t, inputLayer, addLayerIfDoesntExist);
                if (userData != null)
                {
                    return(TerrainPaintUtility.GetTerrainAlphaMapChecked(t.terrain, userData.mapIndex));
                }
                else
                {
                    return(null);
                }
            },

                new Color(0.0f, 0.0f, 0.0f, 0.0f),
                "PaintContext.GatherAlphamap",
                copyTerrainLayerMaterial, 0,
                t =>
            {       // before blit -- setup layer mask in the material
                SplatmapUserData userData = GetTerrainLayerUserData(t);
                copyTerrainLayerMaterial.SetVector("_LayerMask", layerMasks[userData.channelIndex]);
            });
        }
示例#2
0
        private SplatmapUserData GetTerrainLayerUserData(ITerrainInfo context, TerrainLayer terrainLayer = null, bool addLayerIfDoesntExist = false)
        {
            // look up existing user data, if any
            SplatmapUserData userData = (context.userData as SplatmapUserData);

            if (userData != null)
            {
                // check if it is appropriate, return if so
                if ((terrainLayer == null) || (terrainLayer == userData.terrainLayer))
                {
                    return(userData);
                }
                else
                {
                    userData = null;
                }
            }

            // otherwise let's build it
            if (userData == null)
            {
                int tileLayerIndex = -1;
                if (terrainLayer != null)
                {
                    // look for the layer on the terrain
                    tileLayerIndex = TerrainPaintUtility.FindTerrainLayerIndex(context.terrain, terrainLayer);
                    if ((tileLayerIndex == -1) && (addLayerIfDoesntExist))
                    {
                        onTerrainTileBeforePaint?.Invoke(context, ToolAction.AddTerrainLayer, "Adding Terrain Layer");
                        tileLayerIndex = TerrainPaintUtility.AddTerrainLayer(context.terrain, terrainLayer);
                    }
                }

                // if we found the layer, build user data
                if (tileLayerIndex != -1)
                {
                    userData = new SplatmapUserData();
                    userData.terrainLayer      = terrainLayer;
                    userData.terrainLayerIndex = tileLayerIndex;
                    userData.mapIndex          = tileLayerIndex >> 2;
                    userData.channelIndex      = tileLayerIndex & 0x3;
                }
                context.userData = userData;
            }
            return(userData);
        }
示例#3
0
        public void ScatterAlphamap(string editorUndoName)
        {
            Vector4[] layerMasks = { new Vector4(1, 0, 0, 0), new Vector4(0, 1, 0, 0), new Vector4(0, 0, 1, 0), new Vector4(0, 0, 0, 1) };
            Material  copyTerrainLayerMaterial = TerrainPaintUtility.GetCopyTerrainLayerMaterial();

            var rtdesc = new RenderTextureDescriptor(destinationRenderTexture.width, destinationRenderTexture.height, RenderTextureFormat.ARGB32);

            rtdesc.sRGB             = false;
            rtdesc.useMipMap        = false;
            rtdesc.autoGenerateMips = false;
            RenderTexture tempTarget = RenderTexture.GetTemporary(rtdesc);

            ScatterInternal(
                t => // We're going to do ALL of the work in this terrainToRT function, as it is very custom, and we'll just return null to skip the ScatterInternal rendering
            {
                SplatmapUserData userData = GetTerrainLayerUserData(t);
                if (userData != null)
                {
                    onTerrainTileBeforePaint?.Invoke(t, ToolAction.PaintTexture, editorUndoName);

                    int targetAlphamapIndex         = userData.mapIndex;
                    int targetChannelIndex          = userData.channelIndex;
                    Texture2D targetAlphamapTexture = t.terrain.terrainData.alphamapTextures[targetAlphamapIndex];

                    destinationRenderTexture.filterMode = FilterMode.Point;
                    sourceRenderTexture.filterMode      = FilterMode.Point;

                    // iterate all alphamaps to modify them (have to modify all to renormalize)
                    for (int i = 0; i <= t.terrain.terrainData.alphamapTextureCount; i++)       // NOTE: this is a non-standard for loop
                    {
                        // modify the target index last, (skip it the first time)
                        if (i == targetAlphamapIndex)
                        {
                            continue;
                        }
                        int alphamapIndex = (i == t.terrain.terrainData.alphamapTextureCount) ? targetAlphamapIndex : i;

                        Texture2D alphamapTexture = t.terrain.terrainData.alphamapTextures[alphamapIndex];
                        if ((alphamapTexture.width != targetTextureWidth) || (alphamapTexture.height != targetTextureHeight))
                        {
                            Debug.LogWarning("PaintContext alphamap operations must use the same resolution for all Terrains - mismatched Terrains are ignored.", t.terrain);
                            continue;
                        }

                        RenderTexture.active = tempTarget;
                        GL.PushMatrix();
                        GL.LoadPixelMatrix(0, tempTarget.width, 0, tempTarget.height);
                        {
                            copyTerrainLayerMaterial.SetTexture("_MainTex", destinationRenderTexture);
                            copyTerrainLayerMaterial.SetTexture("_OldAlphaMapTexture", sourceRenderTexture);
                            copyTerrainLayerMaterial.SetTexture("_OriginalTargetAlphaMap", targetAlphamapTexture);

                            copyTerrainLayerMaterial.SetTexture("_AlphaMapTexture", alphamapTexture);
                            copyTerrainLayerMaterial.SetVector("_LayerMask", alphamapIndex == targetAlphamapIndex ? layerMasks[targetChannelIndex] : Vector4.zero);
                            copyTerrainLayerMaterial.SetVector("_OriginalTargetAlphaMask", layerMasks[targetChannelIndex]);
                            copyTerrainLayerMaterial.SetPass(1);

                            TerrainPaintUtility.DrawQuad2(t.clippedPCPixels, t.clippedPCPixels, destinationRenderTexture, t.clippedTerrainPixels, alphamapTexture);
                        }
                        GL.PopMatrix();

                        t.terrain.terrainData.CopyActiveRenderTextureToTexture(TerrainData.AlphamapTextureName, alphamapIndex, t.clippedPCPixels, t.clippedTerrainPixels.min, true);
                    }

                    RenderTexture.active = null;
                    OnTerrainPainted(t, ToolAction.PaintTexture);
                }
                return(null);
            },
                "PaintContext.ScatterAlphamap",
                copyTerrainLayerMaterial, 0);

            RenderTexture.ReleaseTemporary(tempTarget);
        }