leaflet.glmarkers
v1.1.0
Published
GL markers with custom shaders for your LeafletJS maps
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 Promises. 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.GLMarkers 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 theaCRSCoordsinto clipspace coordinates)uPixelSize(to convert pixels into clipspace coordinate deltas)uNow(time in milliseconds elapsed since the webpage was loaded)uTexture0throughuTexture7(up to 8 textures, as per thetexturesoption when theGLMarkerGroupwas 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.
