private void GatherInternal( Func <ITerrainInfo, Texture> terrainToTexture, Color defaultColor, string operationName, Material blitMaterial = null, int blitPass = 0, Action <ITerrainInfo> beforeBlit = null, Action <ITerrainInfo> afterBlit = null) { if (blitMaterial == null) { blitMaterial = TerrainPaintUtility.GetBlitMaterial(); } RenderTexture.active = sourceRenderTexture; GL.Clear(false, true, defaultColor); GL.PushMatrix(); GL.LoadPixelMatrix(0, pixelRect.width, 0, pixelRect.height); for (int i = 0; i < m_TerrainTiles.Count; i++) { TerrainTile terrainTile = m_TerrainTiles[i]; if (!terrainTile.gatherEnable) { continue; } Texture sourceTexture = terrainToTexture(terrainTile); if ((sourceTexture == null) || (!terrainTile.gatherEnable)) // double check gatherEnable in case terrainToTexture modified it { continue; } if ((sourceTexture.width != targetTextureWidth) || (sourceTexture.height != targetTextureHeight)) { Debug.LogWarning(operationName + " requires the same resolution texture for all Terrains - mismatched Terrains are ignored.", terrainTile.terrain); continue; } beforeBlit?.Invoke(terrainTile); if (!terrainTile.gatherEnable) // check again, beforeBlit may have modified it { continue; } FilterMode oldFilterMode = sourceTexture.filterMode; sourceTexture.filterMode = FilterMode.Point; blitMaterial.SetTexture("_MainTex", sourceTexture); blitMaterial.SetPass(blitPass); TerrainPaintUtility.DrawQuad(terrainTile.clippedPCPixels, terrainTile.clippedTerrainPixels, sourceTexture); sourceTexture.filterMode = oldFilterMode; afterBlit?.Invoke(terrainTile); } GL.PopMatrix(); RenderTexture.active = oldRenderTexture; }
public void ScatterHeightmap(string editorUndoName) { Material blitMaterial = TerrainPaintUtility.GetBlitMaterial(); for (int i = 0; i < m_TerrainTiles.Count; i++) { TerrainTile terrainTile = m_TerrainTiles[i]; if (terrainTile.clippedLocal.width == 0 || terrainTile.clippedLocal.height == 0) { continue; } RenderTexture heightmap = terrainTile.terrain.terrainData.heightmapTexture; if ((heightmap.width != targetTextureWidth) || (heightmap.height != targetTextureHeight)) { Debug.LogWarning("PaintContext heightmap operations must use the same resolution for all Terrains - mismatched Terrains are ignored.", terrainTile.terrain); continue; } if (onTerrainTileBeforePaint != null) { onTerrainTileBeforePaint(terrainTile, ToolAction.PaintHeightmap, editorUndoName); } RenderTexture.active = heightmap; Rect readRect = new Rect( (terrainTile.clippedLocal.x + terrainTile.rect.x - pixelRect.x + terrainTile.writeOffset.x) / (float)pixelRect.width, (terrainTile.clippedLocal.y + terrainTile.rect.y - pixelRect.y + terrainTile.writeOffset.y) / (float)pixelRect.height, (terrainTile.clippedLocal.width) / (float)pixelRect.width, (terrainTile.clippedLocal.height) / (float)pixelRect.height); Rect writeRect = new Rect( terrainTile.clippedLocal.x, terrainTile.clippedLocal.y, terrainTile.clippedLocal.width, terrainTile.clippedLocal.height); destinationRenderTexture.filterMode = FilterMode.Point; blitMaterial.SetTexture("_MainTex", destinationRenderTexture); blitMaterial.SetPass(0); TerrainPaintUtility.DrawQuad(heightmap.width, heightmap.height, readRect, writeRect); terrainTile.terrain.terrainData.UpdateDirtyRegion(terrainTile.clippedLocal.x, terrainTile.clippedLocal.y, terrainTile.clippedLocal.width, terrainTile.clippedLocal.height, !terrainTile.terrain.drawInstanced); OnTerrainPainted(terrainTile, ToolAction.PaintHeightmap); } }
public void GatherNormals() { RenderTexture rt = originTerrain.normalmapTexture; Material blitMaterial = TerrainPaintUtility.GetBlitMaterial(); RenderTexture.active = sourceRenderTexture; GL.Clear(false, true, new Color(0.5f, 0.5f, 0.5f, 0.5f)); for (int i = 0; i < m_TerrainTiles.Count; i++) { TerrainTile terrainTile = m_TerrainTiles[i]; if (terrainTile.clippedLocal.width == 0 || terrainTile.clippedLocal.height == 0) { continue; } Texture sourceTexture = terrainTile.terrain.normalmapTexture; if ((sourceTexture.width != targetTextureWidth) || (sourceTexture.height != targetTextureHeight)) { Debug.LogWarning("PaintContext normalmap operations must use the same resolution for all Terrains - mismatched Terrains are ignored.", terrainTile.terrain); continue; } Rect readRect = new Rect( (terrainTile.clippedLocal.x + terrainTile.readOffset.x) / (float)targetTextureWidth, (terrainTile.clippedLocal.y + terrainTile.readOffset.y) / (float)targetTextureHeight, (terrainTile.clippedLocal.width) / (float)targetTextureWidth, (terrainTile.clippedLocal.height) / (float)targetTextureHeight); FilterMode oldFilterMode = sourceTexture.filterMode; sourceTexture.filterMode = FilterMode.Point; blitMaterial.SetTexture("_MainTex", sourceTexture); blitMaterial.SetPass(0); TerrainPaintUtility.DrawQuad(pixelRect.width, pixelRect.height, readRect, terrainTile.validPaintRect); sourceTexture.filterMode = oldFilterMode; } RenderTexture.active = oldRenderTexture; }
public void GatherNormals() { RenderTexture rt = originTerrain.normalmapTexture; Material blitMaterial = TerrainPaintUtility.GetBlitMaterial(); RenderTexture.active = sourceRenderTexture; GL.Clear(false, true, new Color(0.5f, 0.5f, 0.5f, 0.5f)); GL.PushMatrix(); GL.LoadPixelMatrix(0, pixelRect.width, 0, pixelRect.height); for (int i = 0; i < m_TerrainTiles.Count; i++) { TerrainTile terrainTile = m_TerrainTiles[i]; if (terrainTile.clippedLocalPixels.width == 0 || terrainTile.clippedLocalPixels.height == 0) { continue; } Texture sourceTexture = terrainTile.terrain.normalmapTexture; if ((sourceTexture.width != targetTextureWidth) || (sourceTexture.height != targetTextureHeight)) { Debug.LogWarning("PaintContext normalmap operations must use the same resolution for all Terrains - mismatched Terrains are ignored.", terrainTile.terrain); continue; } FilterMode oldFilterMode = sourceTexture.filterMode; sourceTexture.filterMode = FilterMode.Point; blitMaterial.SetTexture("_MainTex", sourceTexture); blitMaterial.SetPass(0); TerrainPaintUtility.DrawQuad(terrainTile.clippedPCPixels, terrainTile.clippedLocalPixels, sourceTexture); sourceTexture.filterMode = oldFilterMode; } GL.PopMatrix(); RenderTexture.active = oldRenderTexture; }
public void ScatterHeightmap(string editorUndoName) { Material blitMaterial = TerrainPaintUtility.GetBlitMaterial(); for (int i = 0; i < m_TerrainTiles.Count; i++) { TerrainTile terrainTile = m_TerrainTiles[i]; if (terrainTile.clippedLocalPixels.width == 0 || terrainTile.clippedLocalPixels.height == 0) { continue; } RenderTexture heightmap = terrainTile.terrain.terrainData.heightmapTexture; if ((heightmap.width != targetTextureWidth) || (heightmap.height != targetTextureHeight)) { Debug.LogWarning("PaintContext heightmap operations must use the same resolution for all Terrains - mismatched Terrains are ignored.", terrainTile.terrain); continue; } if (onTerrainTileBeforePaint != null) { onTerrainTileBeforePaint(terrainTile, ToolAction.PaintHeightmap, editorUndoName); } RenderTexture.active = heightmap; GL.PushMatrix(); GL.LoadPixelMatrix(0, heightmap.width, 0, heightmap.height); destinationRenderTexture.filterMode = FilterMode.Point; blitMaterial.SetTexture("_MainTex", destinationRenderTexture); blitMaterial.SetPass(0); TerrainPaintUtility.DrawQuad(terrainTile.clippedLocalPixels, terrainTile.clippedPCPixels, destinationRenderTexture); GL.PopMatrix(); terrainTile.terrain.terrainData.UpdateDirtyRegion(terrainTile.clippedLocalPixels.x, terrainTile.clippedLocalPixels.y, terrainTile.clippedLocalPixels.width, terrainTile.clippedLocalPixels.height, !terrainTile.terrain.drawInstanced); OnTerrainPainted(terrainTile, ToolAction.PaintHeightmap); } }
private void ScatterInternal( Func <ITerrainInfo, RenderTexture> terrainToRT, string operationName, Material blitMaterial = null, int blitPass = 0, Action <ITerrainInfo> beforeBlit = null, Action <ITerrainInfo> afterBlit = null) { var oldRT = RenderTexture.active; if (blitMaterial == null) { blitMaterial = TerrainPaintUtility.GetBlitMaterial(); } for (int i = 0; i < m_TerrainTiles.Count; i++) { TerrainTile terrainTile = m_TerrainTiles[i]; if (!terrainTile.scatterEnable) { continue; } RenderTexture target = terrainToRT(terrainTile); if ((target == null) || (!terrainTile.scatterEnable)) // double check scatterEnable in case terrainToRT modified it { continue; } if ((target.width != targetTextureWidth) || (target.height != targetTextureHeight)) { Debug.LogWarning(operationName + " requires the same resolution for all Terrains - mismatched Terrains are ignored.", terrainTile.terrain); continue; } beforeBlit?.Invoke(terrainTile); if (!terrainTile.scatterEnable) // check again, beforeBlit may have modified it { continue; } RenderTexture.active = target; GL.PushMatrix(); GL.LoadPixelMatrix(0, target.width, 0, target.height); { FilterMode oldFilterMode = destinationRenderTexture.filterMode; destinationRenderTexture.filterMode = FilterMode.Point; blitMaterial.SetTexture("_MainTex", destinationRenderTexture); blitMaterial.SetPass(blitPass); TerrainPaintUtility.DrawQuad(terrainTile.clippedTerrainPixels, terrainTile.clippedPCPixels, destinationRenderTexture); destinationRenderTexture.filterMode = oldFilterMode; } GL.PopMatrix(); afterBlit?.Invoke(terrainTile); } RenderTexture.active = oldRT; }
public void GatherAlphamap(TerrainLayer inputLayer, bool addLayerIfDoesntExist = true) { if (inputLayer == null) { return; } int terrainLayerIndex = TerrainPaintUtility.FindTerrainLayerIndex(originTerrain, inputLayer); if (terrainLayerIndex == -1 && addLayerIfDoesntExist) { terrainLayerIndex = TerrainPaintUtility.AddTerrainLayer(originTerrain, inputLayer); } RenderTexture.active = sourceRenderTexture; GL.Clear(false, true, new Color(0.0f, 0.0f, 0.0f, 0.0f)); GL.PushMatrix(); GL.LoadPixelMatrix(0, pixelRect.width, 0, pixelRect.height); 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(); for (int i = 0; i < m_TerrainTiles.Count; i++) { TerrainTile terrainTile = m_TerrainTiles[i]; if (terrainTile.clippedLocalPixels.width == 0 || terrainTile.clippedLocalPixels.height == 0) { continue; } int tileLayerIndex = TerrainPaintUtility.FindTerrainLayerIndex(terrainTile.terrain, inputLayer); if (tileLayerIndex == -1) { if (!addLayerIfDoesntExist) { // setting these to zero will prevent them from being used later terrainTile.clippedLocalPixels.width = 0; terrainTile.clippedLocalPixels.height = 0; terrainTile.clippedPCPixels.width = 0; terrainTile.clippedPCPixels.height = 0; continue; } tileLayerIndex = TerrainPaintUtility.AddTerrainLayer(terrainTile.terrain, inputLayer); } terrainTile.mapIndex = tileLayerIndex >> 2; terrainTile.channelIndex = tileLayerIndex & 0x3; Texture sourceTexture = TerrainPaintUtility.GetTerrainAlphaMapChecked(terrainTile.terrain, terrainTile.mapIndex); if ((sourceTexture.width != targetTextureWidth) || (sourceTexture.height != targetTextureHeight)) { Debug.LogWarning("PaintContext alphamap operations must use the same resolution for all Terrains - mismatched Terrains are ignored. (" + sourceTexture.width + " x " + sourceTexture.height + ") != (" + targetTextureWidth + " x " + targetTextureHeight + ")", terrainTile.terrain); continue; } FilterMode oldFilterMode = sourceTexture.filterMode; sourceTexture.filterMode = FilterMode.Point; copyTerrainLayerMaterial.SetVector("_LayerMask", layerMasks[terrainTile.channelIndex]); copyTerrainLayerMaterial.SetTexture("_MainTex", sourceTexture); copyTerrainLayerMaterial.SetPass(0); TerrainPaintUtility.DrawQuad(terrainTile.clippedPCPixels, terrainTile.clippedLocalPixels, sourceTexture); sourceTexture.filterMode = oldFilterMode; } GL.PopMatrix(); RenderTexture.active = oldRenderTexture; }