public static void UpdateCombinerCache(TerrainCombiner combiner) { TerrainData terrainData = combiner.GetComponent <Terrain>().terrainData; // Update target materials from sources List <SplatPrototype> targetSplatList = new List <SplatPrototype>(); for (int i = 0; i < combiner.Instances.Length; i++) { TerrainCombinerInstance sourceData = combiner.Instances[i]; if (sourceData.source == null) { continue; } Terrain sourceTerrain = sourceData.source.GetComponent <Terrain>(); foreach (SplatPrototype splat in sourceTerrain.terrainData.splatPrototypes) { if (splat.texture == null) { continue; } // If splay use alpha material it should not be added to target if (sourceData.source.alphaMaterial != null && splat.texture.ToString() == sourceData.source.alphaMaterial.ToString()) { continue; } int index = FindMaterialIndex(targetSplatList, splat.texture); if (index == -1) { targetSplatList.Add(splat); } } } terrainData.splatPrototypes = targetSplatList.ToArray(); // TODO: release ?? combiner.MaterialCache.RenderTextures.Clear(); int size = terrainData.alphamapResolution; int targetLayerCount = terrainData.alphamapLayers; for (int i = 0; i < targetLayerCount; i++) { RenderTexture renderTexture = TCGraphicsHelper.CreateRenderTarget(size); combiner.MaterialCache.RenderTextures.Add(renderTexture); } combiner.MaterialCache.Texture = TCGraphicsHelper.CreateTexture(size); combiner.MaterialCache.ResultData = new float[size, size, terrainData.alphamapLayers]; }
public static void StartCombine(TerrainCombiner terrainCombiner, float groundLevelFraction) { Terrain targetTerrain = terrainCombiner.GetComponent <Terrain>(); // TerrainData targetTerrainData = targetTerrain.terrainData; RenderTexture prevRenderTarget = RenderTexture.active; Graphics.SetRenderTarget(terrainCombiner.HeightmapCache.RenderTarget); GL.Clear(false, true, new Color(groundLevelFraction, 0, 0, 1)); { for (int i = 0; i < terrainCombiner.Instances.Length; i++) { TerrainCombinerInstance terrainInstance = terrainCombiner.Instances[i]; if (terrainInstance.source == null) { continue; } Terrain sourceTerrain = terrainInstance.source.GetComponent <Terrain>(); if (sourceTerrain == null) { continue; } // TerrainData sourceTerrainData = sourceTerrain.terrainData; // Texture2D sourceTexture = heightmapDataCache.sourceTextures[i]; Texture2D sourceTexture = terrainInstance.source.CachedHeightmapTexture; Vector2 position = terrainInstance.position; // Material material = new Material(Shader.Find("Unlit/Texture")); Material material = new Material(Shader.Find("PockerHammer/TCHeightmapShader")); material.SetFloat("_HeighOffset", -terrainInstance.source.GroundLevelFraction); float heightScale = terrainInstance.WorldSize.y / terrainCombiner.WorldSize.y; material.SetFloat("_HeightScale", heightScale); Vector2 scale = TerrainCombiner.CalcChildTerrainPlaneScale(targetTerrain.terrainData.size, sourceTerrain.terrainData.size, terrainInstance.size); TCGraphicsHelper.DrawTexture(sourceTexture, material, position, terrainInstance.rotation, scale); } } Graphics.SetRenderTarget(prevRenderTarget); }
private TerrainCombinerInstance FindClosestInstance(Vector3 worldPos) { TerrainCombinerInstance closestInstance = null; float closestDist = float.MaxValue; foreach (var instance in terrainCombiner.Instances) { Vector3 localPos = instance.transform.InverseTransformPoint(worldPos); Vector3 size = instance.WorldSize; Rect rect = new Rect(-size.x * 0.5f, -size.z * 0.5f, size.x, size.x); if (rect.Contains(new Vector2(localPos.x, localPos.z))) { float dist = Vector2.Distance(new Vector2(worldPos.x, worldPos.z), new Vector2(instance.transform.position.x, instance.transform.position.z)); if (dist < closestDist) { closestDist = dist; closestInstance = instance; } } } return(closestInstance); }
public static void StartCombine(TerrainCombiner terrainCombiner) { Terrain targetTerrain = terrainCombiner.GetComponent <Terrain>(); TerrainData targetTerrainData = targetTerrain.terrainData; RenderTexture prevRenderTarget = RenderTexture.active; Texture2D blackTexture = CreateTexture(Color.black); // TODO: cache? // Iterate through alphamaps for (int nLayer = 0; nLayer < targetTerrainData.alphamapLayers; nLayer++) { Graphics.SetRenderTarget(terrainCombiner.MaterialCache.RenderTextures[nLayer]); GL.Clear(false, true, Color.black); SplatPrototype targetSplat = targetTerrainData.splatPrototypes[nLayer]; // Apply all sources for (int i = 0; i < terrainCombiner.Instances.Length; i++) { TerrainCombinerInstance sourceData = terrainCombiner.Instances[i]; if (sourceData.source == null) { continue; } Terrain sourceTerrain = sourceData.source.GetComponent <Terrain>(); TerrainData sourceTerrainData = sourceTerrain.terrainData; // // TODO: map splat prototypes to find correct id // int nTexture = nLayer/4; // int nColor = nLayer % 4; // // Texture2D[] textures = sourceTerrainData.alphamapTextures; // // if(textures != null && textures.Length > nTexture) { // // Vector2 position = sourceData.position; // Texture2D sourceTexture = textures[nTexture]; // // Material material = new Material(Shader.Find("PockerHammer/TCMaterialShader")); // Matrix4x4 m = Matrix4x4.zero; // // switch(nColor) { // case 0: // m.m00 = 1.0f; // break; // case 1: // m.m11 = 1.0f; // break; // case 2: // m.m22 = 1.0f; // break; // case 3: // m.m33 = 1.0f; // break; // } // // material.SetMatrix ("_ColorMapping", m); // // TCGraphicsHelper.DrawTexture(sourceTexture, material, position, sourceData.rotation, sourceData.scale); // // } // if(nSourceLayer < sourceData.source.CachedMaterialTextures.Count) { int nSourceLayer = FindMaterialIndex(sourceTerrainData, targetSplat.texture); Texture2D sourceTexture = nSourceLayer != -1 ?sourceData.source.CachedMaterialTextures[nSourceLayer] : blackTexture; Texture2D alphaTexture = blackTexture; if (sourceData.source.alphaMaterial != null) { int nSourceAlphaLayer = FindMaterialIndex(sourceTerrainData, sourceData.source.alphaMaterial); alphaTexture = sourceData.source.CachedMaterialTextures[nSourceAlphaLayer]; } Material material = new Material(Shader.Find("PockerHammer/TCMaterialShader")); material.SetTexture("_Texture2", alphaTexture); Vector2 scale = TerrainCombiner.CalcChildTerrainPlaneScale(targetTerrain.terrainData.size, sourceTerrain.terrainData.size, sourceData.size); TCGraphicsHelper.DrawTexture(sourceTexture, material, sourceData.position, sourceData.rotation, scale); } } Graphics.SetRenderTarget(prevRenderTarget); }