TileLayer用webgl渲染时, 你可以通过设置fragmentShader, 来替换默认的fragment shader.
precision mediump float;
uniform sampler2D u_image;
uniform float u_opacity;
varying vec2 v_texCoord;
void main() {
gl_FragColor = texture2D(u_image, v_texCoord) * u_opacity;
}
源代码中必须提供的几个GLSL变量: u_image
, u_opacity
, v_texCoord
.
你可以在shader中定义新的uniform变量, 并在图层的canvascreate事件中给它们赋值.
<!DOCTYPE html> <html> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title> - </title> <style type="text/css"> html,body{margin:0px;height:100%;width:100%} #map0{width:calc(50% - 2px);height:calc(100% - 2px);float:left;border:1px solid} #map1{width:calc(50% - 2px);height:calc(100% - 2px);float:right;border:1px solid} </style> <link rel="stylesheet" href="https://unpkg.com/maptalks/dist/maptalks.css"> <script type="text/javascript" src="https://unpkg.com/maptalks/dist/maptalks.min.js"></script> <body> <div id="map0"></div> <div id="map1"></div> <script> var tileLayer = new maptalks.TileLayer('carto',{ urlTemplate : 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', subdomains : ['a','b','c'], // fragment shader from webglfundamentals.org // https://webglfundamentals.org/webgl/lessons/webgl-image-processing.html fragmentShader: [ 'precision mediump float;' + 'uniform sampler2D u_image;' + 'uniform vec2 u_textureSize;' + 'uniform float u_kernel[9];' + 'uniform float u_opacity;' + 'uniform float u_kernelWeight;' + 'varying vec2 v_texCoord;' + 'void main() {' + 'vec2 onePixel = vec2(1.0, 1.0) / u_textureSize;' + 'vec4 colorSum =' + 'texture2D(u_image, v_texCoord + onePixel * vec2(-1, -1)) * u_kernel[0] +' + 'texture2D(u_image, v_texCoord + onePixel * vec2( 0, -1)) * u_kernel[1] +' + 'texture2D(u_image, v_texCoord + onePixel * vec2( 1, -1)) * u_kernel[2] +' + 'texture2D(u_image, v_texCoord + onePixel * vec2(-1, 0)) * u_kernel[3] +' + 'texture2D(u_image, v_texCoord + onePixel * vec2( 0, 0)) * u_kernel[4] +' + 'texture2D(u_image, v_texCoord + onePixel * vec2( 1, 0)) * u_kernel[5] +' + 'texture2D(u_image, v_texCoord + onePixel * vec2(-1, 1)) * u_kernel[6] +' + 'texture2D(u_image, v_texCoord + onePixel * vec2( 0, 1)) * u_kernel[7] +' + 'texture2D(u_image, v_texCoord + onePixel * vec2( 1, 1)) * u_kernel[8] ;' + 'gl_FragColor = vec4((colorSum / u_kernelWeight).rgb, 1) * u_opacity;' + '}' ].join('\n') }); tileLayer.on('canvascreate', function (e) { // set uniform values in shader var gl = e.gl; var program = gl.program; var textureSizeLocation = gl.getUniformLocation(program, 'u_textureSize'); var kernelLocation = gl.getUniformLocation(program, 'u_kernel[0]'); var kernelWeightLocation = gl.getUniformLocation(program, 'u_kernelWeight'); //kernels of sobelVertical in the original example var kernels = [ 1, 0, -1, 2, 0, -2, 1, 0, -1 ]; gl.uniform2f(textureSizeLocation, 256, 256); gl.uniform1fv(kernelLocation, new Float32Array(kernels)); gl.uniform1f(kernelWeightLocation, computeKernelWeight(kernels)); }); var map1 = new maptalks.Map('map1', { center: [-0.113049,51.498568], zoom: 4, attribution: { content: '© OpenStreetMap' }, baseLayer : tileLayer }); function computeKernelWeight(kernel) { var weight = kernel.reduce(function (prev, curr) { return prev + curr; }); return weight <= 0 ? 1 : weight; } // original var map0 = new maptalks.Map('map0', { center: [-0.113049,51.498568], zoom: 4, attribution: { content: '© OpenStreetMap' }, baseLayer : new maptalks.TileLayer('base',{ urlTemplate : 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', subdomains : ['a','b','c'] }) }); </script> </body> </html>