How do heightmaps work?

I’m creating terrain using heightmaps. However, I have a few questions about heightmaps.

  1. How are triangles constructed from the heightmaps? Is this correct: for each pixel, a square is created with that pixel and the pixels adjacent to the right, to the bottom, and to the right-bottom, and the resulting square is split into two triangles.

  2. How many triangles are produced per pixel? Would a 4096 by 4096 image have 4 times the triangles of a 2048 by 2048? Is a 4096 by 4096 viable in terms of performance on a typical computer?

  3. A large part of my heightmap is flat terrain. However, I notice that TerrainQuad does not optimize and uses the same number of triangles for perfectly flat terrain as it does for rocky terrain. Is there an inbuilt way to optimize this, or is there a simple way for me to extend TerrainQuad and add that functionality? Or is there some other, more efficient way to represent this terrain?

  4. I’m using the alphamap/terrain splatting technique. Is there a way to adjust the “sharpness” or “blurriness” of the splatting at boundaries between textures? eg. I want one terrain, specified by one of my alphamap colors, to have minimal splat.

  5. Can multitexturing and the alphamap/splat technique be combined?
  1. I guess thats about right yeah, @Sploreg might have a few more details.
  2. Triangle count depends on the LOD level and system, its mainly a memory issue, thats why we are working on a paging system for the terrain (TerrainGrid) 4096 should be the maximum size really atm I guess.
  3. I don’t know this exactly but I think lighting distribution is also affected by the vertex count and hence a higher vertex count for nearby terrain might still make sense, optimization happens at a distance through LOD.
  4. Yeah, via the alpha value of the painted texture.
  5. Thats happening in every terrain test if I don’t misunderstand the question?
  1. each pixel corresponds to a vertex on the terrain
  2. it takes 4 pixels to produce a square. Each square has two triangles. So a 2048x2048 map would have 8388608 triangles. The LOD routines will optimize this.
  3. Use the PerspectiveLodCalculator to optimize flat areas. You will need to generate the entropy values (this can be done in the SDK’s terrain editor or in code on the TerrainQuad class). In general geo-mip-mapped terrain doesn’t optimize that much between flat and sharp areas, lod gets very difficult then. However the PerspectiveLodCalculator helps with this
  4. what normen said, use a higher resolution alpha map.
  5. yes that is what the material does. Splat textures is multi-texturing. You can use up to 12 diffuse textures and combine them with normal maps (for a combined total of 13 textures)

Alright :slight_smile: still wouldn’t a reduced vertex count on flat areas cause patchy light distribution for point lights?

Thanks for your responses, I appreciate it.

I’m a newbie to jMonkey so I’m not sure how to use the PerspectiveLodCalculator (also, there’s no Javadoc :confused: ) . I did some poking around and so far this is my idea of how to optimize flat terrain. Is this correct?

[java]terrain = new TerrainQuad(…);


TerrainLodControl tlc = new TerrainLodControl(terrain, getCamera());

PerspectiveLodCalculator plc = new PerspectiveLodCalculator(getCamera(), float pixelError <- WHAT DOES THIS MEAN);



It is easier to generate the entropy in the SDK using the button there. Just save the terrain after and it will save with it.

But yes, what you are doing will work.

The pixel error determines sort of when the LOD will change. Try some values (low values like 1 or 5) to see how it reacts.

I haven’t documented it yet, sorry.