Last active
September 11, 2025 12:45
-
-
Save Sumbera/c6fed35c377a46ff74c3 to your computer and use it in GitHub Desktop.
Revisions
-
Sumbera revised this gist
Oct 6, 2022 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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.js" charset="utf-8"></script> <script> -
Sumbera revised this gist
Aug 16, 2015 . 1 changed file with 2 additions and 2 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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/) 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) -
Sumbera revised this gist
Jul 24, 2014 . 1 changed file with 73 additions and 79 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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> </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); // -- data var verts = []; data.map(function (d, i) { 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 = data.length ; 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, 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> -
Sumbera revised this gist
Jun 10, 2014 . 1 changed file with 4 additions and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1 +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/ 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 -
Sumbera revised this gist
Jun 9, 2014 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -113,7 +113,7 @@ <script> 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); -
Sumbera revised this gist
Jun 9, 2014 . 1 changed file with 68 additions and 15 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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() { 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], 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', { 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_MINUS_SRC_ALPHA); 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"); @@ -158,7 +211,7 @@ 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 -
Sumbera revised this gist
Jun 9, 2014 . 1 changed file with 30 additions and 16 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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 = 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 =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], 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); }); var numPoints = colors.length / 3; @@ -141,20 +149,26 @@ function drawingOnCanvas(canvasOverlay, params) { if (gl == null) return; 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); 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 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 var res = initialResolution; x = (mx + originShift) / res, @@ -228,7 +242,7 @@ matrix[7] *= scaleY; } </script> </body> </html> -
Sumbera created this gist
Jun 8, 2014 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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 This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal 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>