Example #1
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);
        }
 internal static void DrawQuad(RectInt destinationPixels, RectInt sourcePixels, Texture sourceTexture)
 {
     TerrainPaintUtility.DrawQuad2(destinationPixels, sourcePixels, sourceTexture, sourcePixels, sourceTexture);
 }