Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support 3D terrain meshes #1489

Closed
Tracked by #229
trallarn opened this issue Sep 16, 2015 · 36 comments
Closed
Tracked by #229

Support 3D terrain meshes #1489

trallarn opened this issue Sep 16, 2015 · 36 comments

Comments

@trallarn
Copy link

Thank you guys for a great job so far. Do you have any plans on adding rendering support of 3D terrain meshes like google maps earth and cesiumjs are doing?

Example:
http://betaserver.icgc.cat/cesium/Girona3D.html

@dpieri
Copy link

dpieri commented Mar 11, 2016

I'm curious about the technical feasibility of this. Having true 3D ability would be huge for us and we are willing to contribute developer resources towards making it happen. Is that a pipe dream, or could this feature be implemented in a reasonable timeframe?

@mourner
Copy link
Member

mourner commented Mar 14, 2016

We are definitely going to take on the challenge of implementing 3D terrain for GL JS eventually. It wasn't a priority so far though compared to other pushes such as data-driven styling.

It's certainly a complicated task that can take several months of effort to get right, both on the client and the server side. @ansis do you have any ballpark thoughts on the effort/challenges involved here?

@chris-holcomb
Copy link

FWIW, we're looking at solutions for this right now and this would likely bring us over to Mapbox. Particularly with the Google Earth API deprecated, I suspect we're not alone in this.

Chris

@dagatsoin
Copy link

A good source of inspiration could be www.eegeo.com

Since Mapbox GL uses OpenGL it seams faisable, does not? But I see two different cases in 3D render:

  • based on aerial scan data like the exemple above
  • based on actual mapbox data driven styling.

IMO the most in the scope is the second option since render pipeline could be reused.

Terrain elevation
A solution could be to implement a runtime tessellation process based on elevation terrain (with an option on analyzing frequency to do an adaptative tessellation). My 2cts propositions, depending on the render pipeline:

  • implemented on a base shader which from are inherited all the existing vertex shaders.
  • implemented in a pass after the vertex shaders by collapsing the matrix stack, then tesselate the new mesh.

Display 3D meshes
In my opinion (without really knowing the render pipeline) it could be more trivial here. Houses, cars, characters could be classical .fbx with a texture loading as needed. Also, I don't know if Z-buffer is used in actual implementation.
However entering the 3D world could lead to infinite wish lists until MaboxGL will be like Unity3D or Unreal Engine... What should be the MapboxGL scope for 3D? Mesh animation, particules, collisions?
Based on that does it make sense to develop:

  • the next version of MGL in full 3D?
  • a plugin for Three.js, SceneKit, Unity3D, etc. ?

@mourner
Copy link
Member

mourner commented Mar 22, 2016

The first two steps will be terrain rendering and 3D extrusion (e.g. simple 3D buildings). A rough sketch for the second is in the building branch, which we're planning to revisit soon. The biggest challenge with terrain rendering is not terrain itself, but projecting map features and rendering labels with respect to terrain — we're yet to decide on how to approach this.

@lucaswoj lucaswoj changed the title 3D terrain meshes Support 3D terrain meshes Jul 28, 2016
@mike-marcacci
Copy link
Contributor

Just out of curiosity, with extruded buildings out, will this be addressed with or before z-axis offsets come to labels/etc? The two seem intimately tied, at least when defining the behavior of the z-axis in general. For example, it seems impractical to force z-offsets to be absolute (from sea level), so it may also be necessary to define offsets relative to a particular layer.

@lbud
Copy link
Contributor

lbud commented Oct 18, 2016

@mike-marcacci from a technical standpoint, z-offset properties are much easier to implement (and therefore will likely come first) because the property only affects that specified layer; projecting/wrapping the whole map based on a layer is a much more complicated beast.

@EWindfield
Copy link

Not sure if anyone notice this, as of now, you can add "some sort" of 3D terrain with the native fill-extrusion.

map.addLayer({
            "id": "terrain-data",
            "type": "fill-extrusion",
            "source": {
                type: 'vector',
                url: 'mapbox://mapbox.mapbox-terrain-v2'
            },
            "source-layer": "contour",
            'minzoom': 8,
            'paint': {
                'fill-extrusion-color': '#eee',
                'fill-extrusion-height': {
                    'type': 'identity',
                    'property': 'ele'
                },
                'fill-extrusion-opacity':.6
            }
        });

Not a smooth terrain mesh, just extrude polygon with contour data, making all terrain look like they went through "slope irrigation". Negative elevation data are forced to 0, will be cover by map layer even if you manage to cut through z-axis.

@EWindfield
Copy link

Further implementation of fill-extrusion-color to improve the visual of it

 'fill-extrusion-color': {
                    "stops": [[0,'#fff'],[8840*0.02,'#7F7F7F'], [8840*0.1,'#232323']],
                    "property": "ele",
                    "base": 1
                },

@andrewharvey
Copy link
Collaborator

andrewharvey commented Mar 19, 2017

Sketching out my thoughts on the design of this from a GL/Style Spec perspective.

Motivation

What problem are we trying to solve?
What use cases are we trying to accommodate?

Primarily in styles like satellite and satellite-streets having the terrain appear in 3D like
https://www.mapbox.com/blog/3d-terrain-threejs/ but out of the box in GL JS.

Design

Which design should we implement?

GL Source

If the Digital Elevation Model is transmitted as a raster heightmap (as opposed to a vector TIN) then the Mapbox Terrain RGB can already be used with the GL source raster-dem. raster-dem takes care of the pixel color to physical height conversion.

If people have their own DEM they could upload this as a single large 1 band GeoTIFF (potentially with non Byte type) where pixel values are heights. The same way you upload a large RGB GeoTIFF and it's converted into a raster tileset, uploading a 1 band GeoTIFF would convert it to a raster-dem tileset.

GL Layer

A new Mapbox GL elevation layer type would apply the elevation extrusion to the map, working in the same way as other layers, would have a visibilty layout property (to toggle it on/off), and elevation-exaggeration paint property.

In this way you could have multiple elevation layers in one style, so you could have a global elevation, and override it in a local area where you have better data, the same way raster works currently.

Extrusion types like the current fill-extrusion and future line-extrusion #1910 and z-offset properties #3993 would extrude from the elevation.

What are the advantages of this design?

  • Leverages the existing terrain-rgbs making it easier to implement quicker
  • Consistent with existing GL concepts (like visibility)
  • Works together with extrusion and z-offset. Can all be used either independently or in combination with each other.

What are some potential drawbacks of this design?

If the first implementation is as above it will only support a digital terrain model (ground surface). With lidar or photogrametry it's common to have a digital surface models (ground + trees + buildings etc), which has limitations if saved as a hightmap like the terrain-rgbs. eg. you can't texture the side of buildings, and you can't show 3D trees where the leafs form a ball above the surface since.

It would be nice to future proof the design to support this, if possible.

Concepts

What terminology will work best for the new concepts introduced by this design?

I feel it's important to get the terminology right, there are a lot of terms to throw around: terrain, 3d, elevation, dem, dsm, mesh, terrain-rgb, and related terms which have their meanings in GL like hillshade, extrusion and z-offset.

In the design proposal above I've used terrain to refer to the GL Source (raster-dem has since been implemented), and elevation to refer to the GL Layer. It's worth discussing if these should be the same and/or what the best choices are.

If the design is initially for the draped hightmap implementation rather than a 3D mesh, it's good to consider if the terminology will be a good choice even when the full 3D mesh implementation happens.

I've sketched this out at master...andrewharvey:andrewharvey-elevation-layer

What existing precedents support the new concepts?
Where do the concepts set new precedents?

@The-Fonz
Copy link

I'm a big fan of this functionality, would love to see it added. Cesiumjs does it pretty well but is pretty slow and sometimes unstable, and labels are terrible.

A true future-proof approach would indeed be able to use non-monotone meshes (in height direction e.g. overhangs), and to project textures onto those meshes. That gets hairy really quickly though. A more standard approach would be to use monotone height meshes, which is much quicker to implement and much easier. Extra detail can then be added using standalone meshes (buildings, trees, overhanging cliffs), which can be pruned and shown with varying levels of detail depending on zoom level.

Generating this mesh from a height map has the drawback of having a fixed resolution (e.g. 30m). Using a Triangular Irregular Mesh (TIN) solves this issue: it is still monotone in height direction but can vary its detail depending on the terrain. A drawback is that implementing some sort of Level Of Detail (LOD) that uses the previously-downloaded data is harder.

There are algorithms with reasonable running times for generating such TINs. Cesium uses the quantized mesh format to store them.

A possibility for transferring even less data would be to leave out the vertex linking information (so just specify the vertex coordinates), as a TIN is a 2D delaunay triangulation (looking at it from the top), so the triangles can be calculated relatively fast. This would also allow an easy way of implementing LOD, as you can just add some vertices and recalculate the delaunay triangulation where necessary (similar algorithm as TIN generation can be used).

Hope this helps, would be interested to discuss this some more.

@markov00
Copy link

Hi, any news about this?

@andrewharvey
Copy link
Collaborator

My vote is for supporting relatively basic 3d features in the sense of being able to show overlapping features in 3d - i.e. a bridge crossing a road, or multiple floor levels inside a building shell. i.e. very simple support for a z-height coordinate, not unlike PostGIS supports a height coordinate.

@Shongololo that feature is at #3993

@muesliq
Copy link

muesliq commented Apr 26, 2018

Terrain extrusions.. Getting closer, are we not?

@LKajan
Copy link

LKajan commented Sep 23, 2019

It's looking like they are on it.
https://blog.mapbox.com/taking-our-maps-to-the-next-dimension-dbeee37a7c4c

Can you Mapbox reveal us something more?

@jererobles
Copy link

This is very interesting – I'm wondering if it'd be possible to load terrain meshes from external sources such as ESRI or a self hosted service.

@dragons8mycat
Copy link

May I ask what the current status of terrain is? Since reading the post by Abhishek "Taking our maps to the next dimension" I note that he hasn't worked for Mapbox since February. The MARTINI approach is fantastic and opens a lot of doors....where are we with this?

I am loving Mapbox and it's capabilities, unfortunately, the lack of support for vertical terrain and coordinates is restricting my ability to use Mapbox for many projects as they become more focused around environmental and urban planning issues. If Mapbox could provide a method for consuming any of the open-source data terrain formats, 3D Tiles or using terrain mesh/rasters it would be a huge benefit.

@kylebarron
Copy link

kylebarron commented Apr 17, 2020

Slightly adjacent: the deck.gl project provides data visualizations on top of a Mapbox GL JS basemap. As of version 8.1 you can use the TerrainLayer to visualize a 3D terrain mesh on the fly using Mapbox terrain tiles and MARTINI.

The downside with this approach is that since terrain is extruded, the Mapbox GL basemap is hidden, so you can't actually combine the two without re-implementing the map rendering. I'm working on code to do that, but I agree it would be preferable to have support in Mapbox GL JS.

@karimnaaji karimnaaji mentioned this issue Dec 8, 2020
@karimnaaji
Copy link
Contributor

Support for 3d terrain added as part of the v2 release: #10160.

@fxi
Copy link

fxi commented Dec 8, 2020

OMG
image

@timautin
Copy link

timautin commented Dec 8, 2020

This looks amazing! A few questions:

  • will it be available on Android / iOS as well?
  • does it work with vector tiles (streets / outdoors / custom styles)?
  • is it possible to provide our own terrain data?

@karimnaaji
Copy link
Contributor

@timautin

will it be available on Android / iOS as well?

Yes, through the Carbon SDK.

does it work with vector tiles (streets / outdoors / custom styles)?

It works directly with all available vector styles, you can see it with a vector style in this example: https://docs.mapbox.com/mapbox-gl-js/example/free-camera-path/.

is it possible to provide our own terrain data?

If it's under in the mapbox-rgb or terrarium format, then yes.

@mike-marcacci
Copy link
Contributor

This is HUGE team - congrats on the release 🙌

@pteasima
Copy link

pteasima commented Dec 8, 2020

Newbie question, whats the Carbon SDK? 😀 I literally cant find anything with that name.

@timautin
Copy link

timautin commented Dec 8, 2020

Newbie question, whats the Carbon SDK? 😀 I literally cant find anything with that name.

Didn't find a lot of results by googling it either. Anyway I was more asking if support will be native in the Mapbox Android & iOS SDKs? I guess it will 🙂

Playing a bit with the terrain, it seems that changing the style with map.setStyle breaks it (terrain no longer loads). Anyway, congratulation guys, 3D vector tiles really look great! Adding support for 3D tiles would be amazing as well.

@karimnaaji
Copy link
Contributor

karimnaaji commented Dec 8, 2020

@timautin yes, native support is coming!

Playing a bit with the terrain, it seems that changing the style with map.setStyle breaks it

Yes, that's expected unless you directly add it as part of your style (Either through mapbox studio which 3d support is coming, or added as a root style property), otherwise you need explicitly add it to the style like so: https://github.com/mapbox/mapbox-gl-js/blob/main/test/integration/render-tests/fill-extrusion-terrain/flat-roof/style.json#L12_L31

@timautin
Copy link

timautin commented Dec 8, 2020

@timautin yes, native support is coming!

Awesome! Looks like the time to give up Google Maps SDK is finally pretty close 🙂 . Until now I've stuck with them for their (imho) unmatched satellite imagery despite the complete lack of new features / bug fixes for years, but your new 3D vector tiles are really appealing!

Yes, that's expected unless you directly add it as part of your style (Either through mapbox studio which 3d support is coming, or added as a root style property), otherwise you need explicitly add it to the style like so: https://github.com/mapbox/mapbox-gl-js/blob/main/test/integration/render-tests/fill-extrusion-terrain/flat-roof/style.json#L12_L31

I just set up a quick and dirty code without a JSON style and tried to add a toggle satellite / streets style button. But it doesn't matter, it was just for a quick test.

@c-harding
Copy link

Looks awesome! Is there any way to set the elevation of linestrings, so that they hover above the ground by a set distance?

@mourner
Copy link
Member

mourner commented Dec 8, 2020

@xsanda not currently, but we're working on this!

@timautin
Copy link

timautin commented Dec 9, 2020

Are you working on showing a globe rather than a plan as well (or planning to do it)? That would be the cherry on the cake 😃

@HarelM
Copy link

HarelM commented Dec 9, 2020

This is great, except for the license change right before delivering it... :-(

@timautin
Copy link

timautin commented Dec 9, 2020

This is great, except for the license change right before delivering it... :-(

True. By the way does the new licence implies that even if we host all the data on a private server, we'll still have to pay the same as if we were using Mapbox's servers? If so, setting up a Mapbox map on a private server (say without an internet access) would no longer be allowed, right?

@exotfboy
Copy link

Anyone knows how to generate the mapbox-rgb based Terrain tile? What kind of input data are required?

@timautin
Copy link

timautin commented Dec 10, 2020

Anyone knows how to generate the mapbox-rgb based Terrain tile? What kind of input data are required?

I successfully used something similar to this but here's another solution with rio: https://github.com/syncpoint/terrain-rgb ;)

@andrewharvey
Copy link
Collaborator

I successfully used something similar to this but here's another solution with rio: https://github.com/syncpoint/terrain-rgb ;)

Nice tutorial, it uses https://github.com/mapbox/rio-rgbify which produces an MBTiles you can upload to your Mapbox account.

I'm still praying that one day you can just upload your single band GeoTIFF to Mapbox and it'll handle converting it into Terrain RGBs automatically. 🙏

@mcmorran
Copy link

@xsanda not currently, but we're working on this!

This would be very useful. We're displaying things like overhead electrical lines and in some places they span across valleys so it would be great to see them in "mid-air" rather than clamped to ground. Similarly would be nice to have lines slightly above the ground for normal over-head lines, so the options of:

  • Clamped to ground with offset of X (relative to ground)
  • Line between two points that does not clamp to ground

Loving the feature though, looks fantastic and very easy to integrate!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests