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 );
context.drawImage(img,0,0);
for ( var i = 0; i < size; i ++ ) {
data[i] = 0;
}
var imgd = context.getImageData(0, 0, img.width, img.height);
var pix = imgd.data;
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?
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.
I’ve created https://playground.babylonjs.com/#JSVXVR#1 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”.
I’m using data from https://opentopography.org/ 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 https://haddons.net/webgl/threejs.html ) - 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.