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); }