The idea is the following:
- server generates a heightmap, serves it as a .png image file
- client creates a mesh with BabylonJS Dynamic Terrain
Expected behaviour:
A height value (let it be X) on a small heightmap (129x129) is the same height in game as a height value (let it be Y) on a different, big heightmap (2049x2049), in case X == Y.
Observed behaviour:
- small heightmap: works well
- big heightmap: big flat piece of ground
129x129 heightmap:
Terrain generated from 129x129 heightmap:
2049x2049 heightmap:
Terrain generated from 2049x2049 heightmap:
Client code of terrain creation:
private initDynamicTerrain(scene: any, terrainDataId: string) {
this.heightmapService.getHeightmapInfo(terrainDataId).subscribe(heightmapInfo => {
const heightmapUrl = this.heightmapService.getHeightmapUrl(terrainDataId);
const heightmapOptions = {width: heightmapInfo.width, height: heightmapInfo.height, subX: heightmapInfo.width, subZ: heightmapInfo.height, onReady: this.createTerrain.bind(this), minHeight: 0, maxHeight: 10
}; const mapData = new Float32Array(heightmapInfo.width * heightmapInfo.height * 3); BABYLON.DynamicTerrain.CreateMapFromHeightMapToRef(heightmapUrl, heightmapOptions as any, mapData, scene); });
}
private createTerrain(mapData: number, mapSubX: number, mapSubZ: number): void {
const options = {terrainSub: 200,
mapData, mapSubX, mapSubZ }; const terrainMaterial = this.createTerrainMaterial(this.scene, this.heightmapService.getSplatmapUrl(this.terrainDataId)); const terrain = new BABYLON.DynamicTerrain('terrain', options, this.scene); terrain.mesh.material = terrainMaterial; terrain.subToleranceX = 16; terrain.subToleranceZ = 16; terrain.LODLimits = [4, 3, 2, 1, 1]; terrain.createUVMap(); this.scene.registerBeforeRender(() => this.setCameraHeight(this.camera, terrain));
}
Ultimately my goal is to have a mapData with fixed resolution, so it’s size depends only on the heightmap.png (that’s why width: heightmapInfo.width == subX: heightmapInfo.width)
And a fixed draw distance (the moving, morphing terrain size), regardless of the in memory mapData size.
And I think this is the right way to do it, I just can’t figure out why my terrain gets flatter when I increase the size.