i am trying to ignore / skip rendering for pixels falls outside of given bounding box (outside of green border box) something like screenshot attached 
i tried different following methods from my understating nothing works,
in fragment shader unprojecting gl_FragCoord then comparing with south west, north east values returned by maplibregl.MercatorCoordinate.fromLngLat
calculating pixels for min/max latitudes using maplibre project then compared with fragment shader gl_FragCoord.xy
i highly appreciate your help
thank you
Sample testing code
<!DOCTYPE html>
<html lang="en">
<head>
<title>Add a custom style layer</title>
<meta property="og:description" content="Use a custom style layer to render custom WebGL content."/>
<meta charset='utf-8'>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel='stylesheet' href='https://unpkg.com/[email protected]/dist/maplibre-gl.css'/>
<script src='https://unpkg.com/[email protected]/dist/maplibre-gl.js'></script>
<style>
body {
margin: 0;
padding: 0;
}
html, body, #map {
height: 100%;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
function addBboxDebugLayer(map, bbox) {
map.addSource('bbox-debug', {
'type': 'geojson',
'data': {
'type': 'Feature',
'properties': {},
'geometry': {
'type': 'LineString',
'coordinates': [
[bbox.w, bbox.n],
[bbox.e, bbox.n],
[bbox.e, bbox.s],
[bbox.w, bbox.s],
[bbox.w, bbox.n],
]
}
}
});
map.addLayer({
'id': 'bbox-debug',
'type': 'line',
'source': 'bbox-debug',
'layout': {
// 'line-join': 'round',
// 'line-cap': 'round'
},
'paint': {
'line-color': '#00ff00',
'line-width': 1
}
});
}
const map = new maplibregl.Map({
container: 'map',
zoom: 3,
center: [53.33, 24.44],
style: 'https://demotiles.maplibre.org/style.json',
antialias: true, // create the gl context with MSAA antialiasing, so custom layers are antialiased
hash: true,
});
const MAX_BOUNDS = [
30, 8, // south west
80, 39 // north east
];
const boundsMin = maplibregl.MercatorCoordinate.fromLngLat({
lng: MAX_BOUNDS[0],
lat: MAX_BOUNDS[1]
});
const boundsMax = maplibregl.MercatorCoordinate.fromLngLat({
lng: MAX_BOUNDS[2],
lat: MAX_BOUNDS[3]
});
// create a custom style layer to implement the WebGL content
const highlightLayer = {
id: 'highlight',
type: 'custom',
// method called when the layer is added to the map
// Search for StyleImageInterface in https://maplibre.org/maplibre-gl-js/docs/API/
onAdd(map, gl) {
// create GLSL source for vertex shader
const vertexSource = `#version 300 es
uniform mat4 u_matrix;
in vec2 a_pos;
void main() {
gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0);
}`;
// create GLSL source for fragment shader
const fragmentSource = `#version 300 es
precision highp float;
uniform vec2 u_canvasSize;
uniform vec2 u_mapCenter;
uniform vec2 u_mapSize;
uniform mat4 u_matrix;
out vec4 fragColor;
void main() {
fragColor = vec4(gl_FragCoord.xy / u_canvasSize , 0.0, 1.);
}`;
// create a vertex shader
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexSource);
gl.compileShader(vertexShader);
// create a fragment shader
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentSource);
gl.compileShader(fragmentShader);
// link the two shaders into a WebGL program
this.program = gl.createProgram();
gl.attachShader(this.program, vertexShader);
gl.attachShader(this.program, fragmentShader);
gl.linkProgram(this.program);
this.aPos = gl.getAttribLocation(this.program, 'a_pos');
// define vertices of the triangle to be rendered in the custom style layer
const sw = maplibregl.MercatorCoordinate.fromLngLat({
lng: MAX_BOUNDS[0] - 5,
lat: MAX_BOUNDS[1] - 5
});
const ne = maplibregl.MercatorCoordinate.fromLngLat({
lng: MAX_BOUNDS[2] + 5,
lat: MAX_BOUNDS[3] + 5
});
//
// console.log({
// sw: sw,
// ne: ne
// });
// create and initialize a WebGLBuffer to store vertex and color data
this.buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([
//bottom left
sw.x,
sw.y,
// top left
sw.x,
ne.y,
// bottom right
ne.x,
sw.y,
// bottom right
ne.x,
sw.y,
// top right
ne.x,
ne.y,
// top left
sw.x,
ne.y,
]),
gl.STATIC_DRAW
);
},
// method fired on each animation frame
render(gl, matrix) {
const canvasSize = [gl.canvas.width, gl.canvas.height];
gl.useProgram(this.program);
gl.uniformMatrix4fv(
gl.getUniformLocation(this.program, 'u_matrix'),
false,
matrix
);
gl.uniform2fv(
gl.getUniformLocation(this.program, 'u_canvasSize'),
canvasSize
);
gl.uniform2fv(
gl.getUniformLocation(this.program, 'u_mapCenter'),
map.getCenter().toArray()
);
gl.uniform2fv(
gl.getUniformLocation(this.program, 'u_mapSize'),
[20037508.34 * 2, 20037508.34 * 2]
);
gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
gl.enableVertexAttribArray(this.aPos);
gl.vertexAttribPointer(this.aPos, 2, gl.FLOAT, false, 0, 0);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 6);
}
};
// add the custom style layer to the map
map.on('load', () => {
map.addLayer(highlightLayer, 'crimea-fill');
addBboxDebugLayer(map, {
w: MAX_BOUNDS[0],
s: MAX_BOUNDS[1],
e: MAX_BOUNDS[2],
n: MAX_BOUNDS[3]
});
});
</script>
</body>
</html>