Multi-Sun Hillshade
Summary
Computes a hillshade as the weighted average of ordinary hillshades from two to eight suns, each at an azimuth, an inclination and a weight you choose: the multiple-light-source strategy of the Swiss method in its most direct form. Cast shadows, if you want them, are computed separately for each sun and dimmed before the averaging, so ground shadowed from one sun but lit by another stays partly lit, a natural penumbra. Hypsometric shading is applied once, to the finished average. The tool is correct on latitude/longitude DEMs without projecting them and needs no Spatial Analyst license.
The idea
One sun lights the slopes it happens to strike at an angle and washes out the ones that face it squarely or face away. The oldest remedy is simply to use more than one sun. Imhof (2007, p. 211), reviewing the first computer hillshades, suggested making a second image with the light moved 10° or 15° to one side and combining the two photographically; Brassel (1974) let the light direction vary from cell to cell. Averaging several hillshades does the same job without any photography: each sun contributes structure where it rakes the ground, and the average keeps some of it everywhere.
The lab exercise uses two suns, one at 280° and 35° above the horizon and one at 350° and 45°, adds the two hillshades and divides by 2. Those two suns are this tool's starting defaults. The two are 70° apart in direction and 10° apart in height, and the pairing was chosen simply because it looks good on the lab's terrain; try others. The tool goes further than the lab in three ways: up to eight suns, a weight for each, and shadows.
How the average is taken
For each sun the tool computes a standard hillshade, clamped at zero for ground facing away from that sun, exactly as the Enhanced Hillshade would. The hillshades are then combined cell by cell as a weighted mean, with the weights you give summing to 100 percent, so the result stays on the scale of a single hillshade. Two suns at 50 and 50 reproduce the lab's add-and-halve; unequal weights let one sun dominate and the others fill in. A single sun at 100 percent would be the Enhanced Hillshade itself, which is why the tool starts at two.
Shadows are the interesting part. With Model cast shadows on, each sun casts its own shadows across the DEM, found with the same fast sweep the Enhanced Hillshade uses, and each sun's shadowed cells are dimmed to the Shadow brightness percentage in that sun's hillshade before the hillshades are averaged. A cell hidden from one sun but in full view of another therefore keeps part of its light, and the shadows of the finished image have soft edges that trail off where the suns disagree, much as real shadows do under a broad light. One brightness value applies to every sun. The shadow sweep needs the whole DEM in memory, once per sun.
Hypsometric shading is applied once, after the average, so its strength means the same thing it does in the other tools: at s percent the lowest cell of the DEM is darkened to (100 − s) percent of its averaged value and the highest is untouched.
The figure below shows the softening. The left half is a single sun at an azimuth of 330° and an inclination of 15°, made with the Enhanced Hillshade. The right half is this tool with five suns fanned closely around the same direction, at 320°, 325°, 330°, 335° and 340°, all 15° above the horizon and weighted equally at 20 percent each. Both have cast shadows dimmed to 20 percent. A narrow fan like this is a simple way to soften the shadows of what is, in effect, one sun.
A tour of the dialog
The tool opens from the Cartography group of the Wildlife and Forestry Tools ribbon tab or from the Cartography Tools toolset of the Jenness Enterprises toolbox.
Choose the DEM and the output name, then set the Number of sun positions, 2 to 8. The dialog expands or shrinks to match: change the number and it shows an azimuth, an inclination and a weight for exactly that many suns, as in the three-sun pane above. The first two suns start at the lab's 280/35 and 350/45; further suns step 45° clockwise at a 45° inclination, and all of them can be edited. The weights start balanced: with N suns the first N − 1 get 100/N rounded to a whole number and the last gets the remainder, so two suns get 50 and 50, three get 33, 33 and 34.
The last sun has no weight box. Its weight is always calculated automatically, as 100 minus the weights of the others, and it is reported to you in the read-only line labeled Automatically calculated weight, which updates as you change the other weights. You can set that last weight only indirectly, by setting the weights of all the other suns: in the pane above, raising the first two to 40 each would leave 20 for the third. Anything typed into the line itself is ignored. Changing the number of suns re-balances the weights.
Below the suns are the usual options: hillshade gray levels (256 by default), hypsometric shading and its strength, vertical exaggeration, and cast shadows with their brightness. The Elevation units row is offered only when the tool cannot tell what the elevation units are; when the DEM declares its vertical units, or is in geographic coordinates, Pro hides the row. Your last choices, sun positions included, are remembered with the project.
The output is a 16-bit integer raster from 0 to one less than the number of gray levels, NoData where the DEM is NoData and at its edge, with statistics, a histogram and bilinear pyramids already built and a black-to-white stretch applied on arrival (or, at 32 or fewer gray levels, unique values, one gray for each level). Without shadows the computation runs in strips and DEM size is not a concern.
With Model cast shadows on, the tool holds the whole DEM in memory at once, so the memory it needs grows with the number of cells. On most DEMs that is no concern. On a very large one the tool may need more memory than your computer has free, and then one of two things happens: Windows starts using the disk as overflow memory and the tool slows to a crawl, or the tool stops with an out-of-memory error. There is no fixed limit; it depends on how much memory your computer has free. The Enhanced Hillshade page gives rough sizes for the same shadow sweep. If a DEM is too large for the shadow option, clip it to the area you need, or run the tool without shadows, which is not limited in this way.
Environment settings
By default the output matches the input DEM exactly. Processing Extent, Snap Raster, Cell Size and Output Coordinate System are honored as finishing steps applied to the computed hillshade, so the shading is always computed from the full-resolution DEM and then clipped, resampled or reprojected. The Mask environment is not honored, and pyramids are always built with bilinear resampling.
ModelBuilder
In a model the tool takes the sun parameters like any other values, and the number of suns you set decides which of the eight sun groups are used. The weights you pass are kept as passed, but the last sun's weight is computed as 100 minus the others in a model or script just as in the dialog, so whatever you pass for it is replaced. The engine then averages with the weights normalized by their sum.
Parameters
| Label | Explanation | Data type |
|---|---|---|
| Input elevation raster (single band)Required · in_raster | The DEM. Must be single band; projected or geographic. Choose a layer from the map or browse to a dataset. | Raster Layer |
| Output hillshade rasterRequired · out_raster | The averaged hillshade (integer, 0 to one less than the number of gray levels). NoData where the DEM is NoData and at its outer edge. A name is suggested from the input. | Raster Dataset |
| Elevation unitsOptional · elev_units | Meters or Feet. Read from the DEM's vertical coordinate system when it has one; geographic DEMs are assumed to be in meters. In both cases the row is hidden in the dialog; you are asked only when the DEM does not say. | String |
| Number of sun positions (2-8)Required · n_suns | How many suns to blend. The dialog shows an azimuth, inclination and weight for each; changing the count re-balances the weights. | Long |
| Sun i: azimuth (0-360 degrees)Optional · azimuth_1 … azimuth_8 | The compass direction of sun i, clockwise from north. Suns 1 and 2 default to 280 and 350; later suns step 45 degrees clockwise. | Double |
| Sun i: inclination (0-90 degrees)Optional · altitude_1 … altitude_8 | The height of sun i above the horizon. Suns 1 and 2 default to 35 and 45; later suns to 45. | Double |
| Sun i: weight (percent)Optional · weight_1 … weight_8 | The share of sun i in the average. The weights total 100; the last visible one is computed from the others and cannot be edited. | Double |
| Automatically calculated weightOptional · last_weight_info | A read-only line showing the last sun's weight, 100 minus the others. Anything typed here is ignored. | String |
| Hillshade gray levels (Esri hillshade = 256)Required · levels | The number of gray levels; output values run from 0 to one less than this number. The default 256 matches the standard Esri hillshade; 32 or fewer adds a raster attribute table. | Long |
| Apply hypsometric shadingOptional · use_hypso | Darkens low elevations by the strength below, applied once to the averaged hillshade. Off by default. | Boolean |
| Hypsometric strength (0-100)Optional · hypso_strength | At strength s, the brightness multiplier runs from (100 − s) percent at the lowest elevation to 100 percent at the highest. The default is 50. | Long |
| Vertical exaggeration factorOptional · vert_exag | Multiplies the elevations before shading. The default is 1. | Double |
| Model cast shadows (per sun, before averaging)Optional · model_shadows | Casts shadows separately for each sun and dims each sun's shadowed cells before the average. Needs the whole DEM in memory. Off by default. | Boolean |
| Shadow brightness (percent of unshadowed value)Optional · shadow_dim | What a shadowed cell keeps of its unshadowed value in each sun's hillshade; the same value applies to every sun. The default is 20. | Double |
Python
import arcpy
arcpy.ImportToolbox(r"C:\path\to\JennessEnterprisesTools.pyt") # your install path
# Three suns; the last weight is always taken as 100 minus the others.
arcpy.jenness.MultiSunHillshade(
in_raster=r"C:\Project\Elev.gdb\DEM",
out_raster=r"C:\Project\Elev.gdb\DEM_MultiSun",
elev_units="Meters", n_suns=3,
azimuth_1=280, altitude_1=35, weight_1=40,
azimuth_2=350, altitude_2=45, weight_2=40,
azimuth_3=135, altitude_3=60, weight_3=20,
levels=256, model_shadows=True, shadow_dim=20)
Recommended citation
Credits and references
By Jeff Jenness, Jenness Enterprises (www.jennessent.com). A new tool, grown from the two-sun lab exercise. The gradient is Horn's (1981).
- Brassel, K. 1974. A model for automatic hill-shading. The American Cartographer 1:15–27. doi.org/10.1559/152304074784107818
- Horn, B. K. P. 1981. Hill shading and the reflectance map. Proceedings of the IEEE 69:14–47. doi.org/10.1109/PROC.1981.11918
- Imhof, E. 2007. Cartographic relief presentation. Esri Press, Redlands, California. (Reprint of the 1982 English edition, edited by H. J. Steward, Walter de Gruyter, Berlin; first published in German in 1965.)
- Jenness, J. Raster lab 11: Hillshades with Swiss Method effects in ArcGIS Pro; Multiple sun positions. Lab exercise video, GIS training courses, Jenness Enterprises. youtu.be/qVh5LPrv78g
Licensing information
Works at every ArcGIS Pro license level (Basic, Standard, Advanced). No extension licenses are required; the hillshades, shadows and averaging are computed internally, without Spatial Analyst.
Related tools and pages
- About Hillshades and the Swiss Method — the five tools compared.
- MDOW Hillshade — the other multiple-light tool: four fixed suns, weighted by each cell's aspect.
- Enhanced Hillshade — the single-sun tool this one averages.
- Blurred Hillshade — the softening component.
- Simple Hypsometric Shading — the hypsometric effect as an adjustable group layer.
- Projecting Rasters — this tool works on geographic DEMs directly; if you project a DEM first, use bilinear interpolation.