Grdgradient -E Option

A couple of years ago there was a long exchange about shading and illumination and I’m running into similar map shading issues.

Perhaps I’m looking at this far to simply, but I’ve been trying to experiment with grdgradient’s -E option to set a specific illumination source. It appears that the elev specification (of -Esazim/elev) doesn’t change anything when it is set to values lower than 45°.

I had hoped to view some topography under some very low-angle illumination elevations, but haven’t been able to achieve the right combination of -E and -N options to do so.

Please note that the documentation web page neglects to describe the -Em option.

Code snippet:

gmt grdgradient t.grd -Es215/10+a100 -Nt -Gtg.grd # form a gradient grid
gmt makecpt -Croma -T-2200/-2075/25 -I -D -Z > t.cpt

gmt gmtset PS_PAGE_ORIENTATION=landscape
gmt gmtset MAP_GRID_CROSS_SIZE_PRIMARY=0 MAP_GRID_PEN_PRIMARY=0.25p,grey FORMAT_FLOAT_OUT=%g

gmt psbasemap -JL-43.25/33.8/33.96/33.64/6.50313i -R-43.5/-43/33.6/34 -Bwesn -Y1.5i -K > t.ps
gmt grdimage t.grd -J -R -Ct.cpt -Itg.grd -E600 -O -K -fg >> t.ps
gmt psbasemap -J -R -Bxa0.2g0.1f0.05 -Bya0.2g0.1f0.05 -BWESN -O --FORMAT_GEO_MAP=ddd.xx >> t.ps

The resulting map appears to have an illumination elevation angle of about 45°.

Any suggestions, or corrections for the proper use of -E option are greatly appreciated!
t.grd.zip (114.4 KB)

Hello John, what a scandalous omission from the docs! I’ll file a report on GitHub right away. In the meantime please consult the usage message by calling gmt grdgradient on the command line:

  -E[s|p|m]<azim>/<elev>[+a<ambient>][+d<diffuse>][+p<specular>][+s<shine>]
[…]
     Directives s|p|m can simplify the setup:
[…]
       m: Similar to ESRI's 'hillshade' but faster. Note: azimuth and elevation
          are hardwired to 315 and 45 degrees; if you provide other values they
          will be ignored.

Unfortunately I’m not much help for your question about elevations <45°. My apologies.

Thanks, Kristof, I had figured out the command line help and then noticed that -Em wasn’t described on the web page! Thanks for forwarding a mention on the GitHub page.

The elevation portion of the -E option appears non-functional with -Es. For now, I’ve given up.

The -Es is a simpler option

Use -Es for a simpler Lambertian algorithm. Note that with this form you only have to provide azimuth and elevation.

That +a100 might be causing some error in parsing the elevation.

Evolution points now also to Shading with Blender

Thanks Joaquim, I tried it with and without the +a100 and got the same result.

The elevation portion of the -E option appears non-functional with -Es.

The above is an observation based on several attempts at low elevation requests. -Es215/10 gave the same results as -Es215/45.

Hmm. but I can clearly see a difference between 10 and 45

julia> G10 = grdgradient("t.grd", E="s215/10", N=:t);
julia> G45 = grdgradient("t.grd", E="s215/45", N=:t);
julia> viz(G10 - G45, colorbar=true)

Thanks, again, but a couple of things popped into my mind about your reply and example.

First, I’m a GMT (ab)user, not an (ab)user of the Julia version of GMT. I’m too old to make that switch and to climb the learning curve (I’ve been using GMT since the early 1990’s! Sometimes you just can’t teach an old dog a new trick!).

Second, the illumination appears to be coming from an azimuth of 35°, not 215° (maybe your azimuth is from the light source towards the grid, and not from the grid towards the light source?).

Finally, given the fact that the small crater is only half illuminated and half shaded, this must be for the case of elev=45°, correct? What does the graphic look like when 10° elevation is requested? My aim is to achieve really long shadows.

The fact that my examples are made with Julia doesn’t mean that you have to switch to reproduce them. GMT.jl is syntax wrapper but at the end is still GMT who do the work. I just don’t have patience anymore for bash scripting and I think any GMT user can recognize the commands and options used.

The example above represents the difference of the two grids created with grdgradient, not an image of the grid itself. But doing it shows that indeed there is something funny happening when the illumination comes from the 3rd and 4rd quadrants. It is known that illuminating from bellow often causes our brain to see a negative, but that it can also influence the perception of the illumination direction is a surprise to me. Or there is bug somewhere. But it’s not obvious because illuminating from 125 has the same effect.

These figs where made with grdimage and a -Iillum.grd computed with grdgradient. (-Es215/10, etc…)




Ah, forgot to answer this. None of the GMT illumination algorithms (or GDAL, or many others) cast shadows. For shadows you cannot escape new tricks, like the Blender example I linked above.

Aha! So, this is the real answer! Grdgradient cannot cast shadows. That would have been helpful to know from the beginning.

Then the description for the -E option is misleading.

To include -E[m|s|p]azim/elev[+a ambient][+d diffuse][+p specular][+s shine] options in the instructions implies that shadows can be cast.

Since this was a second inquiry (after Kristof’s) along these lines, perhaps the documentation can be adjusted to help others avoid having to go down this dead-end road.

Hmm, I may have talked too much. grdgradient was created at those 90’s that you referred above. I don’t think at that time the modern concept of shadows in computer images existed or was achievable with the computer back than. So the shadows that the man page mention referred to casting bright and shades to create the illumination effect. Now, when people talk about shadows in illumination I interpret it to be images like this

We need (time expensive) ray-tracing techniques to make images like that.

So, yes, we may change slightly the manual but not simple to make it short and informative. We are open to suggestions.

Aha! So, this is the real answer! Grdgradient cannot cast shadows.

That’s what Paul told me four years ago after asking if GMT can cast shadows:

The simple answer is no.

I agree with you John that this should be documented in a clearer way. I’ll put another issue on GitHub and work on this myself.

Opened issue #8585 over on GitHub.

Is it the lack of illumination on the images above that visually appears like shades?

Hi @mkononets, please refer to the technical reference (formerly cookbook) 14.5 Artificial Illumination how DEM illumination works in GMT.

Thanks for the link.

How illumination works is one thing. How it appears on the plot and is perceived by the reader is another thing.

That’s the trap @John_Geodesy and myself fell into. It is just a simple “how is the local surface angled to the light source” without any interaction with surrounding surfaces. And for that it yields pretty convincing results.

The way to go is either

  • raytracing if you want physically correct shadows. You can use Blender for example (see my experimentation as posted before, also @Joaquim did some nice work and posted an beginner friendly tutorial for Julia which can be easily adapted to pure GMT)

  • texture shading after Leland Brown - currently only available in the Julia Wrapper but it has potential for highlighting terrain features without dropping the “shadow” side into pitch black darkness. You don’t get correct shadows but you get nice depth and border information which can be combined with some traditional hill shading for some nice plots. Maybe this is something for @John_Geodesy as well.

See the threat over on GitHub for some more examples.

thanks, I played with texture shading. I downloaded and compiled that C code after your instructions and blended the result together with gdaldem’s hilshaded relief using gdal_calc.py. I liked it a lot and even posted some of my spaghetty bash code in one of the more recent texture shading forum threads.

With texture shading it ended up with quite a lot of manual tweaking, suspect similar workflow with the Blender approach. Not perfect for any case, e.g. not for that moon Tycho crater.

Just for good measure I used the data provided by @John_Geodesy for a texture shading experiment:

As I don’t know what John intended to show this might be missing the point but I find it quite interesting how it emphasises the diagonal structure. Illumination is from azimuth 215°.

The script in Julia:

using GMT
G = gmtread("t.grd");
lelandshade(G, detail=4.0, contrast=4.5, zfactor=25, cmap="t.cpt", azimuth=215, show=true)

The three options detail, contrast & zfactor are your gas pedals to tweak your plot.

Greatly appreciate the extra efforts shared, Kristof. Especially on a Friday! Your latest is close, but the shading in the largest crater still appears to only shade just slightly better than half of the crater.

At a solar elevation angle of 10 to 15°, one would expect most of the crater to be in shade, with just a bit of the NE rim being illuminated. Ray tracing is (I think) what I’m after.