mapbox / mapbox-gl-js

Interactive, thoroughly customizable maps in the browser, powered by vector tiles and WebGL
https://docs.mapbox.com/mapbox-gl-js/
Other
11.17k stars 2.22k forks source link

Support inner glow effect on fill layers #769

Open peterqliu opened 10 years ago

peterqliu commented 10 years ago

To simulate drop shadows.

ajashton commented 9 years ago

Depending on how this is implemented, it may make sense to think about tint bands in the same way. These are basically the non-blurry version of an inner-glow.

Also, depending on the layer, a drop-shadow/outer-glow property would also be desirable.

samanpwbb commented 9 years ago

@kkaefer word on the street is that you have an implementation for this in mind. Do you think you could lay out the next actions (even if real work on this is still a ways away)

kkaefer commented 9 years ago

I'm seeing two ways of implementing this: either via signed distance fields, or via gaussian blur. SDFs are harder to create, but will potentially look nicer than blurs. Gaussian blurs might be a good compromise, since they're faster to compute than SDFs.

Tint bands are difficult with both techniques since the killer feature for tint bands is the ability to color every band differently, which means we'd have to create a separate blur/SDF per feature, which isn't viable.

ajashton commented 9 years ago

Different colors per tint band are important for some things but not always necessary. Eg they are also commonly used for boundaries of national parks / nature reserves, in which case you would only need 1 color per layer.

kkaefer commented 9 years ago

Rendering inner glows with gaussian blur seems possible and looks quite nice:

screen shot 2015-05-18 at 18 17 49

Bands on the other hand aren't going to be possible with this technique. For bands to look decent, we'd have to generate a proper signed distance field, or use actual polygon offsetting.

mourner commented 9 years ago

@kkaefer I see there are noticeable artifacts on tile boundaries, is it easy to fix with the blur approach?

image

Also wondering how blur affects performance.

peterqliu commented 9 years ago

@nickidlugash an extra wrinkle in this problem: when using blur for water bodies, does it make sense to use the same blur distance for all sizes of oceans/lakes/rivers? narrow rivers and small lakes won't be wide/big enough to show a non-shadowed shade of blue, and hence will look darker overall.

If it's indeed an issue, I can't think of a non-complex way to handle these cases.

nickidlugash commented 9 years ago

@nickidlugash an extra wrinkle in this problem: when using blur for water bodies, does it make sense to use the same blur distance for all sizes of oceans/lakes/rivers? narrow rivers and small lakes won't be wide/big enough to show a non-shadowed shade of blue, and hence will look darker overall.

@peterqliu hmm, same blur distance is how it works in carto, and I think it looks fine (I think it might actually look uglier to have a variable blur distance). In carto styles, I usually style the waterway layers to be the same color as the color around the water edges, not the water color itself.

@kkaefer that blur test looks great! We get the same rendering artifacts around tile edges in carto/mapnik too – @ajashton is this something we can fix on the data side?

peterqliu commented 9 years ago

Also wondering how blur affects performance.

@mourner since it's getting blurry anyway, can we smartly simplify the geometry as blur distance increases, in hopes of salvaging some perf savings?

ajashton commented 9 years ago

We get the same rendering artifacts around tile edges in carto/mapnik too – @ajashton is this something we can fix on the data side?

There should be enough data in the vector tiles to fix this on the rendering side. The blur edge artifacts are not an issue in Mapnik when you use image-filters-inflate: true; - this renders the blur with the buffer taken into account.

ajashton commented 9 years ago

same blur distance is how it works in carto, and I think it looks fine (I think it might actually look uglier to have a variable blur distance). In carto styles, I usually style the waterway layers to be the same color as the color around the water edges, not the water color itself.

+1 agreed

nickidlugash commented 8 years ago

@kkaefer is this still something we're considering doing?

jrbowen commented 8 years ago

@ajashton @nickidlugash tint bands are a major style requirement on many of the maps over here at nat geo. I've worked on getting around the issue but haven't been able to come up with anything - is there anything you guys know of in the meantime that will remove the comp bands around the tile edges?

screen shot 2016-03-16 at 3 12 14 pm

screen shot 2016-03-16 at 3 25 35 pm

peterqliu commented 8 years ago

@jbowen24 how are you making your bands? Can you link to a live example?

jrbowen commented 8 years ago

@peterqliu Primarily using the same method described here; https://www.mapbox.com/blog/customizing-geography-class/

Compositing borders with- image-filters: agg-stack-blur(5,5); Knocking out the polygon center with- polygon-comp-op: hard-light; Then changing the background's level of black to choose how much color comes through- background-color: #a2a2a2;

example here; https://api.mapbox.com/v4/jelder.35845870/page.html?access_token=pk.eyJ1IjoiamVsZGVyIiwiYSI6InpCTmhMdm8ifQ.lJcqxcME79NwtzwTNX2qNw#4/-9.54/-34.28

Is there a better way to go about it so the tile boundaries don't show up?

muesliq commented 8 years ago

+1

muesliq commented 7 years ago

Any update on this?

kkaefer commented 6 years ago

As mentioned in a previous comment, signed distance fields are the way to go here. We could render a low resolution SDF for a layer that allows us to shade both sides of the polygon outlines up to a certain distance. Apart from gradients around borders, this would also enable implementing tint bands, and offset polygons/borders without the caveats of a geometric line offseting/buffering algorithm.

To reduce the number of shaded pixels, we could use a contouring algorithm like CONREC (C++ impl, h/t @kevinkreiser), GDAL's Polygonize, or Marching squares (e.g. d3 impl) to obtain a polygon of the part of the tile we're interested in, and only draw those fragments. This helps in areas that don't have many polygons, e.g. when drawing water in a continental area where there are only small lakes, rivers, or shorelines visible.

@muesliq, please note that this doesn't mean that we're going to implement this any time soon, I'm just collecting thoughts. We're happy to accept contributions.

/cc @natslaughter

ifzm commented 5 years ago

Highlighting the plot will make the map look better and look forward to this feature.

bagirimana commented 4 years ago

I think this feature could greatly improve the aesthetics of many Mapbox maps, for sure ours, so I hope its development will be continued. 👌