Banner

Wednesday, 9 October 2013

Terrain building with three.js

In my last blog post, we converted a digital elevation model (DEM) to a WebGL-friendly format (i.e. easy to transfer and parse by JavaScript in the browser). In this blog post, we'll use the elevation data to build a terrain mesh with three.js.

First we need to transfer the terrain data to the browser. The elevation values are stored in a binary file as 16-bit unsigned integers. This page explains how you can send and receive binary data using JavaScript typed arrays. I've created a TerrainLoader by adapting the XHRLoader. You can also use this function:

To preserve as much detail as possible, we were scaling the floating point elevation values (0-2470) to the full range of a 16-bit unsigned integer (0-65535). You'll find the elevation value with this formula:

I'm very impressed by your work on terrain rendering in Cesium! If I should recreate this example in Cecium, what would be the best/easiest way to add heightmaps and textures? Should I install a Cecium Terrain Server or implement my own TerrainProvider interface? It would be nice if I could just pre-render a set of heightmap/texture tiles and serve them directly. Is it possible?

Hey Bjorn,Yes, you have the right idea. To get terrain data into Cesium, you can either create a tileset in a format supported by Cesium, or you can implement a custom TerrainProvider to access the terrain in whatever format it is in.

The tile format expected by CesiumTerrainProvider is documented here. Cesium also supports loading terrain from an ArcGIS Server or VR-TheWorld server out of the box, but unless you happen to have one of those already you're probably better off with the CesiumTerrainProvider.

If you'd prefer to write your own terrain provider, the best way to learn how to do that is to take a look at the source code for CesiumTerrainProvider.

The situation is similar for texturing. You can either use one of the already-supported imagery providers, or write a custom implementation of the ImageryProvider interface.

There are some folks working on modifying gdal2tiles.py to generate terrain tiles. See here.

My own goals are a bit more ambitious. I'm working on a terrain server that allows users to easily import their own terrain data and process it for use with Cesium. The terrain tiles created by this server will be triangle meshes rather than heightmaps, which allows for both faster and more accurate terrain rendering.

The format of these mesh tiles will be open and published as well, but the server itself will be a paid product. This is a way for AGI (the company I work for) to recoup some of the massive investment it has made in Cesium development.

Since my last message I have learned more about JavaScript and I'm sorry for the confusing with the Java language.

I also identified the problem for a desktop execution. When I run it, the firefox console give me this report for besseggen.html and this one when I run jotunheimen.html. So the error comes from the line request.send( null ); one time in the besseggen.html JavaScript and another time in the TerrainLoader JavaScript.

I have read here and here that the BAD_URI error was added into the XMLHttpRequest object by browser editor to improve web security.

So, perhaps you have any ideas to fix the problem or to load the data in the browser ?