maplibre-gl-js
maplibre-gl-js copied to clipboard
Fill outline drawn over instead of under overlapping polygon
maplibre-gl-js version: all
browser: chrome
Steps to Trigger Behavior
- Draw two overlapping polygons
- The outline of the polygon underneath will be painted over the body of the polygon on top
Link to Demonstration
https://stackblitz.com/edit/stackblitz-starters-84slde?file=index.html
Expected Behavior
The outline is under the overlapping polygon.
Actual Behavior
The outline is on top of the overlapping polygon
Some thoughts on the subject.
It looks like a really deep-seated problem without any easy and performance-safe solutions.
Reason for such behaviour is obvious: in drawFill, we first draw all the fills, then all the outlines. Pseudocode:
for (tile of tiles)
drawFill()
for (tile of tiles)
drawOutline()
So it's no surprise that outlines appear on top.
To make it work, we need to alternate fills and outlines: "fill shape1 -> outline shape1 -> fill shape2 -> outline shape2 -> ..." This is currently a very non-trivial task. For that we need to "take apart" each tile and somehow draw its features 1 by 1:
for (tile of tiles)
features = extractFeaturesFrom(tile)
for (feature of features)
drawFill()
drawOutline()
This looks like a really disruptive solution. Implementation will surely be difficult and performance will apparently suffer, though hard to tell how much. So perhaps the best solution would be to leave it as it is. Overlapping geometries within a single source is not a widespread case i suppose.
I need to check again, but it might be that the error is not present when terrain is on.
When terrain is on we render to texture, which is a lot slower and can explain the difference, I think.
Unrelated, but still interesting to me, do you have a number on the performance impact of rendering to texture vs the normal path? Do we have a benchmark maybe?
I don't, but it's a noticable difference in terms of UX so it's in the area of hundres of milliseconds.