fill-extrusion polygons occluded by underlying raster layer with raster-elevation at low pitch, depth-test appears to collapse
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 12.4k
- Forks
- 2.4k
- PR merge metrics
- No merged PRs in 30d
Description
### mapbox-gl-js version
3.25.x
### Browser and version
Chrome 130 / Safari 17 / Firefox 131 — reproduces in all three
### Expected behavior
A fill-extrusion polygon whose fill-extrusion-base sits above a raster layer's raster-elevation should paint on top of the raster at every pitch and
zoom. The raster's sub-1 raster-opacity (254/255) forces the alpha-blend path and should skip depth-write, so the elevated polygon always wins the
depth test.
### Actual behavior
- At pitch >= ~30°: polygon renders correctly on top of the raster.
- At pitch < ~15° (near top-down): the polygon becomes invisible; the raster paints where the polygon should be. The effect gets 100% reproducible past
~zoom 20.5 on zoom-out and near-orthographic views. At the transition zooms the polygon flickers in and out as depth values quantize.
- map.queryRenderedFeatures() still returns the polygon at the missing pixels — it's in the scene, just not drawn. A line layer on the same geometry
(which doesn't depth-test) stays visible; only the fill-extrusion top face is occluded.
- Removing raster-elevation from the raster paint restores the polygon at all pitches, but breaks multi-floor raster stacking.
### Link to the demonstration
_No response_
### Steps to trigger the unexpected behavior
1. new mapboxgl.Map({ style: 'mapbox://styles/mapbox/standard', center: [-74.0, 40.7], zoom: 20, pitch: 0 }).
2. Add an image source and a raster layer with raster-opacity: 254/255 and raster-elevation: 0.1.
3. Add a fill-extrusion layer whose polygon overlaps the raster, with fill-extrusion-base: 0.15 and fill-extrusion-height: 0.5 (top clearly above the
raster in world Z).
4. View at pitch: 0 — polygon is missing; the raster paints through where it should be.
5. map.easeTo({ pitch: 45 }) — polygon reappears.
6. map.easeTo({ pitch: 0 }) — polygon disappears again.
7. Alternate: keep pitch 0 and zoom from 22 → 18 — polygon vanishes below ~zoom 20.5.
### Relevant log output
```shell
No warnings or errors are emitted by Mapbox GL JS. The console stays clean throughout.
map.queryRenderedFeatures(centerPixel, { layers: ['poly'] }) at pitch 0, zoom 19:
[{ layer: { id: 'poly', type: 'fill-extrusion' }, properties: {...}, geometry: {...} }]
(polygon is found in the scene but not visible on screen.)
map.getStyle().layers.map(l => ({ id: l.id, type: l.type, slot: l.slot })) — confirms raster sits before poly in the style layer order.
WebGL: WEBGL_debug_renderer_info reports ANGLE (…) / Apple M-series GPU / … on affected machines; the same repro fails identically on Intel integrated,
Apple Silicon, and discrete NVIDIA, so it's not driver-specific.
```
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the issue through mapboxgl.Map, the raster layer's raster-elevation and raster-opacity, and the fill-extrusion layer at pitch 0 and 45 while varying zoom. Trace the raster and fill-extrusion rendering paths involved in depth testing; done means the polygon remains visible above the raster at low pitch and near-orthographic zooms without breaking raster stacking.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- computer-graphics
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100