tangrams / tangram

WebGL map rendering engine for creative cartography
https://tangram.city
MIT License
2.22k stars 290 forks source link

Dynamic point textures #588

Closed bcamper closed 7 years ago

bcamper commented 7 years ago

This PR relaxes the requirement that a points-based style be bound to only one (or no) texture.

With this change, a scene author can freely re-assign (or un-assign) the texture that the style is bound to, within a draw group, using the texture parameter.

For example:

layers:
  data: ...

  landuse:
    filter: ...
    draw:
      points:
        texture: landuse.png # render landuse icons with one texture
        ...

  pois:
    filter: ...
    draw:
      points:
        texture: pois.png # render POI icons with a different texture
        ...

    zoos:
      filter: ...
      draw:
        points:
          texture: zoos.png # override in sublayer to render zoos with a third texture

This change is fully backwards compatible with existing styles: if a style has set a texture, this simply becomes the default value, but that value can then be overridden if desired within layers.

If no texture value is set for the final merged draw group (either because it was not set by the style or by a parent layer's draw group, or it was explicitly un-set in a child draw group with texture: null), then the feature will be drawn with the built-in points style (e.g. as regular points would be drawn, with no texture bound).

Extending the example above:

  buildings:
    filter: ...
    draw:
      points:
        color: red # no texture is set by parent style or layer, so buildings will draw as simple points
        ...

  pois:
    filter: ...
    draw:
      points:
        texture: pois.png # default POI texture

    parks:
      filter: ...
      draw:
        points:
          texture: null # texture is explicitly un-set, so parks will render as simple points
          color: green
          ...

Internally, this feature uses the recently added "mesh variant" concept, where the same style can create sub-meshes that each have their own uniform state or vertex layouts. All vertex layouts must be compatible with the same underlying shader program, but a variant can set a vertex attribute to a static value to lower memory consumption, if that attribute has a suitable default value. For this PR, the variants will vary the uniform texture sampler that is bound for sprites, and the vertex layout can set static values of zero for point outlines where they are not needed.

bcamper commented 7 years ago

Note: one motivation for this feature from the Mapzen cartography perspective is easier support for additional textures in the future, such as expanded road shields for US states and countries, where it is impractical to fit all these shields into a single texture (and/or some textures may be loaded lazily at run-time, only when those regions are visited).

bcamper commented 7 years ago

@matteblair could you please take a look to ensure this will work from the ES perspective.

nvkelso commented 7 years ago

Tangram ES support being tracked in https://github.com/tangrams/tangram-es/issues/1645.