- Home /

# Separating Procedurally Generated Mesh, Based On Triangle Height

Hello! I have been working on creating a procedurally generated world. The *image attached* shows a simplified representation of the terrain. I have spent so many hours trying to figure this out, and I have been unsuccessful; hence why I am asking anyone for help.

*- Picture showing a basic terrain generation* *- Picture showing any triangles from 'x' height or above to be moved onto a separate mesh*

My **problem**, is that I want to create biomes, and the only way I can possibly think of doing this, is by splitting the terrain into a sub-mesh to give it a different color.

**So my question is**: *how can I divide a mesh into two* **separate** *meshes, by the* **y** *position of the triangles?*

If you have any other questions please let me know!

**Answer** by sSuite
·
Dec 04, 2018 at 05:52 AM

Tricky one!

So, broadly speaking, you'll want to loop through all of the triangles and build the information for two new meshes as you go along. You'll need at least a collection each for triangles and vertices. You'll probably want normals as well, but you could recalculate those automatically if you wanted to. For now, let's just pretend you only want vertices and triangles.

I like to store these as lists, since I'm lazy. Let's start with:

```
List<int> upper_mesh_triangles = new List<int>();
List<int> lower_mesh_triangles = new List<int>();
```

We'll get to the vertices later. That's going to be a little harder. So, now you want to loop through all of your triangles, figure out which ones you want in each mesh, and add them to the lists. Remember that triangles come in groups of 3, so we're stepping through this array 3 at a time:

```
for (int i = 0; i < old_triangles.Length; i+=3) {
if (old_vertices[old_triangles[i+0]].y > threshold ||
old_vertices[old_triangles[i+1]].y > threshold ||
old_vertices[old_triangles[i+2]].y > threshold) {
upper_mesh_triangles.Add(old_triangles[i+0]);
upper_mesh_triangles.Add(old_triangles[i+1]);
upper_mesh_triangles.Add(old_triangles[i+2]);
}
else {
lower_mesh_triangles.Add(old_triangles[i+0]);
lower_mesh_triangles.Add(old_triangles[i+1]);
lower_mesh_triangles.Add(old_triangles[i+2]);
}
}
```

Here's the funky part: Now we need to take our lists of triangles and build lists of vertices -- while ALSO modifying the list of triangles because the indices are now wrong, AND making sure we don't duplicate any vertices that we don't want to. I'll just show you what this would look like for the upper mesh, since the lower mesh will basically be exactly the same.

```
List<Vector3> upper_mesh_vertices = new List<Vector3>();
Dictionary<int,int> upper_mesh_triangle_translations = new Dictionary<int,int>();
for (int i = 0; i < upper_mesh_triangles.Count; i+=3) {
if (!upper_mesh_triangle_translations.ContainsKey(upper_mesh_triangles[i+0])) {
upper_mesh_triangle_translations[upper_mesh_triangles[i+0]] = upper_mesh_vertices.Count;
upper_mesh_vertices.Add(old_vertices[upper_mesh_triangles[i+0]]);
}
upper_mesh_triangles[i+0] = upper_mesh_triangle_translations[upper_mesh_triangles[i+0]];
if (!upper_mesh_triangle_translations.ContainsKey(upper_mesh_triangles[i+1])) {
upper_mesh_triangle_translations[upper_mesh_triangles[i+1]] = upper_mesh_vertices.Count;
upper_mesh_vertices.Add(old_vertices[upper_mesh_triangles[i+1]]);
}
upper_mesh_triangles[i+1] = upper_mesh_triangle_translations[upper_mesh_triangles[i+1]];
if (!upper_mesh_triangle_translations.ContainsKey(upper_mesh_triangles[i+2])) {
upper_mesh_triangle_translations[upper_mesh_triangles[i+2]] = upper_mesh_vertices.Count;
upper_mesh_vertices.Add(old_vertices[upper_mesh_triangles[i+2]]);
}
upper_mesh_triangles[i+2] = upper_mesh_triangle_translations[upper_mesh_triangles[i+2]];
}
```

And there you have it! A list of triangles and vertices for each of your new meshes. You should be able to turn these into actual meshes relatively easily.

Let me know if you have any questions. Hope this helps!

Thank you so much for this detailed explanation. Not only did you help me understand it, but your answer was also extremely detailed as well. Thanks a lot!

Hope this answer eventually helps any others down the track who have similar issues!

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.

### Follow this Question

### Related Questions

Splitting Procedurally Generated Mesh, Based On Height 0 Answers

3D Object Scrolling Panel 0 Answers

What keyword string should I add to enable/disable when changing shader properties ? 1 Answer

How to make mesh ripples fade c# 1 Answer

Outline Shader not working correctly on blender models 0 Answers