Skip to content

Commit

Permalink
Fix render scale issues.
Browse files Browse the repository at this point in the history
Calculate relevant scaled value for line width, circle radius, etc.
Provide zoom, tileSize and canvas width and height to the scale.
  • Loading branch information
kalenkevich committed Jan 20, 2024
1 parent 1b4a945 commit 3cd9548
Show file tree
Hide file tree
Showing 21 changed files with 140 additions and 65 deletions.
4 changes: 2 additions & 2 deletions src/demo/map_styles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ export const VectorTileStyles: DataTileStyles = {
type: MapTileFeatureType.line,
show: ['$lte', ['$get', 'properties.admin_level'], 7],
color: ['$rgba', 120, 123, 140, 1],
width: 10,
width: 2,
},
maxzoom: 15,
minzoom: 0,
Expand Down Expand Up @@ -147,7 +147,7 @@ export const VectorTileStyles: DataTileStyles = {
['motorway', ['$rgba', 233, 201, 43, 1]],
['$default', ['$rgba', 215, 218, 226, 1]],
],
width: ['$switch', ['$get', 'properties.class'], ['primary', 24], ['$default', 8]],
width: ['$switch', ['$get', 'properties.class'], ['primary', 6], ['$default', 4]],
},
minzoom: 6,
},
Expand Down
4 changes: 2 additions & 2 deletions src/map/atlas/atlas_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ export class AtlasTextureManager {
const char = String.fromCharCode(i);

mapping[char] = {
x: currentX,
x: currentX + 5,
y: currentY,
width,
width: width,
height,
pixelRatio,
visible: true,
Expand Down
9 changes: 5 additions & 4 deletions src/map/camera/map_camera.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,13 +132,14 @@ export class MapCamera {

private updateProjectionMatrix() {
// update camera matrix
const zoomScale = 1 / Math.pow(2, this.zoom); // inverted
const tileWidthScale = this.tileSize / this.width;
const tileHeightScale = this.tileSize / this.height;
const zoomScale = Math.pow(2, this.zoom);

const cameraMat = mat3.create();
mat3.translate(cameraMat, cameraMat, [this.x, this.y]);
mat3.scale(cameraMat, cameraMat, [zoomScale / tileWidthScale, zoomScale / tileHeightScale]);
mat3.scale(cameraMat, cameraMat, [
this.width / (this.tileSize * zoomScale),
this.height / (this.tileSize * zoomScale),
]);
mat3.rotate(cameraMat, cameraMat, (Math.PI / 180) * this.rotationInDegree);

// update view projection matrix
Expand Down
15 changes: 8 additions & 7 deletions src/map/map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ export interface MapOptions {
zoom?: number;
/** Initial rotation value of the map. */
rotation?: number;
/** Number of tiles to featch around. */
/** Number of tiles to fetch around. */
tileBuffer?: number;
/** Custom value of device pixel ratio. By defauled would be used `window.devicePixelRatio`. */
devicePixelRatio?: number;
Expand Down Expand Up @@ -107,8 +107,8 @@ export class GlideMap extends Evented<MapEventType> {
private minZoom: number;
private maxZoom: number;

statsWidget: HTMLElement;
frameStats: {
private statsWidget: HTMLElement;
private frameStats: {
elapsed: number;
};

Expand Down Expand Up @@ -149,6 +149,7 @@ export class GlideMap extends Evented<MapEventType> {
this.mapOptions.tilesUrl,
this.mapOptions.tileStyles,
this.mapOptions.tileBuffer || 1,
this.mapOptions.tileStyles.tileSize,
this.maxZoom,
this.projection,
this.fontManager,
Expand Down Expand Up @@ -300,9 +301,9 @@ export class GlideMap extends Evented<MapEventType> {
}

rerender(): Promise<void> {
this.tilesGrid.updateTiles(this.camera, this.width, this.height);
const zoom = this.getZoom();
this.tilesGrid.updateTiles(this.camera, zoom, this.width, this.height);

this.renderQueue.clear();
return this.renderQueue.render(() => {
this.render();
this.fire(MapEventType.RENDER);
Expand All @@ -317,9 +318,9 @@ export class GlideMap extends Evented<MapEventType> {

const tiles = this.tilesGrid.getCurrentViewTiles();
const zoom = this.getZoom();
const projectionMatrix = this.camera.getProjectionMatrix();
const viewMatrix = this.camera.getProjectionMatrix();

this.renderer.render(tiles, zoom, projectionMatrix);
this.renderer.render(tiles, viewMatrix, zoom, this.mapOptions.tileStyles.tileSize);

this.statsWidget.style.display = 'none';

Expand Down
4 changes: 2 additions & 2 deletions src/map/render_queue/render_queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,11 @@ export class RenderQueue {
}

this.isActive = true;
const renderFn = this.queue[index][0];
const resolveFn = this.queue[index][1];
const [renderFn, resolveFn] = this.queue[index];

// invoke render
renderFn();

// we don't need to cancel it anymore
delete this.rafIds[index];
this.rafIds[index + 1] = requestAnimationFrame(() => this.invokeRender(index + 1));
Expand Down
2 changes: 1 addition & 1 deletion src/map/renderer/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ export interface Renderer {

resize(width: number, height: number): void;

render(tiles: MapTile[], zoom: number, matrix: mat3): void;
render(tiles: MapTile[], viewMatrix: mat3, zoom: number, tileSize: number): void;
}
4 changes: 3 additions & 1 deletion src/map/renderer/webgl/glyph/glyph_group_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ export class GlyphGroupBuilder extends ObjectGroupBuilder<WebGlGlyph> {
constructor(
protected readonly canvasWidth: number,
protected readonly canvasHeight: number,
protected readonly zoom: number,
protected readonly tileSize: number,
protected readonly projection: Projection,
private readonly atlasesMappingState: AtlasTextureMappingState
) {
super(canvasWidth, canvasHeight, projection);
super(canvasWidth, canvasHeight, zoom, tileSize, projection);
}

addObject(glyph: WebGlGlyph): void {
Expand Down
3 changes: 3 additions & 0 deletions src/map/renderer/webgl/glyph/glyph_shaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ export default {
uniform mat3 u_matrix;
uniform float u_zoom;
uniform float u_width;
uniform float u_height;
uniform float u_tile_size;
attribute vec2 a_position;
attribute vec2 a_texCoord;
Expand Down
4 changes: 3 additions & 1 deletion src/map/renderer/webgl/glyph/glyph_text_group_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ export class GlyphTextGroupBuilder extends ObjectGroupBuilder<WebGlText> {
constructor(
protected readonly canvasWidth: number,
protected readonly canvasHeight: number,
protected readonly zoom: number,
protected readonly tileSize: number,
protected readonly projection: Projection,
private readonly atlasesMappingState: AtlasTextureMappingState
) {
super(canvasWidth, canvasHeight, projection);
super(canvasWidth, canvasHeight, zoom, tileSize, projection);
}

addObject(text: WebGlText): void {
Expand Down
16 changes: 8 additions & 8 deletions src/map/renderer/webgl/line/line_program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export class LineProgram extends ObjectProgram {
protected a_colorBuffer: WebGLBuffer;
protected a_colorAttributeLocation: number = 3;

protected a_widthBuffer: WebGLBuffer;
protected a_widthAttributeLocation: number = 4;
protected a_line_widthBuffer: WebGLBuffer;
protected a_line_widthAttributeLocation: number = 4;

protected vao: WebGLVertexArrayObjectOES;

Expand Down Expand Up @@ -68,11 +68,11 @@ export class LineProgram extends ObjectProgram {
gl.vertexAttribPointer(this.a_colorAttributeLocation, 4, this.gl.FLOAT, false, 0, 0);
this.gl.vertexAttribDivisor(this.a_colorAttributeLocation, 1);

this.a_widthBuffer = gl.createBuffer();
gl.enableVertexAttribArray(this.a_widthAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, this.a_widthBuffer);
gl.vertexAttribPointer(this.a_widthAttributeLocation, 1, this.gl.FLOAT, false, 0, 0);
this.gl.vertexAttribDivisor(this.a_widthAttributeLocation, 1);
this.a_line_widthBuffer = gl.createBuffer();
gl.enableVertexAttribArray(this.a_line_widthAttributeLocation);
gl.bindBuffer(gl.ARRAY_BUFFER, this.a_line_widthBuffer);
gl.vertexAttribPointer(this.a_line_widthAttributeLocation, 1, this.gl.FLOAT, false, 0, 0);
this.gl.vertexAttribDivisor(this.a_line_widthAttributeLocation, 1);

this.gl.bindVertexArray(null);
}
Expand All @@ -99,7 +99,7 @@ export class LineProgram extends ObjectProgram {
gl.bindBuffer(gl.ARRAY_BUFFER, this.a_colorBuffer);
gl.bufferData(gl.ARRAY_BUFFER, lineGroup.color.buffer as Float32Array, gl.STATIC_DRAW);

gl.bindBuffer(gl.ARRAY_BUFFER, this.a_widthBuffer);
gl.bindBuffer(gl.ARRAY_BUFFER, this.a_line_widthBuffer);
gl.bufferData(gl.ARRAY_BUFFER, lineGroup.width.buffer as Float32Array, gl.STATIC_DRAW);

gl.drawArraysInstanced(gl.TRIANGLES, 0, POSITION_BUFFER.length / 2, lineGroup.numElements - 1);
Expand Down
13 changes: 11 additions & 2 deletions src/map/renderer/webgl/line/line_shaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,22 @@ export default {
uniform mat3 u_matrix;
uniform float u_zoom;
uniform float u_width;
uniform float u_height;
uniform float u_tile_size;
attribute vec2 a_position;
attribute vec3 point_a;
attribute vec3 point_b;
attribute vec4 a_color;
attribute float a_width;
attribute float a_line_width;
varying vec4 v_color;
float getScaledLineWidth() {
return a_line_width / (pow(2.0, u_zoom) * u_tile_size);
}
void main() {
if (point_a.z == -1.0) {
// trasparent
Expand All @@ -30,11 +37,13 @@ export default {
v_color = a_color;
}
float lineWidth = getScaledLineWidth();
vec2 point_a_projected = mercatorProject(point_a);
vec2 point_b_projected = mercatorProject(point_b);
vec2 xBasis = point_b_projected - point_a_projected;
vec2 yBasis = normalize(vec2(-xBasis.y, xBasis.x));
vec2 pos = point_a_projected + xBasis * a_position.x + yBasis * a_width * a_position.y;
vec2 pos = point_a_projected + xBasis * a_position.x + yBasis * lineWidth * a_position.y;
gl_Position = vec4(applyMatrix(u_matrix, clipSpace(pos)), 0, 1);
}
Expand Down
7 changes: 7 additions & 0 deletions src/map/renderer/webgl/object/object_group_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export abstract class ObjectGroupBuilder<ObjectType extends WebGlObject> {
constructor(
protected readonly canvasWidth: number,
protected readonly canvasHeight: number,
protected readonly zoom: number,
protected readonly tileSize: number,
protected readonly projection: Projection
) {}

Expand All @@ -17,5 +19,10 @@ export abstract class ObjectGroupBuilder<ObjectType extends WebGlObject> {
return this.objects.length === 0;
}

/** Scales value for webgl canvas value according to the current zoom and tileSize */
scale(val: number): number {
return val / (Math.pow(2, this.zoom) * this.tileSize);
}

abstract build(): WebGlObjectBufferredGroup;
}
18 changes: 18 additions & 0 deletions src/map/renderer/webgl/object/object_program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ export abstract class ObjectProgram {
// uniform locations
protected u_matrixLocation: WebGLUniformLocation;
protected u_zoomLocation: WebGLUniformLocation;
protected u_widthLocation: WebGLUniformLocation;
protected u_heightLocation: WebGLUniformLocation;
protected u_tile_sizeLocation: WebGLUniformLocation;

protected vao: WebGLVertexArrayObjectOES;

Expand Down Expand Up @@ -101,6 +104,9 @@ export abstract class ObjectProgram {
protected setupUniforms() {
this.u_matrixLocation = this.gl.getUniformLocation(this.program, 'u_matrix');
this.u_zoomLocation = this.gl.getUniformLocation(this.program, 'u_zoom');
this.u_widthLocation = this.gl.getUniformLocation(this.program, 'u_width');
this.u_heightLocation = this.gl.getUniformLocation(this.program, 'u_height');
this.u_tile_sizeLocation = this.gl.getUniformLocation(this.program, 'u_tile_size');
}

link() {
Expand All @@ -116,5 +122,17 @@ export abstract class ObjectProgram {
this.gl.uniform1f(this.u_zoomLocation, zoom);
}

setWidth(width: number) {
this.gl.uniform1f(this.u_widthLocation, width);
}

setHeight(height: number) {
this.gl.uniform1f(this.u_heightLocation, height);
}

setTileSize(tileSize: number) {
this.gl.uniform1f(this.u_tile_sizeLocation, tileSize);
}

abstract drawObjectGroup(objectGroup: WebGlObjectBufferredGroup): void;
}
2 changes: 1 addition & 1 deletion src/map/renderer/webgl/point/point_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export class PointGroupBuilder extends ObjectGroupBuilder<WebGlPoint> {
const objectSize = verticesFromPoint(
this.vertecies,
this.projection.fromLngLat([point.center[0], point.center[1]]),
point.radius,
this.scale(point.radius),
point.components
);

Expand Down
3 changes: 3 additions & 0 deletions src/map/renderer/webgl/point/point_shaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export default {
uniform mat3 u_matrix;
uniform float u_zoom;
uniform float u_width;
uniform float u_height;
uniform float u_tile_size;
attribute vec2 a_position;
attribute vec4 a_color;
Expand Down
3 changes: 3 additions & 0 deletions src/map/renderer/webgl/polygon/polygon_shaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export default {
uniform mat3 u_matrix;
uniform float u_zoom;
uniform float u_width;
uniform float u_height;
uniform float u_tile_size;
attribute vec2 a_position;
attribute vec4 a_color;
Expand Down
5 changes: 4 additions & 1 deletion src/map/renderer/webgl/text/text_builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ import { FontManager } from '../../../font/font_manager';
import { MapTileFeatureType } from '../../../tile/tile';
import { Projection } from '../../../geo/projection/projection';

/** @deprecated Please use GlyphGroupBuilder instead. */
export class TextGroupBuilder extends ObjectGroupBuilder<WebGlText> {
constructor(
protected readonly canvasWidth: number,
protected readonly canvasHeight: number,
protected readonly zoom: number,
protected readonly tileSize: number,
protected readonly projection: Projection,
private readonly fontManager: FontManager
) {
super(canvasWidth, canvasHeight, projection);
super(canvasWidth, canvasHeight, zoom, tileSize, projection);
}

addObject(text: WebGlText) {
Expand Down
9 changes: 6 additions & 3 deletions src/map/renderer/webgl/text/text_shaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ export default {
${MAT_UTILS}
${MERCATOR_PROJECTION_UTILS}
attribute vec2 a_position;
attribute vec4 a_color;
uniform mat3 u_matrix;
uniform float u_zoom;
uniform float u_width;
uniform float u_height;
uniform float u_tile_size;
attribute vec2 a_position;
attribute vec4 a_color;
varying vec4 v_color;
Expand Down
Loading

0 comments on commit 3cd9548

Please sign in to comment.