leaflet.glmarkers
v1.1.0
Published
GL markers with custom shaders for your LeafletJS maps
Downloads
124
Readme
Leaflet.GLMarkers
A LeafletJS plugin to create markers with WebGL shaders.
Demo
There is an interactive demo! That demo uses some predefined data and one predefined texture, and lets you play with the shaders.
Compatibility
Leaflet 1.0.3 (or newer), and a web browser that supports both WebGL and ES6 Promise
s. You can also use a Promise
polyfill for IE11.
Usage
Include Leaflet and Leaflet.GLMarkers in your HTML:
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"
integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ=="
crossorigin=""/>
<script src="https://unpkg.com/[email protected]/dist/leaflet-src.js"
integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA=="
crossorigin=""></script>
<script src='https://unpkg.com/leaflet.glmarkers@latest/dist/Leaflet.GLMarkers.js'></script>
(Alternatively, fetch a local copy of Leaflet and Leaflet.GLMarkers with npm install --save leaflet; npm install --save leaflet.glmarkers
or yarn add leaflet; yarn add leaflet.glmarkers
)
Then, write some GLSL shader code, and have it as a Javascript string. See the interactive demo for some code patterns you can copy-paste.
Initialize a L.GLMarkerGroup
like so:
var glMarkers = new L.GLMarkerGroup({
// The "attributes" option lets you write "attribute float megacity",
// "attribute float rank_min", etc in your vertex shader.
// These attributes will be populated with the values in each GLMarker.
attributes: ['megacity', 'rank_min', 'rank_max', 'labelrank', 'adm0cap'],
// The "texture" option lets you use up to 8 images as textures.
// In this example, we'll have an image of a kitten in the first
// texture, which has to be referred to as "uniform Sampler2D uTexture0"
// in the fragment shader.
textures: ['http://placekitten.com/g/128/128'],
// And the GLMarkerGroup needs the vertex and fragment shaders
// code as strigns.
vertexShader: vertexCode,
fragmentShader: fragCode
}).addTo(map);
And lastly, add some L.GLMarker
s to your .GLMarkerGroup
:
glMarkers.addMarker( new L.GLMarker(
[latitude, longitude],
{ megacity: 0, labelrank: 5, adm0cap: 1 }
) );
It's recommended that you read some "vanilla" WebGL tutorials and resources, such as https://webglfundamentals.org/ and http://thebookofshaders.com/ . Those will explain basic WebGL concepts such as attributes, varyings and uniforms.
A L.GLMarkerGroup
will create four vertices per L.GLMarker
(in two triangles).
Each vertex for a GLMarker
will have the same attributes aCRSCoords
and aLatLngCoords
, plus an attribute called aExtrudeCoords
which is different for each
of the four vertices (with respective values of [-1, -1]
, [-1, +1]
, [+1, -1]
, and [+1, +1]
.
Besides those attributes, you can specify custom attributes during the instantiation
of your GLMarkerGroup
, as seen above.
The following uniforms are defined:
uTransformMatrix
(to convert theaCRSCoords
into clipspace coordinates)uPixelSize
(to convert pixels into clipspace coordinate deltas)uNow
(time in milliseconds elapsed since the webpage was loaded)uTexture0
throughuTexture7
(up to 8 textures, as per thetextures
option when theGLMarkerGroup
was instantiated)
It's the responsability of your vertex shader to put those attributes and uniforms
to good use. See some common patterns in the interactive demo. The file demo/deml.html
shows a minimal Leaflet map and GLMarkerGroup.
Motivation
This is @xavijam's fault, because he launched a coding challenge and I thought it would be a nice pasttime.
This also follows the work done in Leaflet.TileLayer.GL: do the heavy lifting of initializing WebGL and creating triangles with the proper CRS coordinates, while letting the user add points and style the shaders. This should let more people use WebGL to do cartographic stuff, without having to rely on more complex frameworks.
Legalese
"THE BEER-WARE LICENSE": [email protected] wrote this file. As long as you retain this notice you can do whatever you want with this stuff. If we meet some day, and you think this stuff is worth it, you can buy me a beer in return.