Hillshade using Cesium terrain

I am trying to use Cesium’s 3D terrain features to enable a “hillshade”-like effect, computed dynamically. Basically, I want to use Cesium with no base imagery layer, but have terrain cast shadows that are overdramatized somewhat and have a consistent lighting incidence direction. This will serve (hopefully) as a low-complexity base layer for polygon overlays. I’d like it to work globally without respect to time of day.

The goal is something like this (powered by Mapbox Dynamic hillshading; I’m creating a 3D mode for this site and dataset).
So far the closest I can get is the following:

.

I can use precomputed terrain shading, potentially, but I suspect that I may be able to do better in Cesium. Are there any examples or resources available that cover my use case? I haven’t been able to find much.

Welcome to the Cesium community @davenquinn! How are you currently approaching doing this in CesiumJS? Have you seen this globe materials code example?

I think you should be able to get something as desired by turning off globe lighting (disable this line viewer.scene.globe.enableLighting = true;) and then defining a custom color ramp based on the terrain’s aspect and/or slope.

Hi Omar, the globe materials code example wasn’t quite what I was going for, as I wanted a more standard “hillshade” effect. I was able to accomplish what i wanted by layering an externally generated hillshade (generated client-side in a WebGL context from Mapbox Terrain RGB data) into Cesium as an imagery provider.

This leads to a follow-up question — in my experiments, both the hillshade and underlying terrain provider are generated client-side using Terrain RGB tiles (on-the-fly quantized mesh generation is accomplished using my prototype Cesium-Martini library). Is there a recommended way to tie a TerrainProvider and ImageryProvider together so that they are backed by the same tile cache and request queue? As it stands, I am requesting the same image tiles for both layers. They are often cached appropriately, but sometimes duplicate downloads are created when different subdomains are used to load the request.

Do you know how a standard hillshade is typically computed? If the inputs needed are the elevation, slope, and some fixed sun position, you should be able to modify the shader to get this to appear correct. I’m curious what issues you ran into doing this - this might make for a good Sandcastle example to add here.

I think the approach here would be using 3D Tiles for terrain (which is on our roadmap as mentioned here Drape imagery over 3D Tiles · Issue #7591 · CesiumGS/cesium · GitHub). Otherwise I think it may not be trivial to connect these two since their architecture has been intentionally decoupled thus far.

This library looks pretty cool! If you have the time it’d be great to share it in the General category with others here who might find it useful. I’m curious to hear more about the motivation/how you’re using it in your work.