Hi HN. I've been learning WebGL and working on this project for about a year. I posted it previously when it worked in 2D and wanted to share it again because the 3D really makes the shade come to life. Most of the credit for the update due to migrating from Leaflet to Mapbox GL JS.
How do the calculations go so smoothly? I mean for each pixel that is potentially in the shade there can be a many 'upstream' pixels in the direction that the light is coming from that could cause it to be shady if there was something high there. Doing that calculation for each pixel seems very intensive, or is it achieved in some other way?
You're spot on. One optimization is that once you are above the highest pixel of the map, you can assume you won't hit anything else. Another is calculating if the Earth's curvature will move pixels out of your way before you hit them.
Interesting! I had never noticed the amount of shade created by the mountain in the middle of Montreal.
It almost seems wrong at first glance, the shadow it casts is huge and it covers most of the city and far beyond. But it's probably my monkey brain that doesn't notice the gradual changes and isn't aware that where I am at that moment has less light than the surrounding areas.
What is " shade " according to this map? Do you know how much sunlight (lumens?) is lost? Or is this an extrapolation of the shape of the features? It looks like the edges are quite hard when they should be softer and have different levels of opacity? Especially when the sun is very low, because according to this image, the mountain casts a shadow all the way to the town north of the river, several miles away. I'm thinking out loud. https://shademap.app/#45.581,-73.4441,10.0642z,1641473011979...
I will make sure to pay better attention next time I'm in the city around that time.
"shade" means that there is no "direct" sunlight on that spot. Some object is in the way blocking the sun. If you were to go the a spot shaded on this map at the given time (and lay your eye at ground level), you should not see the sun (+/- 2 minutes or so because the suns disk is not a point as this model approximates)
I love this map, and plan to start using it to plan timing for photography projects. I hate wandering into a valley for golden hour only to find that sun has already set!
Mondo cool. I love looking zoomed out at the terminator shadow, it's presumably what a person on the moon would see if they looked at the earth through a telescope. The time-slider is responsive on my ~7yr old laptop, even at the world scale. The resolution of the blocks you use for the DEM seem pretty high-resolution when zoomed in all the way, too, like sub-10m.
Hey. Very cool project. I have an idea. How about you add option to show buildings. That way, people can use this to detect shade on their rooftop solar panels and its stuff.
It's something I'm working towards. Right now you can see building shadows at street level zoom, but they're quite rough. Check out shadowmap.org, which is a project that does buildings well.
This is some cool work. Could you elaborate more on the algorithm used? How do you go from height map to near-real-time shadows given time of day/year? Is it all through raycasting or a faster technique?
Sorry, code is not public. My initial business model was to offer the shade layer as a drop in for any Leaflet, Mapbox, Google Map so companies like AllTrails, Strava, Gaia GPS could use it in their apps but selling's hard. Now I'm leaning a bit towards just releasing an app with offline mode.
Great link, thanks. Horizontal scrollbar tripped me out a little bit though...
Love this, what are you using as the terrain elevation data source? I don't think this is something available from Open Street Map and can't see any attribution.
Also (bug report) it seems to be a little buggy on Safari on MacOS when you zoom out, it gets quite glitchy.
I need to change the default attribution positioning because it's under the time slider but the terrain data is aggregated by Mapbox in their terrain dataset. The building data also comes from the Mapbox vector tiles but is sourced from OpenStreetMap data.
Sorry for the glitches. If you copy and paste your url here, I can see exactly the zoom/location/pitch/bearing you're looking at.
Minor detail, but it seems like while the height of buildings is somehow reflected, the `height=*` key is not. So the church tower in my town has has less shadow than the apartment building next to it.
If no timestamp is specified in the url, it defaults to your local time. As you move the time slider, the shadows will change and update the timestamp in the url so reloading the page will result in seeing the exact same location at the exact same time as before.
The shade does not change automatically, you need to move the time slider.
I echo all of the compliments on the app. It certainly has a utility function but its also very aesthetically pleasing to use for some reason. I think the smoothness and fine resolution plus the contrast of the shade brings familiar form out of nothing.
One thing i didn’t expect and can’t really explain is the emotional impact of zooming out until you can see your location and that of a loved one and watching the sun rise and set at slightly different times and different ways for each. There’s an interesting connection that it somehow creates, I’m not sure.
Anyway, in that context i kept finding myself replaying sunrises and sunsets and my rickety fingers don’t do a great job of making that a smooth process. That made me yearn for a little time widget that progresses the clock automatically at some +/- multiple of realtime.
Congrats btw, i don’t know if you feel like you accomplished your goal of learning webgl but it sure looks like you have to me.
This is really cool. Occasionally I look for land near mountains, with the aim of building a future holiday home there. It'll be really helpful to know what areas are going to still get sun in the middle of winter.
Great question. It costs nothing up to 50K map loads [1], but I did burn some money learning along the way:
I went with Mapbox and Maptiler for tiles early on. Initially I used Leaflet with raster map tiles and raster elevation tiles. Mapbox free-tier for raster tiles was 750,000 tiles per month and I exceeded that a few months in.
Next I used Leaflet with [maplibre/mapbox]-gl-leaflet plugin which allowed me to use unlimited vector map tiles from Mapbox up to 50K map loads. However, I continued to use raster elevation tiles and these soon started exceeding 750,000 tiles per month.
Finally I switched to Mapbox GL JS. This allows you 50K map loads a month and unlimited loading of elevation and vector map tiles per map load. I used Maplibre GL JS for a bit, but it's missing the 3D terrain functionality so I went with Mapbox instead.
In general, it would cost about $100 for every 3000 visitors before switching to Mapbox GL JS.
Being on the HN front page is going to blow out your budget for the month probably. Hope it doesn't cost you too much! I had issues with my own site using Street View which is even more expensive than maps (https://james.darpinian.com/satellites/) until I found out you can apply for large amounts of free Google Maps API credits for educational and non-profit use. It's a little stressful because if you exceed your credits and don't deactivate the API in time you can still end up with a large bill, and the credits have to be re-approved every year in a slow and uncertain manual process. But hey, it's free and pretty generous, and nobody else has Street View so my site can't work without it.
It's a little early to say, but someone posted it on r/InternetIsBeautiful last month and it had about 75K visitors over two days. It looks like the front page of HN will be just a fraction (20%?) of that traffic.
Reddit is truly massive, but I appreciate the HN discussions more.
You're right, I went and looked up my stats and HN doesn't seem as large as I thought. My biggest traffic days have been from Facebook. When Starlink is visible over a major city, I sometimes get a bump in traffic from people sharing the site. I was skeptical at first that adding social share buttons was important, but I think it actually has driven quite a bit of traffic. And I've gotten a ton of twitter followers which is cool. Though they don't actually care about what I tweet about, it's just nice to have a big number on my profile.
Looks great, congrats! I have worked on the same sort of project on (and mostly off) over a while, but didn't get as far as having a nice UI on the front etc. I'd started in WebGL but then moved to a back-end server using CUDA and separate front end (mostly as I wanted to learn a bit about CUDA at the time). What did you use for your source of height data? I'd used some free LiDAR data but didn't find high resolution free LiDAR data for Scotland.
EDIT: I found your blog, so can see you used e.g. https://osmbuildings.org/documentation/data/ for buildings. I'd looked at that also but found the data a little sparse and also not so accurate, but its possibly improved since, and does look good on the rendering.
I use Mapbox terrain RGB [1]. A good free alternative is Nextzen [2], but they do not generate tiles past zoom level 15 (Mapbox does it to 20) and there are some random elevation spikes that Mapbox has cleaned up.
I'm looking forward to a LIDAR elevation tile set becoming available because it can be loaded into Shademap without any modification and hopefully display shade from trees.
Interesting, thanks, I'll have a look at Mapbox terrain RGB.
Will be interesting to see the resolution of a LIDAR tile set if Mapbox are going to have one, I've found that I could sometimes find low-resolution free data (5M / 10M etc), but that higher resolution 25cm/50cm/1M etc was often commercial and very expensive, but that gives much more accurate results in city areas. I'll have a look at Nextzen also.
Are there current plans for a lidar derived surface elevation tile from mapbox?
Even the USGS 3DEP program only offers preprocessed DEMs (that is, DTMs). I can see generating that sort of thing at ~5-10m resolution on a global scale from satellite imagery / photogrammetry.
A global or even regional DSM would be quite a product.
I forget the adage used on HN, but something along the lines of "People are more willing to pay to avoid pain than to gain pleasure". A tool to prevent sun burn or skin cancer seems more promising.
The shade layer is pluggable into any mapping application if you want to prove HN wrong [1]
There's also the whole field of radio signal propagation, the cellular industry regularly uses essentially the same type of product to model shading of cell tower signals.
This is really cool! It might come in handy when house or property hunting. Here is another, similar tool I have found helpful for gardening. https://www.suncalc.org/
Absolutely! I remember looking at some houses on the south side of Donner Lake and somebody said the nickname for that area in the winter was "Siberia", because it spends a lot of time in the shade. I bought the suncalc app on the spot to double check -- and sure enough, they were right.
This tool does a much better job of telling the story. I wish it would've existed at the time!
super awesome! I have plenty of fun playing with this.
* Is there a way to deactivate daylight saving time switches / locale-specific time and just use global UTC time? Because when I drag the "day-of-the-year" slider, at the end of March the rendering jumps for the switch from CET to CEST, and jumps at the end of October for the switch from CEST to CET - at least for my locale.
* Sunsets and sunrises are the most spectacular, just as in real life. Maybe one idea is to allow for a third slider controlling the "second of a minute" ... or providing an optional "time stretching"/"slow motion" dragging behavior the closer the current position of the "minute-of-the-day" slider gets to the moment of sunset/sunrise.
I spent 3 years in Keflavik, Iceland in the 90's when I was a kid and my dad was in the Navy. I remember winter getting only a few hours of daylight where the sun would merely peek over the horizon for part of the afternoon. Looking at Iceland through this map, I was able to tell that some parts have hills to their south and during winter, they'll never leave the shadows.
Of course, go just a little more North, and during the summer, the sun never sets. It just circles the horizon.
I've used an app called PhotoPills to plan landscape photo shoots in the past. It lets you drop a pin on a map and shows you the direction of sunlight at any given time of day.
Shade Map gives me so much more fidelity to play with. The pseudo-3D view with shadow rendering helps tremendously in previsualising a photo.
Does anyone know of code for simplified triangle geometry rendering of dem data? The color data from satellite images blows up storage cost but simplified geometry might be small enough to both be useful and pretty to look at.
Unfortunately it doesn’t seem to take into account terrain outside of the viewport. Try zooming into the tip of a mountain’s shadow during a “long shadows” time of day, once you zoom in enough that the mountain itself is out of viewport suddenly the area brightens.
71 comments
[ 4.0 ms ] story [ 107 ms ] threadHow do the calculations go so smoothly? I mean for each pixel that is potentially in the shade there can be a many 'upstream' pixels in the direction that the light is coming from that could cause it to be shady if there was something high there. Doing that calculation for each pixel seems very intensive, or is it achieved in some other way?
It almost seems wrong at first glance, the shadow it casts is huge and it covers most of the city and far beyond. But it's probably my monkey brain that doesn't notice the gradual changes and isn't aware that where I am at that moment has less light than the surrounding areas.
What is " shade " according to this map? Do you know how much sunlight (lumens?) is lost? Or is this an extrapolation of the shape of the features? It looks like the edges are quite hard when they should be softer and have different levels of opacity? Especially when the sun is very low, because according to this image, the mountain casts a shadow all the way to the town north of the river, several miles away. I'm thinking out loud. https://shademap.app/#45.581,-73.4441,10.0642z,1641473011979...
I will make sure to pay better attention next time I'm in the city around that time.
That would be something great
I'm looking for a house right now, that means I can check how much light it gets before even visiting it. Thanks!
It also takes into account the Earth's curvature, so you can zoom out to planet level and it still works.
By the way, you might like https://felixpalmer.github.io/volcanoes-of-japan/
Great link, thanks. Horizontal scrollbar tripped me out a little bit though...
Also (bug report) it seems to be a little buggy on Safari on MacOS when you zoom out, it gets quite glitchy.
Sorry for the glitches. If you copy and paste your url here, I can see exactly the zoom/location/pitch/bearing you're looking at.
The shade does not change automatically, you need to move the time slider.
One thing i didn’t expect and can’t really explain is the emotional impact of zooming out until you can see your location and that of a loved one and watching the sun rise and set at slightly different times and different ways for each. There’s an interesting connection that it somehow creates, I’m not sure.
Anyway, in that context i kept finding myself replaying sunrises and sunsets and my rickety fingers don’t do a great job of making that a smooth process. That made me yearn for a little time widget that progresses the clock automatically at some +/- multiple of realtime.
Congrats btw, i don’t know if you feel like you accomplished your goal of learning webgl but it sure looks like you have to me.
https://shademap.app/#63.41876,10.43876,12.06084z,1641468451...
I went with Mapbox and Maptiler for tiles early on. Initially I used Leaflet with raster map tiles and raster elevation tiles. Mapbox free-tier for raster tiles was 750,000 tiles per month and I exceeded that a few months in.
Next I used Leaflet with [maplibre/mapbox]-gl-leaflet plugin which allowed me to use unlimited vector map tiles from Mapbox up to 50K map loads. However, I continued to use raster elevation tiles and these soon started exceeding 750,000 tiles per month.
Finally I switched to Mapbox GL JS. This allows you 50K map loads a month and unlimited loading of elevation and vector map tiles per map load. I used Maplibre GL JS for a bit, but it's missing the 3D terrain functionality so I went with Mapbox instead.
In general, it would cost about $100 for every 3000 visitors before switching to Mapbox GL JS.
[1] https://www.mapbox.com/pricing#maploads
Reddit is truly massive, but I appreciate the HN discussions more.
EDIT: I found your blog, so can see you used e.g. https://osmbuildings.org/documentation/data/ for buildings. I'd looked at that also but found the data a little sparse and also not so accurate, but its possibly improved since, and does look good on the rendering.
I'm looking forward to a LIDAR elevation tile set becoming available because it can be loaded into Shademap without any modification and hopefully display shade from trees.
[1] - https://docs.mapbox.com/help/getting-started/mapbox-data/#ma...
[2] - https://www.nextzen.org/#terrain-tiles
EDIT: For buildings I used OSM Buildings initially, but now such data is directly encoded in the vector map tiles provided by Mapbox
Even the USGS 3DEP program only offers preprocessed DEMs (that is, DTMs). I can see generating that sort of thing at ~5-10m resolution on a global scale from satellite imagery / photogrammetry.
A global or even regional DSM would be quite a product.
Bet you could even charge a penny for a feature like this.
The shade layer is pluggable into any mapping application if you want to prove HN wrong [1]
[1] https://shademap.app/about/
This tool does a much better job of telling the story. I wish it would've existed at the time!
Some time ago I made an app (Sun Locator) that has a similar feature (see here for a short demo: http://www.sunlocator.com/sunlocatorwebsite2_files/topo.gif). But your approach is definitely more elegant.
I really like the PowerPoint vibes in your intro video. Might look into doing the same.
* Is there a way to deactivate daylight saving time switches / locale-specific time and just use global UTC time? Because when I drag the "day-of-the-year" slider, at the end of March the rendering jumps for the switch from CET to CEST, and jumps at the end of October for the switch from CEST to CET - at least for my locale.
* Sunsets and sunrises are the most spectacular, just as in real life. Maybe one idea is to allow for a third slider controlling the "second of a minute" ... or providing an optional "time stretching"/"slow motion" dragging behavior the closer the current position of the "minute-of-the-day" slider gets to the moment of sunset/sunrise.
I spent 3 years in Keflavik, Iceland in the 90's when I was a kid and my dad was in the Navy. I remember winter getting only a few hours of daylight where the sun would merely peek over the horizon for part of the afternoon. Looking at Iceland through this map, I was able to tell that some parts have hills to their south and during winter, they'll never leave the shadows.
Of course, go just a little more North, and during the summer, the sun never sets. It just circles the horizon.
For example, look at New York City around dusk, and if you zoom out it's mostly yellow, but if you zoom in it's mostly black.
I've used an app called PhotoPills to plan landscape photo shoots in the past. It lets you drop a pin on a map and shows you the direction of sunlight at any given time of day.
Shade Map gives me so much more fidelity to play with. The pseudo-3D view with shadow rendering helps tremendously in previsualising a photo.
https://www.photopills.com
Still, very cool visualization!
for quite some time i wanted to include shade data in routing so i could choose most/least sunny walking route.
I am sitting in an Airbnb in Chamonix wondering where has good sunshine for skiing today?
Now I know.
I would suggest, in order to increase the visual "information" (as opposed to a blurry landscape), to:
-- give the option to exaggerate the altitudes. Currently, mountains are evident but hillsides are almost indistinct from plains.¹
-- try more relief highlighting colours, like those in DerStefan's opentopomap.org in zoom levels 1 to 8.
¹Please see the work of Anton "Antartis" Balazh, https://news.ycombinator.com/item?id=29686462 : that kind of rendering should be inspirational - I have seen little better.
It also only takes into consideration building hight but not elevation/topology on which the building sits.
I regularity use this in summer when picking a place to have lunch with friends/coworkers outdoors.
You can make sure you sit in the sun (or the shade) at that time.