maplibre-gl-js
maplibre-gl-js copied to clipboard
Globe custom layers: draw globe into depth buffer
This PR fixes #4817
Fill extrusion and 3D custom layer now use a depth buffer with globe rendered into it for occlusion. All layer blending should work just like it does with fill-extrusion without globe. Removed ray-sphere intersection test from fill extrusion pixel shader, since regular depth testing is used now.
All below is OUTDATED, only left for documentation.
A new render pass is added: "3d". It executes after all the other passes ("offscreen", "opaque", "translucent"). When globe is enabled, the globe is drawn into the depth buffer before this "3d" pass. Custom layers that are marked as being 3D then use this render pass. This pass needs to be the last pass, since it replaces the depth buffer contents that is used by other layers for optimization.
This also means that other layers cannot be blended on top of custom 3D layers (only other custom 3D layers can).
Fill-extrusion does not use this pass at the moment, since other layers can be blended on top of it. So fill-extrusion still does ray-sphere intersection in the shader.
There are definitely ways to make both fill extrusion and 3D custom layers use the depth buffer and still allow other layers to be drawn on top, but I think those would be unnecessarily complicated and would not be compatible with the current optimization where opaque pixels do not get overdrawn with underlying translucent layers. Fast drawing of regular 2D maps should take priority, IMO.
Note that the model must be drawn on top of all other layers, including symbols, in order to use globe's depth buffer:
I'm not sure if there is a good solution to this, or if this even had a good solution before the globe. I guess symbols could either always be overdrawn by the model or the model could always be overdrawn by the symbols...