Skip to content

Commit 172fa0e

Browse files
lasselammiactions-userkediarov
authored andcommitted
[MAPS3D-865] Make line-emissive-strength data-driven (#5075)
This PR makes the property `line-emissive-strength` data-driven. Implemented for both GL JS and Native. ``` <public> [MAPS3D-865] Make line-emissive-strength data-driven (#5075) </public> ``` ## Background Making `line-emissive-strength` data-driven should allow merging road layers in the Standard style as a performance optimization. More details are in the ticket: https://mapbox.atlassian.net/browse/MAPS3D-865 ## Draping support During draping we must be able to accumulate the per-feature emissive strength values from each layer, so that they can be used later when the lighting is applied during the terrain/globe raster pass. For this we have two approaches: **dual-source blending** and **MRT fallback**. ### Dual-source blending Dual-source blending is fully compatible with our previous emissive strength support where the emissive values are accumulated in the alpha channel of the main color texture. The old approach applies emissive strength as a constant alpha value for the blend mode, which means no per-feature emissive strength is possible for draping. With dual-source blending, we output the emissive strength value from the fragment shader along with the color value, which are then blended together with `Src1Alpha` blend factor. Using dual-source blending is the optimal approach, since it doesn't increase memory usage and has no performance penalty compared to our previous approach. Unfortunately it's not available on every device, so before we use it we must check that it's supported. This is done in different ways depending on the platform. **GL-JS:** - Support for dual-source blending is checked using the WebGL extension `WEBGL_blend_func_extended` - Latest versions of Chrome and Safari support dual-source blending. Firefox doesn't have support for it yet **GL-Native:** - OpenGL: Support for dual-source blending is checked using `glad` with the extensions `GLAD_GL_ARB_blend_func_extended` and `GLAD_GL_EXT_blend_func_extended` - Metal: Support is checked by using GPU family information queried at runtime similar to how it's done for occlusion queries - Vulkan: Support is checked using physical device feature `dualSrcBlend` queried at runtime ### MRT (multiple render targets) fallback All of the platforms and devices that we support should support a minimum of 4 color attachments for FBOs and we only need 2 for the MRT fallback approach for data-driven emissive strength. The fallback mode is only activated when dual-source blending is not available and when the style has a layer with a data-driven `line-emissive-strength` property. This is when a secondary color attachment is added to offscreen textures that are used for draping using the format `gfx::PixelFormat::R8`. In this mode, all of the layers that use emissive strength accumulate it into the secondary color texture instead of the alpha channel of the main color texture. These secondary color textures are expected to increase memory usage of the draping pool by 25%. ### MRT support for Vulkan I didn't want to make this PR any bigger than it already is, so it only includes support for dual-source blending for Vulkan. MRT support for Vulkan can be implemented as a follow-up PR. ### Render tests To ensure that support for MRT attachments remains fully functional even as more platforms start supporting dual-source blending, I added a new render test flag `forceEmissiveFallback` to force render tests to use the MRT fallback render path. In this way all platforms will run tests for the MRT fallback approach even when dual-source blending is available. ### Shell example I added a Shell example for data-driven `line-emissive-strength`. By using the example it is possible to use both dual-source blending (when available) and MRT fallback. When the example is active it also shows which mode is currently being used, so it is possible to check if a particular device supports dual-source blending by running the Shell app on it and enabling the example. The code for the Shell example is mostly AI generated. <img width="1358" height="960" alt="image" src="https://github.com/user-attachments/assets/806de749-60cd-401b-b7b5-92c5b827c73f" /> ## Performance considerations The changes in this PR should not affect the performance of styles that don't contain any layers with data-driven `line-emissive-strength` property. When a style does contain a layer with a data-driven `line-emissive-strength` property: **Without draping:** - No issues here since the emissive strength is applied normally in the fragment shader during immediate rendering **With draping:** - Dual-source blending: - No extra memory used - No expected performance decrease (benchmarks still needed) - MRT fallback: - Extra memory for draping pool (25% increase) - Extra memory bandwidth needed for writing to multiple render targets. For this render path we must write emissive values from **all layers** to the secondary emissive attachment. I tested loading and rendering performance using a style with reduced number of road layers which is available here https://mapbox.atlassian.net/browse/MAPS3D-865?focusedCommentId=534175 **Loading performance:** Profiled using Xcode with an iPhone 15. I didn't see any clear performance difference in my tests. **Rendering performance:** Tested with S22 Ultra, zoom 12, pitch 60 near Munich. 113 FPS with the original style vs 117 FPS with the updated style using data-driven `line-emissive-strength`. cc @mapbox/gl-js cc @mapbox/gl-native [MAPS3D-865]: https://mapbox.atlassian.net/browse/MAPS3D-865?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ cc @mapbox/maps-android cc @mapbox/maps-ios cc @mapbox/sdk-ci --------- Co-authored-by: Changelog autocreator bot <[email protected]> Co-authored-by: Kirill Kediarov <[email protected]> GitOrigin-RevId: aac743c91adfe15e67295e27cc9ff4702d328d42
1 parent eea710c commit 172fa0e

File tree

5 files changed

+91
-27
lines changed

5 files changed

+91
-27
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Mapbox welcomes participation and contributions from everyone.
99
* Add `FillExtrusionLayer.castShadows` property.
1010
* Add `GeoJSONSource.minZoom` property.
1111
* Add `RasterArraySource.volatile` experimental property.
12+
* Make `line-emissive-strength` property data-driven.
1213

1314
## 11.17.0-beta.1 - 05 November, 2025
1415

Sources/MapboxMaps/Annotations/Generated/PolylineAnnotation.swift

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tests/MapboxMapsTests/Annotations/Generated/PolylineAnnotationIntegrationTests.swift

Lines changed: 34 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tests/MapboxMapsTests/Annotations/Generated/PolylineAnnotationTests.swift

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Tests/MapboxMapsTests/Style/Generated/IntegrationTests/SnowIntegrationTests.swift

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)