Skip to content

Commit

Permalink
Add heatmap layer support for globe view (#11464)
Browse files Browse the repository at this point in the history
  • Loading branch information
akoylasar committed Feb 3, 2022
1 parent bfeb8f9 commit 6ffc4c0
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 19 deletions.
1 change: 0 additions & 1 deletion src/geo/projection/globe.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ export default {
zAxisUnit: "pixels",
center: [0, 0],
unsupportedLayers: [
'heatmap',
'fill-extrusion',
'debug',
'custom'
Expand Down
18 changes: 14 additions & 4 deletions src/render/draw_heatmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
heatmapUniformValues,
heatmapTextureUniformValues
} from './program/heatmap_program.js';
import {mercatorXfromLng, mercatorYfromLat} from '../geo/mercator_coordinate.js';

import type Painter from './painter.js';
import type SourceCache from '../source/source_cache.js';
Expand Down Expand Up @@ -38,6 +39,14 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS

context.clear({color: Color.transparent});

const tr = painter.transform;

const isGlobeProjection = tr.projection.name === 'globe';
const definesValues = isGlobeProjection ? ['PROJECTION_GLOBE_VIEW'] : null;

const tileTransform = tr.projection.createTileTransform(tr, tr.worldSize);
const mercatorCenter = [mercatorXfromLng(tr.center.lng), mercatorYfromLat(tr.center.lat)];

for (let i = 0; i < coords.length; i++) {
const coord = coords[i];

Expand All @@ -51,18 +60,19 @@ function drawHeatmap(painter: Painter, sourceCache: SourceCache, layer: HeatmapS
if (!bucket) continue;

const programConfiguration = bucket.programConfigurations.get(layer.id);
const program = painter.useProgram('heatmap', programConfiguration);
const program = painter.useProgram('heatmap', programConfiguration, definesValues);
const {zoom} = painter.transform;
if (painter.terrain) painter.terrain.setupElevationDraw(tile, program);

painter.prepareDrawProgram(context, program, coord.toUnwrapped());

program.draw(context, gl.TRIANGLES, DepthMode.disabled, stencilMode, colorMode, CullFaceMode.disabled,
heatmapUniformValues(coord.projMatrix,
tile, zoom, layer.paint.get('heatmap-intensity')),
heatmapUniformValues(painter, coord,
tile, tileTransform, mercatorCenter, zoom, layer.paint.get('heatmap-intensity')),
layer.id, bucket.layoutVertexBuffer, bucket.indexBuffer,
bucket.segments, layer.paint, painter.transform.zoom,
programConfiguration);
programConfiguration,
isGlobeProjection ? bucket.globeExtVertexBuffer : null);
}

context.viewport.set([0, 0, painter.width, painter.height]);
Expand Down
60 changes: 52 additions & 8 deletions src/render/program/heatmap_program.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import {
Uniform1i,
Uniform1f,
Uniform2f,
Uniform3f,
UniformMatrix4f
} from '../uniform_binding.js';
import pixelsToTileUnits from '../../source/pixels_to_tile_units.js';
Expand All @@ -12,11 +14,20 @@ import type Tile from '../../source/tile.js';
import type {UniformValues, UniformLocations} from '../uniform_binding.js';
import type Painter from '../painter.js';
import type HeatmapStyleLayer from '../../style/style_layer/heatmap_style_layer.js';
import type {TileTransform} from '../../geo/projection/index.js';
import type {OverscaledTileID} from '../../source/tile_id.js';
import {mat4} from 'gl-matrix';
import {globeToMercatorTransition, globePixelsToTileUnits} from '../../geo/projection/globe.js';

export type HeatmapUniformsType = {|
'u_extrude_scale': Uniform1f,
'u_intensity': Uniform1f,
'u_matrix': UniformMatrix4f
'u_matrix': UniformMatrix4f,
'u_inv_rot_matrix': UniformMatrix4f,
'u_merc_center': Uniform2f,
'u_tile_id': Uniform3f,
'u_zoom_transition': Uniform1f,
'u_up_dir': Uniform3f,
|};

export type HeatmapTextureUniformsType = {|
Expand All @@ -28,7 +39,12 @@ export type HeatmapTextureUniformsType = {|
const heatmapUniforms = (context: Context, locations: UniformLocations): HeatmapUniformsType => ({
'u_extrude_scale': new Uniform1f(context, locations.u_extrude_scale),
'u_intensity': new Uniform1f(context, locations.u_intensity),
'u_matrix': new UniformMatrix4f(context, locations.u_matrix)
'u_matrix': new UniformMatrix4f(context, locations.u_matrix),
'u_inv_rot_matrix': new UniformMatrix4f(context, locations.u_inv_rot_matrix),
'u_merc_center': new Uniform2f(context, locations.u_merc_center),
'u_tile_id': new Uniform3f(context, locations.u_tile_id),
'u_zoom_transition': new Uniform1f(context, locations.u_zoom_transition),
'u_up_dir': new Uniform3f(context, locations.u_up_dir)
});

const heatmapTextureUniforms = (context: Context, locations: UniformLocations): HeatmapTextureUniformsType => ({
Expand All @@ -37,16 +53,42 @@ const heatmapTextureUniforms = (context: Context, locations: UniformLocations):
'u_opacity': new Uniform1f(context, locations.u_opacity)
});

const identityMatrix = mat4.create();

const heatmapUniformValues = (
matrix: Float32Array,
painter: Painter,
coord: OverscaledTileID,
tile: Tile,
tileTransform: TileTransform,
mercatorCenter: [number, number],
zoom: number,
intensity: number
): UniformValues<HeatmapUniformsType> => ({
'u_matrix': matrix,
'u_extrude_scale': pixelsToTileUnits(tile, 1, zoom),
'u_intensity': intensity
});
): UniformValues<HeatmapUniformsType> => {
const transform = painter.transform;
const isGlobe = transform.projection.name === 'globe';
const extrudeScale = isGlobe ? globePixelsToTileUnits(transform.zoom, coord.canonical) : pixelsToTileUnits(tile, 1, zoom);

const values = {
'u_matrix': coord.projMatrix,
'u_extrude_scale': extrudeScale,
'u_intensity': intensity,
'u_inv_rot_matrix': identityMatrix,
'u_merc_center': [0, 0],
'u_tile_id': [0, 0, 0],
'u_zoom_transition': 0,
'u_up_dir': [0, 0, 0],
};

if (isGlobe) {
values['u_inv_rot_matrix'] = tileTransform.createInversionMatrix(coord.canonical);
values['u_merc_center'] = mercatorCenter;
values['u_tile_id'] = [coord.canonical.x, coord.canonical.y, 1 << coord.canonical.z];
values['u_zoom_transition'] = globeToMercatorTransition(transform.zoom);
values['u_up_dir'] = (transform.projection.upVector(coord.canonical, mercatorCenter[0], mercatorCenter[1]): any);
}

return values;
};

const heatmapTextureUniformValues = (
painter: Painter,
Expand All @@ -67,3 +109,5 @@ export {
heatmapUniformValues,
heatmapTextureUniformValues
};

export type HeatmapDefinesType = 'PROJECTION_GLOBE_VIEW';
3 changes: 2 additions & 1 deletion src/render/program/program_uniforms.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ import {terrainRasterUniforms} from '../../terrain/terrain_raster_program.js';
import {skyboxUniforms, skyboxGradientUniforms} from './skybox_program.js';
import {skyboxCaptureUniforms} from './skybox_capture_program.js';
import {globeRasterUniforms, atmosphereUniforms} from '../../terrain/globe_raster_program.js';
import type {HeatmapDefinesType} from './heatmap_program.js';

export type DynamicDefinesType = CircleDefinesType | SymbolDefinesType | LineDefinesType;
export type DynamicDefinesType = CircleDefinesType | SymbolDefinesType | LineDefinesType | HeatmapDefinesType;

export const programUniforms = {
fillExtrusion: fillExtrusionUniforms,
Expand Down
5 changes: 0 additions & 5 deletions test/ignores.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,6 @@
"render-tests/video/projected": "https://github.com/mapbox/mapbox-gl-js/issues/11234",
"query-tests/terrain/draped/lines/slope-occlusion-box-query": "skip - non-deterministic",
"render-tests/fill-extrusion-pattern/opacity-terrain": "skip - deferred for globe-view",
"render-tests/globe/globe-heatmap/default": "skip - pending globe-view implementation",
"render-tests/globe/globe-heatmap/default-zoomed": "skip - pending globe-view implementation",
"render-tests/globe/globe-heatmap/horizontal": "skip - pending globe-view implementation",
"render-tests/globe/globe-heatmap/near-horizon": "skip - pending globe-view implementation",
"render-tests/globe/globe-heatmap/vertical": "skip - pending globe-view implementation",
"render-tests/globe/globe-padding": "skip - pending globe-view implementation",
"render-tests/globe/globe-transition/horizon-during-transition": "skip - pending globe-view implementation"
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 6ffc4c0

Please sign in to comment.