Pyramid Shader: Introduction

Why is it called Pyramid Shader?

The name comes from its original function: to compute terrain shading based on a weighted Laplacian pyramid. The concept was based off part of a lecture by my adviser and cartography professor, Bernhard Jenny, in which he showed us this image, which is also available at shadedreliefarchive.com:

Part of the manual relief's clarity can be achieved digitally, by splitting a terrain model into separate scales of detail, and giving less weight to the fine scales than the coarse ones. Laplacian pyramids are great at this because they have a very useful property: add each level (or layer) of the pyramid together, and the original image is the result, yet each level represents a particular scale of detail.

To build a Laplacian pyramid, first build a Gaussian pyramid by creating a stack of layers, each with a Gaussian blur radius twice as large as the one previous. Then, for each level of the Gaussian pyramid, subtract the level above to make the corresponding level of the Laplacian pyramid. The last Gaussian level is also considered the last level of the Laplacian pyramid. Note that adding all of the Laplacian pyramid levels together is comparable to undoing each subtraction step (All levels greater than G0 cancel with themselves), so the result equals the original DEM. Because each level of the Laplacian pyramid contains a specific scale of detail, and the sum of all the levels is the original raster, Pyramid Shader can selectively control how prevalent each scale is by weighting the lower levels less than the higher levels when adding them all back together.

To build a Laplacian pyramid, first build a Gaussian pyramid by creating a stack of layers, each with a Gaussian blur radius twice as large as the one previous. Then, for each level of the Gaussian pyramid, subtract the level above to make the corresponding level of the Laplacian pyramid. The last Gaussian level is also considered the last level of the Laplacian pyramid. Note that adding all of the Laplacian pyramid levels together is comparable to undoing each subtraction step (All levels greater than G0 cancel with themselves), so the result equals the original DEM. Because each level of the Laplacian pyramid contains a specific scale of detail, and the sum of all the levels is the original raster, Pyramid Shader can selectively control how prevalent each scale is by weighting the lower levels less than the higher levels when adding them all back together.

Pyramid Shader started out as my term project for Bernie's Geovisualization Algorithms class, but we continued development afterwards, and as I shifted to working on my thesis, he took the reins of the project while I mostly tested the features he added or investigated new uses for them. We tweaked the interface to be more user-friendly, and then he bundled in the products of the other students' research as well, plus a few other innovations from other cartography researchers. It is now a very useful terrain shading tool.

So, it's time to write a user manual.

Installation

You can download Pyramid Shader as a .jar, .exe, or .app here. Either install the OS-specific versions, or simply run the jar file (you'll need Java 8 installed for any of these options). Run your executable of choice to start the software.

Using Pyramid Shader

Pyramid Shader will start out by asking you for an ASCII grid file. This is basically just a text file that has a bit of header information and then a long table of elevation values. Since you'll most likely be starting with a GeoTiff, you'll need to convert it. There are several options here: ArcGIS, Global Mapper, and Geographic Imager are the major proprietary programs that can do this, but you can also do it with Landserf, QGIS, GDAL, or SAGA, all four of which are free. 

If you want to get right to using Pyramid Shader, you can use this grid, which I'll be using for the examples. It's the same region as the image above, a combination of elevation and bathymetry data (courtesy of GEBCO). Unzip the archive into a directory of your choice.

Once you select the grid (the file with the .asc extension), Pyramid Shader will load it and then generate the pyramid stack. When using larger grids, you may encounter an out-of-memory error at this point, depending on how much RAM you have and how big the grid is. I find that if you have 12 GB of RAM or less, it is best to keep the longest dimension of your grid below 5000 pixels (or cells, rows, columns, or whatever your preferred terminology). If you encounter the memory error, you'll need to downsample your grid and try again. A smaller grid is generally desirable anyway, as certain useful algorithms, most notably the local hypsometric color, take much, much longer on larger grids.

Pyramid Shader's interface after loading the provided grid. As you can see, parts of this terrain are so noisy they blend together into a rough gray smudge. Let's do something about that.

Pyramid Shader's interface after loading the provided grid. As you can see, parts of this terrain are so noisy they blend together into a rough gray smudge. Let's do something about that.

The palette on the right is the Settings Palette. It's split up into four tabs:

Visualization: Controls the algrorithm(s) used to shade the terrain. These include standard relief shading, hypsometric tints, local hypsometric colors, Jane Darbyshire's bivariate shading, slope, aspect, curvature, and continuous tone.

Generalization: Controls the Laplacian pyramid settings. This was the original function of Pyramid Shader. The Landforms Removal setting determines the number of pyramid levels to generate, and the Details Removal slider controls the weighting of each level.

Illumination: Allows you to control the lighting direction and ambient light for the terrain. Azimuth controls the compass direction of the sun, Zenith controls its angle above the horizon, and Ambient Light is illumination independent of direction. If you have Photoshop, you can apply ambient light there with a bit more control.

Contours: This tab implements Jim Eynard's illuminated contouring algorithm. You can use this tab to control contour spacing, width, height, illumination, generalization, and color. There's a lot here so I'll save it for a later chapter.

The menus are another important part of the interface with some easy-to-miss features:

File Menu: In addition to loading grids, this is where you export shaded relief and contour maps. You can also re-save your grid after generalizing, downsampling, or filtering it using local hypsometric colors. Finally, you can also export normal maps here, which are a very useful tool that I am covering in another set of tutorials.

Edit Menu: Most people would consider the functions here to be very basic raster processing from GIS software; you can multiply your terrain values by a scaling factor, add or subtract an offset value, or specify a value to act as null or noData. If the default terrain exaggeration doesn't quite go as far as you like, you can scale the grid values to make up the difference, although keep in mind that each use of this function is cumulative and persistent.

View Menu: Tools for zooming or resetting the view to fit the window.

Window Menu: Hide or show the settings panel and display parameters for your grid. The "Info" option is similar to the "About this program" item in many software packages.

I've developed a standard workflow that brings digital reliefs closer to the look and feel of hand-drawn reliefs like the map of the Andes shown above. Over the course of these blog posts I will cover these methods and also introduce some of the other features of Pyramid Shader. For now, we'll start with the core algorithm; generalization Laplacian pyramids, and relief shading.

Exercise I

Try to reset any settings you may have tweaked (or simply reload the grid or program). For this terrain, I found it best to max out the vertical exaggeration and also to scale the heights by a factor of 3. Next, go to the Generalization tab.

To begin, try 5 levels and 50%, and experiment with raising and lowering each. The lowest setting for Details Removal weights all levels the same (so no generalization at all), and the highest setting makes only the coarsest levels visible. If you turn the Details Removal slider all the way up, you can see how Landforms Removal works; as you increase Landforms Removal, the image becomes blurry because we are generating higher levels of Laplacian pyramids, and with Details Removal set to max, only the highest levels are easily visible.

Try setting the options in the generalization tab to 4 levels at 45%.

The Andes map after pyramid shading (left), compared to the original (right). It is now easier to make out the major mountain ranges that were in the noisy areas. Note that this is not the same as simply blurring the terrain; the fine details are still there, but their visual prominence has been reduced relative to the large features. 

Higher resolution maps often need higher settings on either slider, depending on scale. You can compare the generalized result to the original by briefly lowering either setting to the minimum. The ideal settings should make larger features suddenly pop out of the map where they were previously obscured by lots of small side valleys/ridges (see the above image, made with 4 pyramid levels and details removal of 45%).

Once you're happy with the generalization settings and illumination (the convention in cartography is to use the default setting of NW at 45°), you can head over to the Visualization tab to customize the relief shading. For this we'll use the Exposition Color option from the dropdown menu (most of the others are completely different algorithms that we'll cover in future tutorials).

Exposition Color is just like Gray Shading except you can customize the color gradient. The gradient editor here is similar to the one in Photoshop; click on the gradient to add a color stop, or drag an existing stop off the gradient to remove it. Click an existing stop to select it, at which point you can change the color. You can also drag a stop along the gradient to adjust its position. The left end of the gradient corresponds to the darkest value under the default color scheme, and the right end corresponds to the brightest.

There are a number of presets available as well; the one corresponding to most analytical relief shaders, such as those in ArcGIS, is Hard Gray. This shades everything pointed more than 90° away from the light source as black. If we are only considering direct lighting, this is more realistic than the default shading. However this causes all the information on the shadowed sides to be lost. It also ignores ambient lighting, which will be present on any planet with an atmosphere (alpine valleys do not turn black as soon as the sun drops below the ridgeline, unless one is on the moon). Our default shading thus moves the cutoff to 180° so that there is always some information available even in the shadows.

Comparison of selected relief shading presets in Exposition Color. Default or Black and White (at left) maps a black to white gradient to surfaces facing from 180° to 0° away from the light source. Hard gray (at center) is similar, except everything facing more than 90° away from the light source is shaded black. Natural Light (at right) uses a more complex gradient, with bluish shadows and a slight yellow tone to the highlights.

Taking the ambient vs. direct lighting concept one step further is the Natural Light preset. This gives a slight yellow tint to the highlights and a slight bluish tint to the shadows. On Earth, ambient light is provided by the sky, which scatters blue light from the sun. This scattering shifts the color of direct light to warmer colors and indirect light to cooler colors, as can be seen in this image

If you use Photoshop in your cartography pipeline, I recommend exporting your relief using the default black to white shading and then using Gradient Map adjustment layers in Photoshop to finalize your colors. This will allow you to non-destructively edit your colors and see how they blend with your other layers as you're compositing.

Export the relief using File>Save Image, and you've got your relief map. We'll cover additional methods for recapturing the clarity of manual reliefs in later posts.