public void Process(GTerrainChunk chunk, ref GPolygon p) { Texture2D albedo = chunk.Terrain.TerrainData.Shading.AlbedoMap; Color c0 = albedo.GetPixelBilinear(p.Uvs[0].x, p.Uvs[0].y); Color c1 = albedo.GetPixelBilinear(p.Uvs[1].x, p.Uvs[1].y); Color c2 = albedo.GetPixelBilinear(p.Uvs[2].x, p.Uvs[2].y); p.VertexColors = new List <Color32>(3); p.VertexColors.Add(c0); p.VertexColors.Add(c1); p.VertexColors.Add(c2); }
public void Process(GTerrainChunk chunk, ref GPolygon p) { Texture2D albedo = chunk.Terrain.TerrainData.Shading.AlbedoMap; Vector2 uv = (p.Uvs[0] + p.Uvs[1] + p.Uvs[2]) / 3; Color c = albedo.GetPixelBilinear(uv.x, uv.y); p.VertexColors = new List <Color32>(3); p.VertexColors.Add(c); p.VertexColors.Add(c); p.VertexColors.Add(c); }
public void Process(GTerrainChunk chunk, ref GPolygon p) { Vector2 uv0 = p.Uvs[0]; Vector2 uv1 = p.Uvs[1]; Vector2 uv2 = p.Uvs[2]; Vector2 uv01 = (uv0 + uv1) * 0.5f; Vector2 uv12 = (uv1 + uv2) * 0.5f; Vector2 uv20 = (uv2 + uv0) * 0.5f; Vector3 v0 = p.Vertices[0]; Vector3 v1 = p.Vertices[1]; Vector3 v2 = p.Vertices[2]; Vector3 v01 = (v0 + v1) * 0.5f; Vector3 v12 = (v1 + v2) * 0.5f; Vector3 v20 = (v2 + v0) * 0.5f; v01.y = chunk.Terrain.GetInterpolatedHeightMapSample(uv01).x *chunk.Terrain.TerrainData.Geometry.Height; v12.y = chunk.Terrain.GetInterpolatedHeightMapSample(uv12).x *chunk.Terrain.TerrainData.Geometry.Height; v20.y = chunk.Terrain.GetInterpolatedHeightMapSample(uv20).x *chunk.Terrain.TerrainData.Geometry.Height; p.Vertices.Clear(); p.Vertices.Add(v0); p.Vertices.Add(v01); p.Vertices.Add(v20); p.Vertices.Add(v1); p.Vertices.Add(v12); p.Vertices.Add(v01); p.Vertices.Add(v2); p.Vertices.Add(v20); p.Vertices.Add(v12); p.Vertices.Add(v01); p.Vertices.Add(v12); p.Vertices.Add(v20); p.Uvs.Clear(); p.Uvs.Add(uv0); p.Uvs.Add(uv01); p.Uvs.Add(uv20); p.Uvs.Add(uv1); p.Uvs.Add(uv12); p.Uvs.Add(uv01); p.Uvs.Add(uv2); p.Uvs.Add(uv20); p.Uvs.Add(uv12); p.Uvs.Add(uv01); p.Uvs.Add(uv12); p.Uvs.Add(uv20); p.Triangles.Clear(); p.Triangles.Add(0); p.Triangles.Add(1); p.Triangles.Add(2); p.Triangles.Add(3); p.Triangles.Add(4); p.Triangles.Add(5); p.Triangles.Add(6); p.Triangles.Add(7); p.Triangles.Add(8); p.Triangles.Add(9); p.Triangles.Add(10); p.Triangles.Add(11); }
private void CreatePolygons(GSubDivisionTree tree) { int dispSeed = Terrain.TerrainData.Geometry.DisplacementSeed; float dispStrength = Terrain.TerrainData.Geometry.DisplacementStrength; Texture2D subdivMap = Terrain.TerrainData.Geometry.Internal_SubDivisionMap; Vector2 uv0, uv1, uv2; Vector3 v0, v1, v2; float r; Rand rand; double radius; int baseResolution = Terrain.TerrainData.Geometry.MeshBaseResolution; int resolution = Terrain.TerrainData.Geometry.MeshResolution; int level; double triangleBaseLength = 1f / Terrain.TerrainData.Geometry.ChunkGridSize; IGPolygonProcessor pp = Terrain.TerrainData.Geometry.PolygonProcessor; GPolygon polygon = new GPolygon(); GeneratedUv.Clear(); GeneratedVertices.Clear(); GeneratedVertexColors.Clear(); GeneratedTriangles.Clear(); Vector3 terrainSize = new Vector3( Terrain.TerrainData.Geometry.Width, Terrain.TerrainData.Geometry.Height, Terrain.TerrainData.Geometry.Length); v0 = Vector3.zero; v1 = Vector3.zero; v2 = Vector3.zero; tree.ForEachLeaf((n) => { uv0 = n.V0; uv1 = n.V1; uv2 = n.V2; if (dispStrength > 0) { if (uv0.x != 0 && uv0.x != 1 && uv0.y != 0 && uv0.y != 1) { r = subdivMap.GetPixelBilinear(uv0.x, uv0.y).r; level = baseResolution + Mathf.Min(Mathf.FloorToInt(r / GCommon.SUB_DIV_STEP), resolution - baseResolution); rand = new Rand(dispSeed + (int)(uv0.x * 1000 + uv0.y * 1000)); radius = 0.35 * dispStrength * triangleBaseLength * TriangleEdgeLength[level]; uv0.x = Mathf.Clamp01(uv0.x + (float)((rand.NextDouble() - 0.5) * radius)); uv0.y = Mathf.Clamp01(uv0.y + (float)((rand.NextDouble() - 0.5) * radius)); } if (uv1.x != 0 && uv1.x != 1 && uv1.y != 0 && uv1.y != 1) { r = subdivMap.GetPixelBilinear(uv1.x, uv1.y).r; level = baseResolution + Mathf.Min(Mathf.FloorToInt(r / GCommon.SUB_DIV_STEP), resolution - baseResolution); rand = new Rand(dispSeed + (int)(uv1.x * 1000 + uv1.y * 1000)); radius = 0.35 * dispStrength * triangleBaseLength * TriangleEdgeLength[level]; uv1.x = Mathf.Clamp01(uv1.x + (float)((rand.NextDouble() - 0.5) * radius)); uv1.y = Mathf.Clamp01(uv1.y + (float)((rand.NextDouble() - 0.5) * radius)); } if (uv2.x != 0 && uv2.x != 1 && uv2.y != 0 && uv2.y != 1) { r = subdivMap.GetPixelBilinear(uv2.x, uv2.y).r; level = baseResolution + Mathf.Min(Mathf.FloorToInt(r / GCommon.SUB_DIV_STEP), resolution - baseResolution); rand = new Rand(dispSeed + (int)(uv2.x * 1000 + uv2.y * 1000)); radius = 0.35 * dispStrength * triangleBaseLength * TriangleEdgeLength[level]; uv2.x = Mathf.Clamp01(uv2.x + (float)((rand.NextDouble() - 0.5) * radius)); uv2.y = Mathf.Clamp01(uv2.y + (float)((rand.NextDouble() - 0.5) * radius)); } } Vector4 h0 = Terrain.GetInterpolatedHeightMapSample(uv0); Vector4 h1 = Terrain.GetInterpolatedHeightMapSample(uv1); Vector4 h2 = Terrain.GetInterpolatedHeightMapSample(uv2); if (h0.w >= 0.5f || h1.w >= 0.5f || h2.w >= 0.5f) //alpha channel for visibility { return; } if (pp != null) { polygon.Clear(); v0.Set(uv0.x * terrainSize.x, h0.x * terrainSize.y, uv0.y * terrainSize.z); v1.Set(uv1.x * terrainSize.x, h1.x * terrainSize.y, uv1.y * terrainSize.z); v2.Set(uv2.x * terrainSize.x, h2.x * terrainSize.y, uv2.y * terrainSize.z); polygon.Vertices.Add(v0); polygon.Vertices.Add(v1); polygon.Vertices.Add(v2); polygon.Uvs.Add(uv0); polygon.Uvs.Add(uv1); polygon.Uvs.Add(uv2); polygon.Triangles.Add(0); polygon.Triangles.Add(1); polygon.Triangles.Add(2); pp.Process(this, ref polygon); int currentTrisIndex = GeneratedVertices.Count; for (int i = 0; i < polygon.Triangles.Count; ++i) { GeneratedTriangles.Add(currentTrisIndex + polygon.Triangles[i]); } for (int i = 0; i < polygon.Vertices.Count; ++i) { GeneratedVertices.Add(polygon.Vertices[i]); } for (int i = 0; i < polygon.Uvs.Count; ++i) { GeneratedUv.Add(polygon.Uvs[i]); } if (polygon.VertexColors != null && polygon.VertexColors.Count > 0) { for (int i = 0; i < polygon.VertexColors.Count; ++i) { GeneratedVertexColors.Add(polygon.VertexColors[i]); } } } else { int currentTrisIndex = GeneratedVertices.Count; GeneratedTriangles.Add(currentTrisIndex + 0); GeneratedTriangles.Add(currentTrisIndex + 1); GeneratedTriangles.Add(currentTrisIndex + 2); v0.Set(uv0.x * terrainSize.x, h0.x * terrainSize.y, uv0.y * terrainSize.z); v1.Set(uv1.x * terrainSize.x, h1.x * terrainSize.y, uv1.y * terrainSize.z); v2.Set(uv2.x * terrainSize.x, h2.x * terrainSize.y, uv2.y * terrainSize.z); GeneratedVertices.Add(v0); GeneratedVertices.Add(v1); GeneratedVertices.Add(v2); GeneratedUv.Add(uv0); GeneratedUv.Add(uv1); GeneratedUv.Add(uv2); } }); //Convert vertices terrain local space to chunk local space. //This way we can place the chunk pivot/origin point at the center of its region instead of the terrain pivot. //Chunk position is set by the terrain component. //This step is very important for other task such as level streaming and occlusion culling, etc. //Special thank to Aleš Stupka for the contribution. Matrix4x4 vertexTransformMatrix = Terrain.transform.localToWorldMatrix * transform.worldToLocalMatrix; for (int i = 0; i < GeneratedVertices.Count; ++i) { GeneratedVertices[i] = vertexTransformMatrix.MultiplyPoint(GeneratedVertices[i]); } }