Smooth heightmap

Hi Folks,

I’ve been working on a WebGL project using Three.js for a while now that’s not quite live yet, but was hitting performance problems in my models due to have many trees. Instancing in Three.js is a bit involved so I thought I’d take a look at Babylon JS as well before getting too far along, which seems to have a much cleaner approach to instancing.

Babylon JS also has a much cleaner approach to creating terrain from height maps, but I’m not quite getting the effect I want, so thought I’d ask here to see if anyone can help out. I’m looking for smooth terrain based on a heightmap that’s much smaller in pixel size than the terrain I’m creating. In this case, the terrain is 2816x2816 pixels but the heightmap is 36x36 pixels. I was able to do this manually in Three.js as follows:

function getHeightData(img, scale) {
  if (scale == undefined) scale=1;
  var canvas = document.createElement( 'canvas' );
  canvas.width = img.width;
  canvas.height = img.height;
  var context = canvas.getContext( '2d' );

  var size = img.width * img.height;
  var data = new Float32Array( size );


  for ( var i = 0; i < size; i ++ ) {
    data[i] = 0;

  var imgd = context.getImageData(0, 0, img.width, img.height);
  var pix =;

  var j=0;
  for (var i = 0; i<pix.length; i +=4) {
    var all = pix[i]+pix[i+1]+pix[i+2];
    data[j++] = all/(12*scale);
  return data;

And then:

  // Set height of vertices
  var vertices = plane.attributes.position.array;
  for(i = 0, j = 2; i < heightDataLength; i++, j +=3) {
    vertices[j] = heightData[i] * HEIGHT_AMPLIFIER;

Having the CreateGroundFromHeightMap function in Babylon JS is fantastic, but I’m not sure if I can use it to generate a similar result to what I’m doing with the above code. If I’m doing it manually in Babylon JS what would be the equivalent of plane.attributes.position.array?

I’ve got two pages with examples of each - and . Any help appreciated.

Thanks, Tom

1 Like

So first welcome!!

Here is the code used by the API:

To get your plane positions, you can just call:

var positions = mesh.getVertexBuffer(BABYLON.VertexBuffer.PositionKind)
1 Like

Ah, thanks, so it seems I’d misinterpreted “subdivisions” as the total number of subdivisions for the mesh rather than the subdivisions in the x and z directions, so I was just creating way too many. I’m still not quite getting things as smooth as I’d like in some particular parts of the mesh, but I’ll dig in a bit deeper and see what more I can find.

Thanks for the pointers so far.

1 Like

Feel free to create a repro in the Playground if you want to chat more about other options :slight_smile:

I’ve created showing what I mean. There are some “ripples” towards the top of the scene on the surface of the track which I’d really like to be smoothed out.

I’ve also tried setting this so that it’s pointing directly at the “ripples” but can’t quite seem to get it working. Let me know if it’s not clear which bits are the “ripples”.

1 Like

Well not sure to see them but it seems that you need more subdivisions right?

I don’t think so - is with twice as many subdivisions, and the ripples are even more pronounced.

1 Like

maybe ‘worldmonger’ might help you out…
Maybe the image that you use as the heightmap doesn’t correcly update the ground.
You could perhaps tweak the parameter colorFilter in order to give more weight to the wanted color

1 Like

I’m using data from to get the heightmaps, as this is for an application that’s using real locations, so I don’t really have control over the heightmap. For some reason three.js is producing a smoother heightmap (I’ve now added a wireframe to ) - I’ll try digging into the details of what values are being returned from the height map functions in each case and see what I can find.

1 Like

Hey, I am having a similar issue. Did you figure it out?