Skip to content

Conversation

@bcamper
Copy link
Member

@bcamper bcamper commented Feb 13, 2019

For styles drawn with non-opaque blend modes, the blend_order is used to determine the rendering order, and thus which features are drawn on top of each other where there are overlaps.

Because it has only been possible to set blend_order at the style level, a common pattern has developed where several very similar / template rendering styles are created, to achieve different visual layering:

polygons-overlay-low:
  base: polygons
  blend: overlay
  blend_order: 1
polygons-overlay-mid:
  base: polygons
  blend: overlay
  blend_order: 3
polygons-overlay-high:
  base: polygons
  blend: overlay
  blend_order: 5

This is inefficient and unwieldy -- and inflexible, especially when mixing data on top of basemaps (which end up having to predefine certain fixed blend_order "slots" for use by data overlays). This PR enables the blend_order to be set at the draw block level (following prior similar work for dash, texture, etc.). This allows for much more flexible blend_order expressions, and a semantic use that aligns with the order parameter used for geometry world order of opaque-rendered features. For example:

styles:
  polygons-overlay:
    base: polygons
    blend: overlay

layers:
  overlays:
    ...
    draw:
      polygons-overlay:
        blend_order: 3

    sub-layer:
      ...
      draw:
        polygons-overlay:
          blend_order: 7

Implementation notes: perviously, the engine enforced that each style was only rendered once per render pass. With this feature, the engine will now bucket geometries for a given style by their blend_order, and then render styles one or more times (split up using these buckets), as dictated by the total number of unique, sorted blend_order values currently visible in the scene.

@bcamper
Copy link
Member Author

bcamper commented Feb 15, 2019

@matteblair just wanted to run this by you, in case it poses any gotchas on the ES side... I think it's worthwhile given the way this (anti-)pattern has evolved (seeing some dataviz cases where 10+ of these types of styles are being created).

On the JS side, it is a fairly natural extension of a recent move towards more "bucketing" internally of different style variations (different texture bindings, use of constant attributes in some cases, etc.). I know this is not quite the same on the ES side, but believe there is some similar behavior for managing sprite/texture batching etc. (?)

@nvkelso
Copy link
Member

nvkelso commented Feb 15, 2019

Created ES issue in tangrams/tangram-es#2039.

@matteblair
Copy link
Member

Thanks for the heads up. This won't be trivial to implement in Tangram ES, but I don't think there's anything fundamentally preventing it.

@tallytalwar
Copy link
Member

This is also true for dash parameter, which JS supports and ES does not and having had a look at it recently, not trivial to implement on ES. tangrams/tangram-es#2023

@bcamper
Copy link
Member Author

bcamper commented Feb 17, 2019

@matteblair @tallytalwar Interesting, thanks. Are there particular challenges (for my knowledge benefit) for this in the ES rendering pipeline? On JS, the change that "opened up" a lot of these changes was adding a concept of having different "variants" of meshes per style, instead of requiring exactly one mesh. When a style was rendered for a tile, it would render all the mesh variants, but they could change certain state, such as uniform values, texture bindings, etc. This was originally added for the line offset feature. I was then able to repurpose this for several related features, like moving dash and texture bindings to the draw level.

Doing this for blend_order required a further change. Each mesh variant for the style now has a blend_order, which means they are no longer rendered in succession in one "render this style" call. Previously, all visible styles were sorted by blend_order; now, the full set of all the individual mesh variants are sorted by blend_order (which means there is some "style setup" code that may need to be run multiple times, if styles end up interleaved with multiple blend_order values).

Does that make sense? (May or may not be directly applicable in the ES case.)

@bcamper bcamper merged commit 717f00b into master Feb 20, 2019
@bcamper bcamper deleted the draw-blend-order branch February 20, 2019 03:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants