Skip to content

Instantly share code, notes, and snippets.

@Sumbera
Last active September 11, 2025 12:45
Show Gist options
  • Save Sumbera/c6fed35c377a46ff74c3 to your computer and use it in GitHub Desktop.
Save Sumbera/c6fed35c377a46ff74c3 to your computer and use it in GitHub Desktop.

Revisions

  1. Sumbera revised this gist Oct 6, 2022. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -108,7 +108,7 @@
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
    <script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
    <script src="http://www.sumbera.com/gist/js/leaflet/canvas/L.CanvasOverlay.js"></script>
    <script src="http://www.sumbera.com/gist/86T.json" charset="utf-8"></script>
    <script src="http://www.sumbera.com/gist/86T.js" charset="utf-8"></script>


    <script>
  2. Sumbera revised this gist Aug 16, 2015. 1 changed file with 2 additions and 2 deletions.
    4 changes: 2 additions & 2 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -1,4 +1,4 @@
    Leaflet and WebGL sample rendering 80T points
    for more info read blog post : http://blog.sumbera.com/2014/06/08/leaflet-webgl-many-points-rendering/
    for more info read [blog post](http://blog.sumbera.com/2014/06/08/leaflet-webgl-many-points-rendering/)

    inspired by http://build-failed.blogspot.cz/2013/02/displaying-webgl-data-on-google-maps.html and by very nice WebGL tutorial here: http://greggman.github.io/webgl-fundamentals/webgl/lessons/webgl-how-it-works.html
    inspired by [this](http://build-failed.blogspot.cz/2013/02/displaying-webgl-data-on-google-maps.html) and by very nice WebGL tutorial [here](http://greggman.github.io/webgl-fundamentals/webgl/lessons/webgl-how-it-works.html)
  3. Sumbera revised this gist Jul 24, 2014. 1 changed file with 73 additions and 79 deletions.
    152 changes: 73 additions & 79 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -42,65 +42,65 @@
    </script>
    <!-- fragment shader -->


    <script id="fshader" type="x-shader/x-fragment">
    precision mediump float;
    varying vec4 v_color;

    void main() {
    float border = 0.05;
    float radius = 0.5;
    vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0);
    vec4 color1 = vec4(v_color[0], v_color[1], v_color[2], 0.2);

    vec2 m = gl_PointCoord.xy - vec2(0.5, 0.5);
    float dist = radius - sqrt(m.x * m.x + m.y * m.y);

    float t = 0.0;
    if (dist > border)
    t = 1.0;
    else if (dist > 0.0)
    t = dist / border;

    // float centerDist = length(gl_PointCoord - 0.5);
    // works for overlapping circles if blending is enabled


    gl_FragColor = mix(color0, color1, t);
    /*
    // -- another way for circle
    float centerDist = length(gl_PointCoord - 0.5);
    float radius = 0.5;
    // works for overlapping circles if blending is enabled
    gl_FragColor = vec4(v_color[0], v_color[1], v_color[2], 0.2 * step(centerDist, radius));
    */
    /*
    // simple circles
    float d = distance (gl_PointCoord, vec2(0.5,0.5));
    if (d < 0.5 ){
    gl_FragColor =vec4(v_color[0], v_color[1], v_color[2], 0.2);
    }
    else{
    discard;
    }
    */

    // -- squares
    //gl_FragColor = v_color;
    //gl_FragColor =vec4(v_color[0], v_color[1], v_color[2], 0.2); // v_color;

    }

    </script>


    <script id="fshader" type="x-shader/x-fragment">
    precision mediump float;
    varying vec4 v_color;

    void main() {

    float border = 0.05;
    float radius = 0.5;
    vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0);
    vec4 color1 = vec4(v_color[0], v_color[1], v_color[2], 0.2);

    vec2 m = gl_PointCoord.xy - vec2(0.5, 0.5);
    float dist = radius - sqrt(m.x * m.x + m.y * m.y);

    float t = 0.0;
    if (dist > border)
    t = 1.0;
    else if (dist > 0.0)
    t = dist / border;

    // float centerDist = length(gl_PointCoord - 0.5);
    // works for overlapping circles if blending is enabled



    gl_FragColor = mix(color0, color1, t);





    /*
    // -- another way for circle
    float centerDist = length(gl_PointCoord - 0.5);
    float radius = 0.5;
    // works for overlapping circles if blending is enabled
    gl_FragColor = vec4(v_color[0], v_color[1], v_color[2], 0.2 * step(centerDist, radius));
    */

    /*
    // simple circles
    float d = distance (gl_PointCoord, vec2(0.5,0.5));
    if (d < 0.5 ){
    gl_FragColor =vec4(v_color[0], v_color[1], v_color[2], 0.2);
    }
    else{
    discard;
    }
    */

    // -- squares
    //gl_FragColor = v_color;
    //gl_FragColor =vec4(v_color[0], v_color[1], v_color[2], 0.2); // v_color;

    }

    </script>

    </head>
    <body>
    @@ -127,7 +127,7 @@
    glLayer.canvas.width = canvas.clientWidth;
    glLayer.canvas.height = canvas.clientHeight;


    var gl = canvas.getContext('experimental-webgl', { antialias: true });

    var pixelsToWebGLMatrix = new Float32Array(16);
    @@ -168,34 +168,28 @@
    gl.uniformMatrix4fv(u_matLoc, false, pixelsToWebGLMatrix);



    var colorBuffer = gl.createBuffer();
    var vertBuffer = gl.createBuffer();

    // -- data
    var colors = [];
    var verts = [];

    data.map(function (d, i) {
    pixel = LatLongToPixelXY(d[0], d[1]);
    //pixel = latlonToPixels(d[0], d[1]);
    //colors.push(0.5, 0.8, 0.2);
    colors.push(Math.random(), Math.random(), Math.random());
    verts.push(pixel.x, pixel.y);
    pixel = LatLongToPixelXY(d[0], d[1]);
    //-- 2 coord, 3 rgb colors interleaved buffer
    verts.push(pixel.x, pixel.y, Math.random(), Math.random(), Math.random());
    });

    var numPoints = colors.length / 3;
    var numPoints = data.length ;

    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

    gl.vertexAttribPointer(colorLoc, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(colorLoc);
    var vertBuffer = gl.createBuffer();
    var vertArray = new Float32Array(verts);
    var fsize = vertArray.BYTES_PER_ELEMENT;

    gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);
    gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, false, 0, 0);
    gl.bufferData(gl.ARRAY_BUFFER, vertArray, gl.STATIC_DRAW);
    gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, false,fsize*5,0);
    gl.enableVertexAttribArray(vertLoc);
    // -- offset for color buffer
    gl.vertexAttribPointer(colorLoc, 3, gl.FLOAT, false, fsize*5, fsize*2);
    gl.enableVertexAttribArray(colorLoc);

    glLayer.redraw();

    @@ -298,4 +292,4 @@

    </script>
    </body>
    </html>
    </html>
  4. Sumbera revised this gist Jun 10, 2014. 1 changed file with 4 additions and 1 deletion.
    5 changes: 4 additions & 1 deletion README.md
    Original file line number Diff line number Diff line change
    @@ -1 +1,4 @@
    Leaflet and WebGL sample rendering 80T points, inspired by http://build-failed.blogspot.cz/2013/02/displaying-webgl-data-on-google-maps.html and by very nice WebGL tutorial here: http://greggman.github.io/webgl-fundamentals/webgl/lessons/webgl-how-it-works.html
    Leaflet and WebGL sample rendering 80T points
    for more info read blog post : http://blog.sumbera.com/2014/06/08/leaflet-webgl-many-points-rendering/

    inspired by http://build-failed.blogspot.cz/2013/02/displaying-webgl-data-on-google-maps.html and by very nice WebGL tutorial here: http://greggman.github.io/webgl-fundamentals/webgl/lessons/webgl-how-it-works.html
  5. Sumbera revised this gist Jun 9, 2014. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion index.html
    Original file line number Diff line number Diff line change
    @@ -113,7 +113,7 @@

    <script>

    var leafletMap = L.map('map').setView([50.00, 14.44], 12);
    var leafletMap = L.map('map').setView([50.00, 14.44], 8);
    L.tileLayer("http://{s}.sm.mapstack.stamen.com/(toner-background,$fff[difference],$fff[@23],$fff[hsl-saturation@20],toner-lines[destination-in])/{z}/{x}/{y}.png")
    //L.tileLayer("http://{s}.sm.mapstack.stamen.com/(toner-lite,$fff[difference],$fff[@23],$fff[hsl-saturation@20])/{z}/{x}/{y}.png")
    .addTo(leafletMap);
  6. Sumbera revised this gist Jun 9, 2014. 1 changed file with 68 additions and 15 deletions.
    83 changes: 68 additions & 15 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -35,20 +35,72 @@
    // multiply each vertex by a matrix.
    gl_Position = u_matrix * a_vertex;


    // pass the color to the fragment shader
    v_color = a_color;
    }
    </script>
    <!-- fragment shader -->
    <script id="fshader" type="x-shader/x-fragment">
    precision mediump float;
    varying vec4 v_color;
    void main() {
    //gl_FragColor = v_color;

    gl_FragColor =vec4(v_color[0], v_color[1], v_color[2], 0.2); // v_color;
    }
    </script>



    <script id="fshader" type="x-shader/x-fragment">
    precision mediump float;
    varying vec4 v_color;

    void main() {

    float border = 0.05;
    float radius = 0.5;
    vec4 color0 = vec4(0.0, 0.0, 0.0, 0.0);
    vec4 color1 = vec4(v_color[0], v_color[1], v_color[2], 0.2);

    vec2 m = gl_PointCoord.xy - vec2(0.5, 0.5);
    float dist = radius - sqrt(m.x * m.x + m.y * m.y);

    float t = 0.0;
    if (dist > border)
    t = 1.0;
    else if (dist > 0.0)
    t = dist / border;

    // float centerDist = length(gl_PointCoord - 0.5);
    // works for overlapping circles if blending is enabled



    gl_FragColor = mix(color0, color1, t);





    /*
    // -- another way for circle
    float centerDist = length(gl_PointCoord - 0.5);
    float radius = 0.5;
    // works for overlapping circles if blending is enabled
    gl_FragColor = vec4(v_color[0], v_color[1], v_color[2], 0.2 * step(centerDist, radius));
    */

    /*
    // simple circles
    float d = distance (gl_PointCoord, vec2(0.5,0.5));
    if (d < 0.5 ){
    gl_FragColor =vec4(v_color[0], v_color[1], v_color[2], 0.2);
    }
    else{
    discard;
    }
    */

    // -- squares
    //gl_FragColor = v_color;
    //gl_FragColor =vec4(v_color[0], v_color[1], v_color[2], 0.2); // v_color;

    }

    </script>

    </head>
    <body>
    @@ -61,7 +113,7 @@

    <script>

    var leafletMap = L.map('map').setView([50.00, 14.44], 8);
    var leafletMap = L.map('map').setView([50.00, 14.44], 12);
    L.tileLayer("http://{s}.sm.mapstack.stamen.com/(toner-background,$fff[difference],$fff[@23],$fff[hsl-saturation@20],toner-lines[destination-in])/{z}/{x}/{y}.png")
    //L.tileLayer("http://{s}.sm.mapstack.stamen.com/(toner-lite,$fff[difference],$fff[@23],$fff[hsl-saturation@20])/{z}/{x}/{y}.png")
    .addTo(leafletMap);
    @@ -75,8 +127,8 @@
    glLayer.canvas.width = canvas.clientWidth;
    glLayer.canvas.height = canvas.clientHeight;


    var gl = canvas.getContext('experimental-webgl');
    var gl = canvas.getContext('experimental-webgl', { antialias: true });

    var pixelsToWebGLMatrix = new Float32Array(16);
    var mapMatrix = new Float32Array(16);
    @@ -98,9 +150,10 @@
    gl.useProgram(program);


    gl.blendFunc(gl.SRC_ALPHA, gl.ONE);

    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.enable(gl.BLEND);
    gl.disable(gl.DEPTH_TEST);
    // gl.disable(gl.DEPTH_TEST);
    // ----------------------------
    // look up the locations for the inputs to our shaders.
    var u_matLoc = gl.getUniformLocation(program, "u_matrix");
    @@ -158,7 +211,7 @@



    var pointSize = Math.max(leafletMap.getZoom() - 6.0, 1.0);
    var pointSize = Math.max(leafletMap.getZoom() - 4.0, 1.0);
    gl.vertexAttrib1f(gl.aPointSize, pointSize);

    // -- set base matrix to translate canvas pixel coordinates -> webgl coordinates
  7. Sumbera revised this gist Jun 9, 2014. 1 changed file with 30 additions and 16 deletions.
    46 changes: 30 additions & 16 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -5,7 +5,6 @@
    <meta charset="utf-8">

    <style>

    html, body {
    height: 100%;
    padding: 0;
    @@ -25,12 +24,13 @@
    <script id="vshader" type="x-shader/x-vertex">
    uniform mat4 u_matrix;
    attribute vec4 a_vertex;
    attribute float a_pointSize;
    attribute vec4 a_color;
    varying vec4 v_color;

    void main() {
    // Set the size of the point
    gl_PointSize = 3.0;
    gl_PointSize = a_pointSize;

    // multiply each vertex by a matrix.
    gl_Position = u_matrix * a_vertex;
    @@ -44,7 +44,9 @@
    precision mediump float;
    varying vec4 v_color;
    void main() {
    gl_FragColor = v_color;
    //gl_FragColor = v_color;

    gl_FragColor =vec4(v_color[0], v_color[1], v_color[2], 0.2); // v_color;
    }
    </script>

    @@ -59,8 +61,9 @@

    <script>

    var leafletMap = L.map('map').setView([50.00, 14.44], 10);
    L.tileLayer("http://{s}.sm.mapstack.stamen.com/(toner-lite,$fff[difference],$fff[@23],$fff[hsl-saturation@20])/{z}/{x}/{y}.png")
    var leafletMap = L.map('map').setView([50.00, 14.44], 8);
    L.tileLayer("http://{s}.sm.mapstack.stamen.com/(toner-background,$fff[difference],$fff[@23],$fff[hsl-saturation@20],toner-lines[destination-in])/{z}/{x}/{y}.png")
    //L.tileLayer("http://{s}.sm.mapstack.stamen.com/(toner-lite,$fff[difference],$fff[@23],$fff[hsl-saturation@20])/{z}/{x}/{y}.png")
    .addTo(leafletMap);


    @@ -94,19 +97,24 @@
    gl.linkProgram(program);
    gl.useProgram(program);


    gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
    gl.enable(gl.BLEND);
    gl.disable(gl.DEPTH_TEST);
    // ----------------------------
    // look up the locations for the inputs to our shaders.
    var u_matLoc = gl.getUniformLocation(program, "u_matrix");
    var colorLoc = gl.getAttribLocation(program, "a_color");
    var vertLoc = gl.getAttribLocation(program, "a_vertex");
    gl.aPointSize = gl.getAttribLocation(program, "a_pointSize");
    // Set the matrix to some that makes 1 unit 1 pixel.

    pixelsToWebGLMatrix.set([2 / canvas.width, 0, 0, 0, 0, -2 / canvas.height, 0, 0, 0, 0, 0, 0, -1, 1, 0, 1]);
    gl.viewport(0, 0, canvas.width, canvas.height);

    gl.uniformMatrix4fv(u_matLoc, false, pixelsToWebGLMatrix);



    var colorBuffer = gl.createBuffer();
    var vertBuffer = gl.createBuffer();
    @@ -118,9 +126,9 @@
    data.map(function (d, i) {
    pixel = LatLongToPixelXY(d[0], d[1]);
    //pixel = latlonToPixels(d[0], d[1]);
    colors.push(0.5, 0.8, 0.2);
    //colors.push(Math.random(), Math.random(), Math.random());
    verts.push(pixel.x, pixel.y);
    //colors.push(0.5, 0.8, 0.2);
    colors.push(Math.random(), Math.random(), Math.random());
    verts.push(pixel.x, pixel.y);
    });

    var numPoints = colors.length / 3;
    @@ -141,20 +149,26 @@

    function drawingOnCanvas(canvasOverlay, params) {
    if (gl == null) return;
    // -- this is important for any changes in canvas size

    gl.clear(gl.COLOR_BUFFER_BIT);


    pixelsToWebGLMatrix.set([2 / canvas.width, 0, 0, 0, 0, -2 / canvas.height, 0, 0, 0, 0, 0, 0, -1, 1, 0, 1]);
    gl.viewport(0, 0, canvas.width, canvas.height);

    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.clear(gl.COLOR_BUFFER_BIT);


    var pointSize = Math.max(leafletMap.getZoom() - 6.0, 1.0);
    gl.vertexAttrib1f(gl.aPointSize, pointSize);

    // -- set base matrix to translate canvas pixel coordinates -> webgl coordinates
    mapMatrix.set(pixelsToWebGLMatrix);

    var bounds = leafletMap.getBounds();
    var topLeft = new L.LatLng(bounds.getNorth(), bounds.getWest());
    var offset = LatLongToPixelXY(topLeft.lat, topLeft.lng);

    // -- Scale to current zoom
    // -- Scale to current zoom
    var scale = Math.pow(2, leafletMap.getZoom());
    scaleMatrix(mapMatrix, scale, scale);

    @@ -170,7 +184,7 @@
    function randomInt(range) {
    return Math.floor(Math.random() * range);
    }

    /*
    function latlonToPixels(lat, lon) {
    initialResolution = 2 * Math.PI * 6378137 / 256, // at zoomlevel 0
    @@ -182,7 +196,7 @@
    my = my * originShift / 180;
    // -- to pixels at zoom level 0
    // -- to pixels at zoom level 0
    var res = initialResolution;
    x = (mx + originShift) / res,
    @@ -228,7 +242,7 @@
    matrix[7] *= scaleY;
    }


    </script>
    </body>
    </html>
  8. Sumbera created this gist Jun 8, 2014.
    1 change: 1 addition & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1 @@
    Leaflet and WebGL sample rendering 80T points, inspired by http://build-failed.blogspot.cz/2013/02/displaying-webgl-data-on-google-maps.html and by very nice WebGL tutorial here: http://greggman.github.io/webgl-fundamentals/webgl/lessons/webgl-how-it-works.html
    234 changes: 234 additions & 0 deletions index.html
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,234 @@
    <!doctype html>
    <html>
    <head>
    <title>Many Points with leaflet WebGL</title>
    <meta charset="utf-8">

    <style>

    html, body {
    height: 100%;
    padding: 0;
    margin: 0;
    background: rgb(14, 21, 30);
    height: 100%;
    }

    #map {
    position: absolute;
    height: 100%;
    width: 100%;
    background-color: #333;
    }
    </style>
    <!-- vertex shader -->
    <script id="vshader" type="x-shader/x-vertex">
    uniform mat4 u_matrix;
    attribute vec4 a_vertex;
    attribute vec4 a_color;
    varying vec4 v_color;

    void main() {
    // Set the size of the point
    gl_PointSize = 3.0;

    // multiply each vertex by a matrix.
    gl_Position = u_matrix * a_vertex;

    // pass the color to the fragment shader
    v_color = a_color;
    }
    </script>
    <!-- fragment shader -->
    <script id="fshader" type="x-shader/x-fragment">
    precision mediump float;
    varying vec4 v_color;
    void main() {
    gl_FragColor = v_color;
    }
    </script>

    </head>
    <body>
    <div id="map"></div>
    <link rel="stylesheet" href="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.css" />
    <script src="http://cdn.leafletjs.com/leaflet-0.7.2/leaflet.js"></script>
    <script src="http://www.sumbera.com/gist/js/leaflet/canvas/L.CanvasOverlay.js"></script>
    <script src="http://www.sumbera.com/gist/86T.json" charset="utf-8"></script>


    <script>

    var leafletMap = L.map('map').setView([50.00, 14.44], 10);
    L.tileLayer("http://{s}.sm.mapstack.stamen.com/(toner-lite,$fff[difference],$fff[@23],$fff[hsl-saturation@20])/{z}/{x}/{y}.png")
    .addTo(leafletMap);


    var glLayer = L.canvasOverlay()
    .drawing(drawingOnCanvas)
    .addTo(leafletMap);
    var canvas = glLayer.canvas();

    glLayer.canvas.width = canvas.clientWidth;
    glLayer.canvas.height = canvas.clientHeight;


    var gl = canvas.getContext('experimental-webgl');

    var pixelsToWebGLMatrix = new Float32Array(16);
    var mapMatrix = new Float32Array(16);

    // -- WebGl setup
    var vertexShader = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(vertexShader, document.getElementById('vshader').text);
    gl.compileShader(vertexShader);

    var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(fragmentShader, document.getElementById('fshader').text);
    gl.compileShader(fragmentShader);

    // link shaders to create our program
    var program = gl.createProgram();
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    gl.useProgram(program);

    // ----------------------------
    // look up the locations for the inputs to our shaders.
    var u_matLoc = gl.getUniformLocation(program, "u_matrix");
    var colorLoc = gl.getAttribLocation(program, "a_color");
    var vertLoc = gl.getAttribLocation(program, "a_vertex");
    // Set the matrix to some that makes 1 unit 1 pixel.

    pixelsToWebGLMatrix.set([2 / canvas.width, 0, 0, 0, 0, -2 / canvas.height, 0, 0, 0, 0, 0, 0, -1, 1, 0, 1]);
    gl.viewport(0, 0, canvas.width, canvas.height);

    gl.uniformMatrix4fv(u_matLoc, false, pixelsToWebGLMatrix);



    var colorBuffer = gl.createBuffer();
    var vertBuffer = gl.createBuffer();

    // -- data
    var colors = [];
    var verts = [];

    data.map(function (d, i) {
    pixel = LatLongToPixelXY(d[0], d[1]);
    //pixel = latlonToPixels(d[0], d[1]);
    colors.push(0.5, 0.8, 0.2);
    //colors.push(Math.random(), Math.random(), Math.random());
    verts.push(pixel.x, pixel.y);
    });

    var numPoints = colors.length / 3;

    gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);

    gl.vertexAttribPointer(colorLoc, 3, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(colorLoc);

    gl.bindBuffer(gl.ARRAY_BUFFER, vertBuffer);
    gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verts), gl.STATIC_DRAW);
    gl.vertexAttribPointer(vertLoc, 2, gl.FLOAT, false, 0, 0);
    gl.enableVertexAttribArray(vertLoc);

    glLayer.redraw();


    function drawingOnCanvas(canvasOverlay, params) {
    if (gl == null) return;
    // -- this is important for any changes in canvas size
    pixelsToWebGLMatrix.set([2 / canvas.width, 0, 0, 0, 0, -2 / canvas.height, 0, 0, 0, 0, 0, 0, -1, 1, 0, 1]);
    gl.viewport(0, 0, canvas.width, canvas.height);

    gl.viewport(0, 0, canvas.width, canvas.height);
    gl.clear(gl.COLOR_BUFFER_BIT);
    // -- set base matrix to translate canvas pixel coordinates -> webgl coordinates
    mapMatrix.set(pixelsToWebGLMatrix);

    var bounds = leafletMap.getBounds();
    var topLeft = new L.LatLng(bounds.getNorth(), bounds.getWest());
    var offset = LatLongToPixelXY(topLeft.lat, topLeft.lng);

    // -- Scale to current zoom
    var scale = Math.pow(2, leafletMap.getZoom());
    scaleMatrix(mapMatrix, scale, scale);

    translateMatrix(mapMatrix, -offset.x, -offset.y);

    // -- attach matrix value to 'mapMatrix' uniform in shader
    gl.uniformMatrix4fv(u_matLoc, false, mapMatrix);
    gl.drawArrays(gl.POINTS, 0, numPoints);

    }

    // Returns a random integer from 0 to range - 1.
    function randomInt(range) {
    return Math.floor(Math.random() * range);
    }

    /*
    function latlonToPixels(lat, lon) {
    initialResolution = 2 * Math.PI * 6378137 / 256, // at zoomlevel 0
    originShift = 2 * Math.PI * 6378137 / 2;
    // -- to meters
    var mx = lon * originShift / 180;
    var my = Math.log(Math.tan((90 + lat) * Math.PI / 360)) / (Math.PI / 180);
    my = my * originShift / 180;
    // -- to pixels at zoom level 0
    var res = initialResolution;
    x = (mx + originShift) / res,
    y = (my + originShift) / res;
    return { x: x, y: 256- y };
    }
    */
    // -- converts latlon to pixels at zoom level 0 (for 256x256 tile size) , inverts y coord )
    // -- source : http://build-failed.blogspot.cz/2013/02/displaying-webgl-data-on-google-maps.html

    function LatLongToPixelXY(latitude, longitude) {
    var pi_180 = Math.PI / 180.0;
    var pi_4 = Math.PI * 4;
    var sinLatitude = Math.sin(latitude * pi_180);
    var pixelY = (0.5 - Math.log((1 + sinLatitude) / (1 - sinLatitude)) / (pi_4)) * 256;
    var pixelX = ((longitude + 180) / 360) * 256;

    var pixel = { x: pixelX, y: pixelY };

    return pixel;
    }

    function translateMatrix(matrix, tx, ty) {
    // translation is in last column of matrix
    matrix[12] += matrix[0] * tx + matrix[4] * ty;
    matrix[13] += matrix[1] * tx + matrix[5] * ty;
    matrix[14] += matrix[2] * tx + matrix[6] * ty;
    matrix[15] += matrix[3] * tx + matrix[7] * ty;
    }

    function scaleMatrix(matrix, scaleX, scaleY) {
    // scaling x and y, which is just scaling first two columns of matrix
    matrix[0] *= scaleX;
    matrix[1] *= scaleX;
    matrix[2] *= scaleX;
    matrix[3] *= scaleX;

    matrix[4] *= scaleY;
    matrix[5] *= scaleY;
    matrix[6] *= scaleY;
    matrix[7] *= scaleY;
    }


    </script>
    </body>
    </html>