[RFC] Fitting data on terrain surface
Target Use Case
As of 8.8, deck.gl always treats the z component of a geospatial position as altitude. This may not be ideal in some circumstances, for example:
- When a layer containing 2D data is rendered alongside the
TerrainLayer, the objects are occluded by the terrain - When using deck.gl layers in an overlay on top of a 3D base map (Mapbox/Maplibre/Google Maps), the objects are not aligned with the terrain
- When using deck.gl layers interleaved with a 3D base map (Mapbox/Maplibre/Google Maps), the objects are occluded by the terrain
Mapbox/Maplibre support fitting user data to the surface of the terrain, namely:
- Point (circle, icon, text): treat z as relative to the terrain surface, instead of sea level ("shifting")
- Geometry (polygon, path, bitmap): render as a texture over the terrain mesh ("draping")
This capability is especially favorable when working with GeoJSON, since a spec-conforming GeoJSON is 2D. See user requests e.g. https://github.com/visgl/deck.gl/issues/6644 https://github.com/visgl/deck.gl/discussions/5457
Proposal
- Add a new operation
terrain. If aTerrainLayerhas the propoperation: "terrain", instead of drawing to the screen, it supplies 1) an elevation texture; 2) a 3D mesh for other layers to use. - Add a new extension
TerrainExtension. A 2D layer can use this extension to be fitted over the terrain surface. - Add a new effect
TerrainEffectto coordinate the resources. This is similar to how the mask effect works.
Sample code snippet:
layers: [
new TerrainLayer({
data: 'https://my.tile.server/{x}/{y}/{z}',
operation: 'terrain'
}),
new GeoJsonLayer({
data: './regions.json',
extensions: [new TerrainExtension()]
})
]
@ibgreen @chrisgervang @felixpalmer
Very interesting proposal, I like the use of a new operation to define the linkage between the terrain and offset layer.
- Unlike the mask extension a very common use case will be to draw the
TerrainLayerto screen as well as using it as source for other layers. Is it worth supporting a compounddrawoperation"draw+terrain"in this case? Requiring the user to duplicate the layer seems cumbersome - The naming
TerrainExtensionis implying a geospatial usecase only. It is possible to conceive of non-geospatial usecases, like aPointLayerabove an extrudedColumnLayer.OffsetExtensionas an alernative? - The
MaskExtensionsupports multiple masks by reference using themaskIdprop. SupportterrainIdprop in a similar manner? - The implementation of "shifting" seems relatively straightforward as the offset can be performed in the vertex shader by a lookup in the elevation texture, however I think it would be good to clarify how the draping will work. In the case of a bitmap we would apply the bitmap to the mesh, but what happens in the case of polygons/paths? Will they be rasterized into an bitmap prior to draping? Will we attempt to merge the geometries? Will there be limitations on rendering (lighting effects, screenspace line-widths)?
Hi, any progress on this? Thanks
Hi! Has this made it into master?
Has there been any progress on this issue? Thanks!
Bumping this feature
hi @Pessimistress I want to apply the mask to deck.Tile3DLayer that using google 3d tiles
i have already added polygon over it using TerrainExtension
all I want is remove or hide this area from other Tiles like masking the given area (invert masking) and you have mentioned TerrainEffect in upper thread and how do I do this please help
If a TerrainLayer has the prop operation: "terrain", instead of drawing to the screen, it supplies 1) an elevation texture; 2) a 3D mesh for other layers to use.
how can I access the 3D mesh for other layers to use (ex like three js )