GLSL shaders are small C-like programs that modify the default rendering pipeline of your graphics card and let you manipulate every pixel on your screen at full speed. I like to think of it as the language of light.
One of the nicest features of the Tangram engine is the ability to write GLSL code alongside the YAML scene files. This give Tangram’s styles remarkable flexibility.
TRON2.0 was designed with the intention of pushing this power to the limits.
Everything starts with Geraldine’s idea of making a map where the patterns change with the zoom level, providing an extra sense of scale. From there we started collecting visual references in a Pinterest board.
Sketching ideas in small shaders
With some references in mind, I started making some sketches of dynamic patterns to present to Geraldine.
Hover or click on any sketch
Our next iteration consisted of making an algorithmic color palette.
vec3 palette(in float x) {
return mix(vec3(0.000,1.000,1.),
vec3(1.,0.,0.),
vec3(smoothstep(0.0,1.048, x),
sin(x*2.806),
smoothstep(-0.512,1.072,x)))
*(1.0-sin(-0.196+x*3.950)*0.380);
}
The art behind this language of light is understanding and using the expressive possibilities of numbers between 0.0 and 1.0. The palette function above, for example, takes a single value between this range and uses it to oscillate, interpolate and stretch the values between two colors, resulting in whole new spectrum of light, a spectrum that we assign programmatically to moving lines of traffic, fading buildings walls, neon highways, hillshades and shimmering oceans.
With it, we started creating the patterns that ultimately shaped the distinctive elements of TRON2.0.
Hover and click on any sketch
Composing in Tangram Play
Although we used this github repository for the process, we also worked in our in-house web Tangram editor environment, Tangram Play.
In TRON2.0, we took advantage of one of the newest features of Tangram: the import
system. This allows Tangram to import
any other YAML scene file, and it is easy as…
import:
- https://tangrams.github.io/tron-style/tron-style.yaml
…to start editing a scene.
Try it on directly in Tangram Play
We used import
to divide the scene into different folders and files, making TRON2.0 easier to read and edit.
Here’s how it ends up looking:
tron-style.yaml
is the main.yaml
file that mixes and holds it all together. There you will find the definition of thesources
,cameras
andscene:background:color
, together with theimports
that glow and connections to thelayers
,styles
andcomponents
resources.the
layers/
folder holds the sets of rules that filter the data (coming from thesources
) into different style rules. layers tell Tangram how to treat each component on the map, whether they aretext
,points
,lines
orpolygons
, withsize
andcolor
. In this folder you will find different.yaml
scene files that carefully make sense of the data and display it in a cartographically intuitive way. This meticulous work was made by Geraldine Sarmiento and Nathaniel V. Kelso. At the end of each layer file you will also find astyles
section where the custom shaders are defined and crafted by me (Patricio Gonzalez Vivo). Shaders are not a simple thing, but at Mapzen we are trying to make them more approachable. Tangramstyles
can be mixed, which reduces the complexity and size of the shaders by reusing them as much as possible.the
styles/
folder contains all thestyles
that are shared across layers. It is definitely a more abstract layer. This folder sorts thestyles
by theirbase
geometry (points
,lines
orpolygons
). Thosestyles
common to all the other geometries can be found incommon.yaml
. You will note that most shader styles “extend” from blocks.the
components/
folder holds some of the global resources used in the scene, likefonts
andimages/
along with theglobals.yaml
. This particular file is very interesting because holdsglobals
variables and JS functions that control the map. We can use theseglobals
to turn on or off the animations or to change the language on the map.
Reusing the building blocks
“When coding, don’t repeat yourself.”
Thanks to the new import
feature, I was able to turn shader recipes into something that anybody could use in Tangram styles. As part of the effort to make GLSL Shaders more approachable in Tangram, I started building Tangram Blocks, a toolbox/library of shader snippets that can be mixed together. A lot of work on TRON2.0 involved making these blocks reusable in a production context. Each block self-documents itself, providing not only a description and examples but also helpful information like the range of the expected variables.
This is a list of some of to new patterns introduce by TRON2.0:
- Polygons diagonal stripes
- Polygons dots
- Polygons shimmering
- Lines glow
- Lines dots glow
- Lines data stream for the car animation
- Elevation stripes hillshading
- Interpolation zoom function
Bundling things up
By the time we finished, we had a beautiful animated map. We also a a lot of related YAML scene files. Each one of them needs to be loaded before we can start rendering – this would mean a lot of HTTP requests that would affect performance.
To solve that I worked up a small Python script that lets you bundle a scene file and its dependencies and components all together into one .zip
file, called Tangram Bundler.
Installing it is simple:
pip install tangram_bundler
tangram-bundle scene.yaml
You use it by referring to the main YAML scene file (the one that calls all the others).
TRON2.0 was a trip of innovative concepts and ideas that we took with Geraldine. It was as much fun as it was aesthetically and technically challenging. Let us know how you use it!