Monday 14 October 2013

Textural terrains with three.js

This is the third blog post in my "terrain mapping with three.js" series. With the terrain geometry in place, it's time to create a texture and drape it over the terrain.

In the first blog post in this series, we created a digital elevation model (DEM) for Jotunheimen. We can use this DEM to create color relief and hillshade that will enhance the view of our terrain (this blog post explains the details).

gdaldem color-relief jotunheimen.tif color-relief.txt jotunheimen-relief.tif



Creating nice-looking hillshades got easier with GDAL 1.10. By adding the "combined" option to gdaldem you get a slope-enhanced shaded relief:

gdaldem hillshade -combined jotunheimen.tif jotunheimen-hillshade.tif


I'm combining color relief and hillshade with Mapnik, and at the same time adding colors for lakes, glaciers and trees using open data from the Norwegian Mapping Authority (this blog post explains the details).

nik2img.py jotunheimen-texture.xml jotunheimen-texture.png --projected-extent 432000 6790000 492000 6850000 -d 4096 4096

The texture styles are available on GitHub. The final texture (converted to JPG to save some bandwith) looks like this:


Adding the texture to the terrain mesh is dead easy: Use THREE.ImageUtils.loadTexture to load the texture and add it to the map property of the material:

var material = new THREE.MeshPhongMaterial({
  map: THREE.ImageUtils.loadTexture('../assets/jotunheimen-texture.jpg')
});

We also need to add some light to see the texture:

scene.add(new THREE.AmbientLight(0xeeeeee));

That's all! Our 3D terrain now looks like this (click to see in WebGL):

View of Jotunheimen from the south.

View of Jotunheimen from the north.  Galdhøpiggen, the highest mountain in Norway (2469 m), is among the glaiers in the middle. 

The code is available on Github. In the next blog post, we'll create a virtual reality version of our terrain.

6 comments:

Unknown said...

WOw, it is really fascinating what is possible with some lines of gdal-code! I will try that out for my area(s) as well.

keep posting!

brett said...

This is awesome thanks! I just got to your second post and I'm trying to load the material on top of the mesh. I haven't changed anything in your original github code, but my terrain is showing up black. Any ideas?

Spencer Haley said...

@Brett - I ran into the exact same situation this evening, and the game changer was using a JPG in lieu of a TIF. Your mileage may vary, but that fixed up my black terrain in no time at all.

Bjørn, thank you again for such an excellent guide.

brett said...

@Spencer - Thanks for the reply. However, i discovered an inherent problem in the code that would never allow it to happen unless you use .jpg. If you wish to use something different you can apply:

geometry.computeCentroids();
geometry.computeFaceNormals();
geometry.computeVertexNormals();

Unknown said...

Hi, thanks for your great work. I was trying to use your method to accomplish a similar task. But the problem is that the color relief image and the Hillshade image is way too large. How do you deal with this problem?? Thanks a lot.

Unknown said...

Hii Bjorn,Your work is really amazing & fasinating,thanks a lot.But i am wondering if on the top of above terrain can we put mountain or lake or any street names so that it looks like a map completely.(like google maps in 3d).Is it possible??
Thanks in advance