mapbox / mapbox/mapbox-gl-js

fill-extrusion-pattern flickering (z-fighting) on tile borders

Open
#10,777 0 comments 0 reactions 1 assignee Claimed by @astojilj View on GitHub
3d :triangular_ruler: bug :lady_beetle:
Dominant language
TypeScript
Stars
12.4k
Forks
2.4k
PR merge metrics
No merged PRs in 30d

Description

https://user-images.githubusercontent.com/549216/122194949-9848e200-ce9e-11eb-99ef-0fadeee82699.mov

Example above uses multiple layers where filters separate contribution but it is reproducible also using a single layer with fill extrusion pattern. This is content contributed by one of the tiles:

![Screen Shot 2021-06-16 at 12 27 46](https://user-images.githubusercontent.com/549216/122197393-cdeeca80-cea0-11eb-801a-aea3ba2c20d9.png)

It is noticeable for fill extrusions with pattern only: because of difference in polygon rings starting points, overlapping triangles in two tiles, that share the border, have different UV mapping and the issue is noticeable.

A small offset in areas around the border resolves this. It is good to investigate also if clipping edges at tile borders is better approach.

```
diff --git a/src/shaders/fill_extrusion_pattern.vertex.glsl b/src/shaders/fill_extrusion_pattern.vertex.glsl
index 1edef27ed..ebab372f5 100644
--- a/src/shaders/fill_extrusion_pattern.vertex.glsl
+++ b/src/shaders/fill_extrusion_pattern.vertex.glsl
@@ -58,6 +58,8 @@ void main() {
base = max(0.0, base);
height = max(0.0, height);

+ // Offset vertices slightly near tile borders to avoid z fighting
+ vec2 posOffset = (vec2(-1.0) + step(67.0, pos_nx.xy) + step(8125.0, pos_nx.xy)) * 0.1;
float t = top_up_ny.x;
float z = t > 0.0 ? height : base;

@@ -69,10 +71,10 @@ void main() {
float c_ele = flat_roof ? centroid_pos.y == 0.0 ? elevationFromUint16(centroid_pos.x) : flatElevation(centroid_pos) : ele;
// If centroid elevation lower than vertex elevation, roof at least 2 meters height above base.
float h = flat_roof ? max(c_ele + height, ele + base + 2.0) : ele + (t > 0.0 ? height : base == 0.0 ? -5.0 : base);
- vec3 p = vec3(pos_nx.xy, h);
+ vec3 p = vec3(pos_nx.xy + posOffset, h);
gl_Position = mix(u_matrix * vec4(p, 1), AWAY, hidden);
#else
- vec3 p = vec3(pos_nx.xy, z);
+ vec3 p = vec3(pos_nx.xy + posOffset, z);
gl_Position = u_matrix * vec4(p, 1);
#endif

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.