This is the documentation of version 1.0.0-rc.4. Go to the latest version, 1.0.0-rc.5.

Custom GPU passes

addPass runs your own full-screen fragment shader inside the map effects plugin's GPU chain. Every effect drawn over the chain (bloom, grade, fog, edge blur, tint, vignette) then works on your picture. Use it for a stylisation, such as a watercolour, a posterise, a split tone or a colour lookup. addLayer puts a 2D canvas of your own between those effects, such as a paper texture or film grain. The demo below paints the map in watercolour on a paper texture, lets bloom, a contrast grade and a vignette work on the painting, and leaves a margin of bare paper around it:

Your own GPU passes

effects.addPass({
    id: 'posterise',
    fragment: `uniform float uLevels;
        void main() {
            vec4 colour = texture(uSource, vUv);
            fragColor = vec4(floor(colour.rgb * uLevels) / uLevels, colour.a);
        }`,
    uniforms: { uLevels: 5 },
});

effects.removePass('posterise');

Textures and mip levels

A pass can sample textures of its own besides uSource, such as a paper grain, a noise tile or a colour lookup table. To give it one, declare a uniform sampler2D and pass the image under the same name in textures:

const paper = new Image();
paper.src = 'paper.png';

effects.addPass({
    id: 'paper-tone',
    fragment: `uniform sampler2D uPaper;
        uniform vec3 uTone;
        void main() {
            vec4 colour = texture(uSource, vUv);
            float grain = texture(uPaper, gl_FragCoord.xy / vec2(textureSize(uPaper, 0))).r;
            fragColor = vec4(colour.rgb * mix(uTone, vec3(1.0), grain), colour.a);
        }`,
    uniforms: { uTone: [0.95, 0.9, 0.8] },
    textures: { uPaper: paper },
});

Layers between the effects

addLayer draws a 2D canvas layer of your own at a place in the overlay stack, and capture() draws it in the same place. Use it for a paper texture, film grain, scanlines or a frame that some effects should work on and others not. This one lays the paper image from above over the map, under the tint and the vignette:

effects.addLayer({
    id: 'paper',
    placement: 'after-edgeBlur',
    draw: (context, { width, height }) => {
        context.globalAlpha = 0.25;
        context.fillStyle = context.createPattern(paper, 'repeat') ?? 'transparent';
        context.fillRect(0, 0, width, height);
    },
});

effects.removeLayer('paper');

Related guides and examples

Related guides

Related examples