-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
Custom WebGL Layers API #6456
Comments
@mourner Very excited to see that this is progressing. I wanted to provide some input from deck.gl as we have been integrating with mapbox-gl for a long time.
What would be valuable for deck.gl is the ability to provide a matrix to mapbox-gl. Then we could keep showing the map at any (or at least a wider range of) angles and not have the map "pop in and out" as is currently the case. There is an example of this interaction in our react-map-gl repo FWIW - As you probably know, deck.gl provides a dedicated module viewport-mercator-project that is essentially devoted to generating mapbox compatible projection matrices from a |
@ibgreen 👍 I think this aligns with the proposal in #2801 (a bit embedded in the discussion) for a declarative camera API. (It's not exactly the same, since if what you have is an already computed matrix, you'd have to work backwards to the camera's zoom/center/pitch/bearing abstraction.) #5743 brought us a step closer on this front. |
@ibgreen @anandthakker as far as I remember, the original reason to limit pitch is that we don't have level-of-detail tile loading logic — all tiles load on the same zoom level, so a pitch too high would trigger tiles loading into infinity. What if we try to fix this root issue instead of exposing a leaky abstraction (accepting an external projection matrix)? |
Hi, We completely share your point of view regarding the opportunities and the risks of this feature, particularly the performance improvement, the ability to draw between Mapbox GL layers and the risk of sharing an unique WebGL context. Regarding the idea of using events without “custom-webgl” layers. I think we’ll be able to adapt to that API, although I think it could require some workarounds from third-party renderers. For instance, in your example, if the Regarding the list of open questions:
Tracking all state probably takes a huge performance hit. And, in this way, a correct API-compliant external renderer should work with any Mapbox GL release as long as Mapbox GL doesn’t break this API promise. If in the future there is more tracked state, then it shouldn’t matter to external renderers. However, removing tracked state is a breaking change.
Thank you! |
@mourner Here is a GIF of the simple example in react-map-gl mentioned above, where we hide the map whenever mapbox can no longer match the view projection matrix. I realize it looks strange in a simple example like this but when we have a lot of deck.gl geometry on top of the map and carefully selected colors it makes more sense as the map is just one of many visual components. |
Now, the requirement to specify an external matrix can probably be regarded as a separate issue from the custom layers API, so maybe we can leave this discussion here. But I do think this is a feature mapbox should consider offering as a complement to the API. If there is any interest from your side, I'd be happy to help explain use cases or brainstorm for ways to work around your concerns. |
That looks promising, thanks for the links! FWIW, we did a lot of work in deck.gl on a similar system. We ended up creating a hierarchy of "Viewport" classes (that are essentially geospatial aware cameras that are used to generate matrices and uniforms) and a separate "TransitionManager" to handle the various transition and animation cases. Our Viewport classes include a "WebMercatorViewport" that is mapbox compatible but also more "standard" viewports like "FirstPersonViewport" (when using these we just turn off the map). |
When does it make sense for us to do a test integration with deck.gl? Is the Carto PR in good condition, or is it still too early? Our main initial focus would be quite simple:
|
I think we could also expose this a class MyCustomStyleLayer extends CustomStyleLayer {
constructor(...) {}
renderTranslucent(context, matrix) {
// draw
}
}
map.addLayer(new MyCustomStyleLayer(...)); I think we many want to eventually expose the style spec format and style property evaluation so that custom layers can be specified within styles. If that happens, I think it would be easier to expand the
Is there some way we could support async use of the context while not relying on the user to manually invalidate it? Either by assuming the state is invalid whenever mapboxgl code resumes control from user code, or by adding a
I think we'll need to expose some concept of render passes so that we can support both flat and 3d layers. If we're doing this we might as well expose the opaque pass if the optimization is worthwhile enough for us to use it internally (is it @kkaefer?).
The matrix we provide users will transform a z value from some units (question: which units? pixels? % of the world? meters?) into the gl coords used by us. We could expose near and far values if that helps in some way but I think this should be mainly handled by the matrix we provide. But what if we eventually want to switch to logarithmic depth in order to increase depth precision? This would be a breaking change for all custom 3d layers because we'd need them to add extra custom shader code. I'm not sure what we can do here besides possibly breaking things in the future. Some more open questions:
|
I'm also in favor of sticking with the layer concept for this feature, rather than introducing a new paradigm. |
Actually, I would really like to use a custom shader for Edit: added description for screen shot. In older versions of our systems we have used a "land" layer above "water", rather than a "water" layer above "land".. but that's not how mapbox/openstreetmap data is defined. |
@markusjohnsson is this the same as the 'inverted fill' to mask a map area #6267 ? |
@planemad our problem could be solved using either method, but what I'm suggesting here is not the same thing, technically. |
As someone who pitched for something like this in #4327 more than year ago, I'm very interested in following this discussion. I currently resort to Tangram whenever I need to do some custom rendering that goes beyond overlaying something. |
@ibesora thanks for chiming in! Customizing the shaders is something I've explored a bit a while ago here #281 (comment), but I think we can follow up on that independently of this feature — it's a different kind of "custom" that doesn't overlap much. BTW, we're sprinting on custom layers this week in Kyiv with @ansis — stay tuned for updates! |
This is in progress over at #7039 |
closed in #7039 |
Currently the only way to extend Mapbox GL JS with custom WebGL visualizations is overlaying the map with another canvas. This approach is used in several GL JS-powered visualization platforms such as Deck.gl (with Kepler.gl) and Carto VL. It has a few major drawbacks:
To solve this, we need to expose a way to hook into the GL JS rendering loop and draw something using the same GL context. We want to do that very carefully though, because it’s a volatile public API that is likely to change in a breaking way multiple times as we iterate on it, and has a risk of breaking from internal changes. Committing to it can significantly increase our maintenance burden.
To move this forward while reducing the risks, we'd like to introduce it in a way that doesn’t touch the style specification. To achieve this, instead of adding a new layer type, we could introduce a new event that fires after each layer draw so that you could do custom drawing in between layers. Additionally, we would expose public map methods for getting the GL context and invalidating the GL state.
One way this could look is:
Open questions:
offscreen
,opaque
andtranslucent
. Are we OK with only exposing thetranslucent
pass for drawing custom layers?Previous proposal by the Carto team: #6124
Original issue: #281
cc @mapbox/gl-core @davidmanzanares @philogb
The text was updated successfully, but these errors were encountered: