Thomas Flynn shared a guide on how to recreate a historical map in 3D with data from NASA and set up the project on Sketchfab.
I’m Thomas Flynn, a specialist in 3D for cultural heritage and the GLAM sector (Galleries, Libraries, Archives & Museums). I’m also Cultural Heritage Lead at sketchfab.com, a role that straddles the Community and Business Teams. I’m originally from the UK but currently, live and work in New York. I go by the handle nebulousflynn online because my name is fairly commonplace.
My work at Sketchfab is very varied and includes among other things giving presentations on 3D at international conferences, delivering workshops in photogrammetry, consulting services and of course making interesting things in 3D to post on my Sketchfab profile.
I began working with 3D while I was at the British Museum, creating and publishing the museum’s first online collection of 3D scans. This was received so well by staff, audience, and the press that it got me thinking that there was some good work to be explored in this area. After that, I founded museuminabox.org with George Oates & Adrian McEwan and continued working with the British Museum alongside Dan Pett, Jennifer Wexler, Neil Wilkin and lots of other clever and awesome people. I joined Sketchfab full time at the beginning of 2017 and love it – I get to work with amazingly talented people in the team as well as cultural organizations all over the world.
I’m not trained in 3D, everything I know I’ve picked up through practical work and self-education. I’m a big believer in the power of the web: if you’re looking to learn something new, everything you need is out there online thanks to generous people are sharing their knowledge.
Making 3D from 2D Data
One niche area that I’m interested in is the 3D re-interpretation and re-use of Creative Commons and Public Domain 2D imagery. There are many amazing collections of source material for this kind of work including data releases from cultural organizations like the New York Public Library, Cleveland Museum of Art, and The Met but also governmental organizations like the US Geological Survey (USGS) and NASA. Which brings me to the subject of this article, my recent upload New York Phoenicia Quadrangle.
I had used some USGS data before (a heightmap plus a ‘Global Colorized Hillshade’ image) to create a 3D model of the planet Mars but it wasn’t until I started following Joshua Stevens, Data Visualization and Cartography lead at NASA Earth on Twitter that I learned about a couple of other sources of data from USGS and how to combine data from 1900 land surveys with the data from the Shuttle Radar Topography Mission of 2000.
How to Create a 3D Version of a Historical Map
Full disclosure: I basically followed an awesome tutorial published by Joshua on his blog, that itself was inspired by the work of graphic designer Scott Reinhard. I’m republishing the steps here with permission.
I’ll go into slightly more detail for each step in the next sections, but if you know a thing or two about 3D already and you’re interested in creating your own 3D historical map, these are the basic steps:
In place of a lengthy tutorial, here is a brief rundown of what I did to create the map above. AKA, how to draw the owl:
- Acquire a GeoTIFF of a USGS topo map that you like using topoView.
- Grab some elevation data. 30-meter SRTM data is a great start. I recommend the 30m Tile Downloader from Derek Watkins.
- (Optional) If you have multiple SRTM tiles, merge them with $ gdal_merge.py
- Ensure the elevation data is in the same projection as the topo map. (Use $ gdalinfo to read the topo map’s metadata and then $ gdalwarp to reproject the elevation data to match.)
- Clip the elevation data to the extent of the topo map.
- Double check the alignment of the data in Photoshop (or GIMP). Export an aligned elevation image in black (low elevations) and white (highest elevation). Use 16-bit color for this step! Otherwise, the elevation data will be posterized to 256 values, resulting in a stair-step appearance once rendered.
- Create a plane in Blender with the same aspect ratio as the topo map. Use the topo map for a color texture and the elevation image for a displacement map. Exaggerate the displacement liberally. Position a sun (or three) at low angles to produce long shadows.
I hope looking at these maps brought you as much joy as I found in making them. Better yet, I hope you feel encouraged to make one of your own. And if you do, please share!
Before we continue I should make it clear that in creating this model I was not interested in scientific accuracy at all and really just wanted to create something that looked as cool as Joshua and Scott’s work!
Step 1: Get your Historic Map
Step 2 – 4: Get your Elevation (heightmap) Data
Using the 30-Meter SRTM Tile Downloader that Joshua mentions is pretty straight forward, just navigate to the same area of the map that you chose your historic map from, click and download. You’ll need to register urs.earthdata.nasa.gov to access the download but it’s very quick and doesn’t require email confirmation. The preview JPG may look good to your eye but it’s only 8bit, so it doesn’t have enough data for the smooth displacement we’ll want later.
It turned out that the USGS map that I had chosen actually spanned two tiles, one above the other, from the SRTM data and while Joshua addresses this eventuality in his workflow, I had no idea what “merge them with $ gdal_merge.py” meant. What I did know is that I wanted a greyscale image to use as a heightmap, so here’s the process I used to achieve my goal:
- Unzipping the file from the SRTM Tile Downloader offered me a .hgt file. I had no idea what a .hgt file was but a quick web search found me this article on lifewire.com by Tim Fisher which put me on the right track
- I downloaded VTBuilder and imported my .hgt file Layer > Import Data > Elevation > select .hgt file
- With the layer select in the left panel, go to Elevation > Export to… > choose BMP
- Use an image editor to stitch two or more output BMPs together if you need to.
Step 5: Crop the Elevation data to your Historical Map
Great now I have a grayscale image! Now to align and scale it to your historical map,
- Open your historical map image in the editor of your choice, I used Photoshop but this process will likely work in GIMP, Krita, Affinity Photo etc.
- Import the SRTM image as a new layer over the historical map
- Scale the SRTM image so it fits as close as possible to the historical map
- You’ll probably have a much larger area of land in your SRTM file than in the historical map and will need to zoom in on the rights section. Look for recognizable landforms to help you do this.
- I reduced the opacity and changed the blend mode of the SRTM layer to ‘Multiply’ and ‘Pin Light’ to help better see where peaks and valleys lined up:
Aligning the SRTM data to the topo map while in the Multiply Blend Mode.
- You shouldn’t need to rotate the image but you might find that you need to scale the vertical and horizontal independently to get a better fit.
- N.b. Remember there are 100 years and very different capture techniques between the creation of these two data sets, they may not align 100% however you scale them!
- Once you got the scale and position correct, switch back to normal mode and crop the layer (I used a rectangular clipping mask) to the map part of the document:
- Add a solid black layer behind the SRTM data, here’s how my layers are set up in Photoshop:
- Export the resulting image – this will be our displacement map later Give the file a sensible name like ‘MAP_heightmp.jpg’:
Step 7: Creating the 3D Geometry
I used Blender and will share the steps I used here, but I guess this would also be fairly straightforward to do in most other 3D editors. I used Blender 2.7.
- Open up an empty scene in Blender.
- Import your historical map File > Import > Images as Planes
- Select the newly imported plane, scale it up if you like, then duplicate it with CTRL-C (CMD-C on Mac) > CTRL-V (CMD-V on Mac).
- Select and move the duplicated layer up a little on the Z axis G > Z > move cursor
- Hide the original map by clicking the eye next to that layer in the Outliner panel.
- Select the duplicate map and hit Alt-Z to show the map texture and Tab to switch to Edit Mode.
- Switch to the top view with Numpad-7 and use the Knife Tool to add 4 edges that run along the edge of the topo map: select the Knife Tool K, using C to constrain the cut parallel to the edges of the map document.
- Once you’ve cut along all the edges, make sure you’re in Face Select mode > select all the faces that are not the topographic map (either right-click each face or use the ) > hit X > select Delete Faces:
- Next, we need to subdivide the faces of the remaining plane. In edit mode, select the face and click Subdivide under Add: in the Tools menu (hit T if you can’t see it). Input 100 under Number of cuts in the tool options panel (bottom of Tools menu). Tab out of Edit Mode, then back into Edit Mode. Click the Subdivide button again and input a low number e.g. between 1 – 5 (or as high as your machine setup allows):
- Now we’ve got enough geometry to work with, we can use our height map to displace the geometry. Tab into Object Mode, select the topo map > add a Displacement modifier: tab in the Properties panel > Add Modifier > Displace:
- Now switch to the Texture Tab (checkered square), it should have the displace Modifier preselected:
- Click New, then Open and navigate to the heightmap, you should see something like this:
- Now flip back to the Modifier Tab and change these settings in the Displace Modifier:
- Texture Coordinates > UV
- Strength > 0.1 or similar, whatever looks good to you
- Hit Apply on the Displace Modifier when you’re happy with what you see. You might need to delete some verts if your alignment was slightly off:
- To make the model ready for online + real-time 3D on Sketchfab let’s optimize the geometry by adding a Decimate Modifier: Add Modifier > Decimate. With Collapse reduction selected change the Ratio to 0.05 or similar, whatever doesn’t warp the texture too much but reduces the facecount to something sensible like 10 thousand or so and hit Apply. Before decimation:
- Un-hide the original map and adjust its vertical position until your happy with the newly displaced version floating just above it:
- Go to File > Export > Wavefront (.obj) or your preferred format.
Step 8: (OPTIONAL) Creating an Ambient Occlusion Map
I used xNormal to bake a quick Ambient Occlusion map to help emphasize the valleys in the map. This step is optional so I won’t go into a lot of detail.
- Open xNormal
- Drop your newly exported .obj (or whatever) onto the main panel for the High Definition Mesh
- Drop your newly exported .obj (or whatever) onto the main panel for the Low Definition Mesh
- Under Baking Options, choose your desired Output File Name and Destination
- Select 4096 x 4096 or lower for Size
- Make sure only Ambient Occlusion is selected under Maps to Bake
- Hit Generate Maps
- The output file will be square. Use an image editor to make it match the topo map image dimensions.
Step 9: Upload + Scene Setup on Sketchfab
Now you have everything you need to post your model on Sketchfab!
- First compress you .obj, .mtl, colour topo map (and AO map if you made one) to a .zip file.
- Log in to Sketchfab (or create an account if you don’t have one ) then drag and drop your .zip file onto the browser window.
- Give your model a title, description, category, and tags and hit Continue.
- Once the model is finished uploading, open up its 3D settings.
- Here are the settings that I updated for my model, if I don’t mention a setting it means I left it on it’s default setting. 3D Editor tabs from left to right:
- Background > Colour #B8B8A8 (or choose your own)
- Lights > 2 Directional Lights, to taste I use one ‘Attached to Camera’ with ‘Cast Shadows’ enabled:
- Ground Shadows > Baked AO
Intensity > 1
Border Fade > 0
Height > Adjust so it’s just under the flat version of the map
Shadow Diffusion > 0.6
- Environment > Kirby Cove
Brightness > 0.5
Shadow > OFF
Just make sure that both the flat and displaced version of the map have the map image set as their Base Colour. Assign the Ambient Occlusion map from Step 8 to the Ambient Occlusion slot on the displaced map if you created one.
- Depth of Field
Foreground Blur > 0
Background Blur > 100
- Sharpness > 0.2
- Tone Mapping
Type > Filmic (I love the more retro look!)
Exposure > 1.1
Brightness > 0.2
Show of your model with some nice views and descriptions!
I set things up so that you are a teeny tiny person exploring a huge map.
- Find a nice viewing angle on your model and hit Save View to create a thumbnail and set the initial viewing position for your model:
And that’s it! I hope you found this extended tutorial interesting, be sure to check out Joshua’s and Scott’s work that I based this one. You can find me on Sketchfab and Twitter if you want to say hello
Thomas Flynn, 3D Artist
Interview conducted by Kirill Tokarev
Unkempt Flagstones with Mud and Grass Material by Stan Brown is a versatile ground material with many options to change and randomize the Grass, Mud, and Tiles. Custom Alphas can be plugged into the sbsar node, to control the shape of the stone.
Any future updates are included and will be available for download in case they are released.