Skip to content

Commit f5250ce

Browse files
authored
fix discontinuity when transitioning from globe to mercator in custom layer example (#12544)
* fix discontinuity when transitioning from globe to mercator in globe custom layer immediate mode example -expose more variables for this purpose in prerender and render methods * minor cleanup
1 parent f6a5adb commit f5250ce

File tree

4 files changed

+23
-12
lines changed

4 files changed

+23
-12
lines changed

debug/satellites-custom-layer.js

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
const EARTH_RADIUS_METERS = 6371008.8;
2-
const EARTH_CIRCUMFERENCE_METERS = 2 * Math.PI * EARTH_RADIUS_METERS;
3-
const GLOBE_CIRCUMFERENCE_ECEF = 8192;
4-
const METERS_TO_ECEF = GLOBE_CIRCUMFERENCE_ECEF / EARTH_CIRCUMFERENCE_METERS;
5-
61
const KM_TO_M = 1000;
72
const TIME_STEP = 3 * 1000;
83

@@ -13,12 +8,19 @@ const globeVertCode = `
138
uniform mat4 u_projection;
149
uniform mat4 u_globeToMercMatrix;
1510
uniform float u_globeToMercatorTransition;
11+
uniform vec2 u_centerInMerc;
12+
uniform float u_pixelsPerMeterRatio;
1613
1714
void main() {
1815
vec4 p = u_projection * u_globeToMercMatrix * vec4(a_pos_ecef, 1.);
1916
p /= p.w;
2017
if (u_globeToMercatorTransition > 0.) {
21-
vec4 merc = u_projection * vec4(a_pos_merc, 1.);
18+
19+
vec4 merc = vec4(a_pos_merc, 1.);
20+
merc.xy = (merc.xy - u_centerInMerc) * u_pixelsPerMeterRatio + u_centerInMerc;
21+
merc.z *= u_pixelsPerMeterRatio;
22+
23+
merc = u_projection * merc;
2224
merc /= merc.w;
2325
p = mix(p, merc, u_globeToMercatorTransition);
2426
}
@@ -141,21 +143,22 @@ const satellitesLayer = {
141143
}
142144
},
143145

144-
render (gl, projectionMatrix, projection, globeToMercMatrix, transition) {
146+
render (gl, projectionMatrix, projection, globeToMercMatrix, transition, centerInMercator, pixelsPerMeterRatio) {
145147
if (this.satData) {
146148
this.updateBuffers();
147149

148150
const primitiveCount = this.posEcef.length / 3;
149-
gl.enable(gl.DEPTH_TEST);
151+
gl.disable(gl.DEPTH_TEST);
150152
if (projection && projection.name === 'globe') { // globe projection and globe to mercator transition
151153
gl.useProgram(this.globeProgram);
152154

153155
updateVboAndActivateAttrib(gl, this.globeProgram, this.posEcefVbo, this.posEcef, "a_pos_ecef");
154156
updateVboAndActivateAttrib(gl, this.globeProgram, this.posMercVbo, this.posMerc, "a_pos_merc");
155-
156157
gl.uniformMatrix4fv(gl.getUniformLocation(this.globeProgram, "u_projection"), false, projectionMatrix);
157158
gl.uniformMatrix4fv(gl.getUniformLocation(this.globeProgram, "u_globeToMercMatrix"), false, globeToMercMatrix);
158159
gl.uniform1f(gl.getUniformLocation(this.globeProgram, "u_globeToMercatorTransition"), transition);
160+
gl.uniform2f(gl.getUniformLocation(this.globeProgram, "u_centerInMerc"), centerInMercator[0], centerInMercator[1]);
161+
gl.uniform1f(gl.getUniformLocation(this.globeProgram, "u_pixelsPerMeterRatio"), pixelsPerMeterRatio);
159162

160163
gl.drawArrays(gl.POINTS, 0, primitiveCount);
161164
} else { // mercator projection

src/geo/transform.js

+6
Original file line numberDiff line numberDiff line change
@@ -1114,6 +1114,12 @@ class Transform {
11141114
// Point at center in world coordinates.
11151115
get point(): Point { return this.project(this.center); }
11161116

1117+
// Point at center in Mercator coordinates.
1118+
get pointMerc(): Point { return this.point._div(this.worldSize); }
1119+
1120+
// Ratio of pixelsPerMeter in the current projection to Mercator's.
1121+
get pixelsPerMeterRatio(): number { return this.pixelsPerMeter / mercatorZfromAltitude(1, this.center.lat) / this.worldSize; }
1122+
11171123
setLocationAtPoint(lnglat: LngLat, point: Point) {
11181124
let x, y;
11191125
const centerPoint = this.centerPoint;

src/render/draw_custom.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ function drawCustom(painter: Painter, sourceCache: SourceCache, layer: CustomSty
3333
context.setColorMode(painter.colorModeForRenderPass());
3434

3535
if (painter.transform.projection.name === "globe") {
36-
prerender.call(implementation, context.gl, painter.transform.customLayerMatrix(), painter.transform.getProjection(), painter.transform.globeToMercatorMatrix(), globeToMercatorTransition(painter.transform.zoom));
36+
const center = painter.transform.pointMerc;
37+
prerender.call(implementation, context.gl, painter.transform.customLayerMatrix(), painter.transform.getProjection(), painter.transform.globeToMercatorMatrix(), globeToMercatorTransition(painter.transform.zoom), [center.x, center.y], painter.transform.pixelsPerMeterRatio);
3738
} else {
3839
prerender.call(implementation, context.gl, painter.transform.customLayerMatrix());
3940
}
@@ -76,7 +77,8 @@ function drawCustom(painter: Painter, sourceCache: SourceCache, layer: CustomSty
7677
context.setDepthMode(depthMode);
7778

7879
if (painter.transform.projection.name === "globe") {
79-
implementation.render(context.gl, painter.transform.customLayerMatrix(), painter.transform.getProjection(), painter.transform.globeToMercatorMatrix(), globeToMercatorTransition(painter.transform.zoom));
80+
const center = painter.transform.pointMerc;
81+
implementation.render(context.gl, painter.transform.customLayerMatrix(), painter.transform.getProjection(), painter.transform.globeToMercatorMatrix(), globeToMercatorTransition(painter.transform.zoom), [center.x, center.y], painter.transform.pixelsPerMeterRatio);
8082
} else {
8183
implementation.render(context.gl, painter.transform.customLayerMatrix());
8284
}

src/style/style_layer/custom_style_layer.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import assert from 'assert';
77
import type {ValidationErrors} from '../validate_style.js';
88
import type {ProjectionSpecification} from '../../style-spec/types.js';
99

10-
type CustomRenderMethod = (gl: WebGLRenderingContext, matrix: Array<number>, projection: ?ProjectionSpecification, projectionToMercatorMatrix: ?Array<number>, projectionToMercatorTransition: ?number) => void;
10+
type CustomRenderMethod = (gl: WebGLRenderingContext, matrix: Array<number>, projection: ?ProjectionSpecification, projectionToMercatorMatrix: ?Array<number>, projectionToMercatorTransition: ?number, centerInMercator: ?Array<number>, pixelsPerMeterRatio: ?number) => void;
1111

1212
/**
1313
* Interface for custom style layers. This is a specification for

0 commit comments

Comments
 (0)