Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to invert raster-colors #5468

Open
dktue opened this issue Feb 5, 2025 · 2 comments
Open

Add option to invert raster-colors #5468

dktue opened this issue Feb 5, 2025 · 2 comments
Labels
enhancement New feature or request PR is more than welcomed Extra attention is needed

Comments

@dktue
Copy link

dktue commented Feb 5, 2025

There are already very good options to manipulate raster-colors, like raster-saturation, raster-hue-rotate, raster-contrast and even more.

But in my option there's one missing: raster-invert that should work exactly like the css-filter invert.

Image
Image

@dktue
Copy link
Author

dktue commented Feb 5, 2025

I already tried to implement this, but I failed. Here's my (not working) minimum example:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="https://unpkg.com/maplibre-gl@5.0.1/dist/maplibre-gl.js"></script>
    <link href="https://unpkg.com/maplibre-gl@5.0.1/dist/maplibre-gl.css" rel="stylesheet" />
    <style>
        body { margin: 0; padding: 0; }
        #map { position: absolute; top: 0; bottom: 0; left: 0; right: 0; }
    </style>
</head>
<body>
    <div id="map"></div>
    <script>
        const map = new maplibregl.Map({
            container: 'map',
            center: [0, 0],
            zoom: 2,
            style: {
                version: 8,
                sources: {
                    'osm-tiles': {
                        type: 'raster',
                        tiles: ['https://tile.openstreetmap.org/{z}/{x}/{y}.png'],
                        tileSize: 256,
                        attribution: '© OpenStreetMap contributors'
                    }
                },
                layers: [{
                    id: 'osm-tiles-layer',
                    type: 'raster',
                    source: 'osm-tiles',
                    paint: {
                        'raster-fade-duration': 0
                    }
                }]
            }
        });

        map.on('load', () => {
            map.addLayer({
                id: 'custom-shader-layer',
                type: 'custom',
                renderingMode: '2d',
                onAdd: function(map, gl) {
                    const vertexSource = `
                        attribute vec2 a_pos;
                        varying vec2 v_texcoord;
                        void main() {
                            gl_Position = vec4(a_pos, 0.0, 1.0);
                            v_texcoord = (a_pos + 1.0) / 2.0;
                        }
                    `;
                    const fragmentSource = `
                        precision mediump float;
                        uniform sampler2D u_texture;
                        varying vec2 v_texcoord;
                        void main() {
                            vec4 color = texture2D(u_texture, v_texcoord);
                            gl_FragColor = vec4(1.0 - color.r, 1.0 - color.g, 1.0 - color.b, color.a);
                        }
                    `;
                    this.program = gl.createProgram();
                    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
                    gl.shaderSource(vertexShader, vertexSource);
                    gl.compileShader(vertexShader);
                    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
                    gl.shaderSource(fragmentShader, fragmentSource);
                    gl.compileShader(fragmentShader);
                    gl.attachShader(this.program, vertexShader);
                    gl.attachShader(this.program, fragmentShader);
                    gl.linkProgram(this.program);
                },
                render: function(gl, matrix) {
                    gl.useProgram(this.program);
                    gl.bindTexture(gl.TEXTURE_2D, map.painter.context.activeTexture.texture);
                    gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
                }
            });
        });
    </script>
</body>
</html>

@HarelM
Copy link
Collaborator

HarelM commented Feb 6, 2025

You can probably do it using addProtocol, get the raster image and apply the invert manipulation on it.
If this is something you would like to push from the spec perspective, I would advise to open an issue in the maplibre-style-spec repo.
When opening such an issue, please try and define what will happen if multiple properties are used and not just the invert itself.
Thanks!

@HarelM HarelM added enhancement New feature or request PR is more than welcomed Extra attention is needed labels Feb 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request PR is more than welcomed Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants