-
-
Notifications
You must be signed in to change notification settings - Fork 884
Description
User Story
As a GIS data analyst, I can edit contrast/brightness/saturation
per-band, so that raster-tile-sources RGB channels can be edited separately in order to apply contrast stretching to match multiple basemaps colors and visually highlight change.
Rationale
Similar feature requested at mapbox mapbox/mapbox-gl-js#13520
Context is, with historical-satellite I'm comparing different public XYZ/TMS raster tilesets sources. I'm enhancing differences by rendering two overlaid maps in two different canvases, with css clip-path and blending-modes
. It would sometimes be useful to preprocess the canvas to apply some sort of histogram equalization, or at least contrast stretching. This way, the blending modes would let the user focus only on large visual change.
What would be great is to extend the raster-saturation raster-contrast raster-brightness-min/max
so they would not only accept a float value, but optionally a float array, which would be exposed per-band, so each RGB channel would have applied a different color-transform.
Under the hood, the current implementation would be akin to passing the same amount/param for each band.
Currently, these uniforms are defined via shader and mapped from raster layer paint properties here
maplibre-gl-js/src/render/program/raster_program.ts
Lines 63 to 66 in 00f1958
'u_brightness_low': layer.paint.get('raster-brightness-min'), | |
'u_brightness_high': layer.paint.get('raster-brightness-max'), | |
'u_saturation_factor': saturationFactor(layer.paint.get('raster-saturation')), | |
'u_contrast_factor': contrastFactor(layer.paint.get('raster-contrast')), |
Similar discussion specific to raster-color & raster-color-mix
#4479 (comment) suggests using addProtocol custom
to draw returned image into a canvas and edit. It would be more performant to do these operations in the raster fragment shader, especially given they are already applied - only applied the same for all bands.
Impact
If these properties raster-brightness-min/max, raster-saturation, raster-contrast
stay as is - same values for every band of raster - then automated contrast-stretching will only be approximate, applying the same intensity stretching for R/G/B.
In raster.fragment.glsl, the fragment shader uniform u_colorization_scale
(and function configureRasterColor
) could be passed 3x the current count of params (current min/max is the same for all bands, could be minR, maxR, minG, maxG, minB, maxB