Create Meshes from Height Maps using Blender
Here's an example mesh created by the technique I'll outline in this post, from a heightmap using Blender.
Height maps are textures which represent the height of geometry as a black and white image - black means "low" and white means "high".
Part of a pebble floor surface heightmap © Epic Games
These heightmaps can be used in conjunction with a shading technique called tessellation, which subdivides geometry on the graphics card to increase the triangle density. A height map can then be applied to the surface to raise and lower the vertices of the generated triangles, and the result is a detailed surface.
There are a few drawbacks with GPU-based tessellation however:
- It can be quite performance-intensive if a very high-triangle density is desired
- The new geometry can't be made available on the CPU to allow accurate physics collision and occlusion
- Some mobile platforms don't support tessellation
In some cases it makes sense to create tessellated meshes offline, instead of tessellating on the GPU. In this post I'll outline my workflow to create the below mesh with Blender.
Here's the workflow I used to create this mesh with Blender:
- Create a Plane
- Increase the Triangle Count
- Add the Displacement Modifier
- Add the Decimate Modifier
Create a Plane
Increase the Triangle Count
This can be done by either subdividing the mesh in Edit Mode, or using a modifier. I chose to subdivide the mesh destructively since it preserves the UVs better, though you may want to play around (see my note at the end of the post about why I didn't use the multi-res modifier and bake a normal map from the low-poly mesh).
Add the Displacement Modifier
In Object Mode, add the modifier from the Modifiers panel, then Add Modifier -> Displace under Deform. Change the Direction to "Z" but leave the other options as-is (we'll change them later).
Hit "New", which will create a texture to link. Then head over to the Textures panel, and hit Open, selecting the local height map texture file you want to use.
You will then see the height map applied to the mesh. You'll want to play with the Strength and Midlevel options on the displace modifier.
Add the Decimate Modifier
Now we're nearly finished, however for real-time use this mesh has too many triangles. The Decimate modifier can help with that - there are 3 different algorithms you can use to cut down the unecessary geometry.
At this point you may want to shade your mesh as flat/smooth, depending on what the texure looks like. In this case it would make sense as smooth.
This workflow is great for quickly creating meshes that look far better than planes with normal maps applied, however the meshes that you get from this workflow aren't perfect.
One way to improve would be to bake a normal map from the higher res mesh to accompany the low-poly mesh, and properly mark the sharp edges in the mesh. I am not confident in that area of 3D modelling though, but when I do get better there I'll write a follow-up.
🏷️ mesh modifier map triangle blender texture geometry workflow surface tessellation decimate outline heightmap black white