Skip to content

Commit

Permalink
Globe View: Latest shader changes for native port (#11015)
Browse files Browse the repository at this point in the history
* Add globe view shader changes

* Add globe view shader uniforms

* Fix flow

* Fix lint

* Add _prelude.vertex.glsl shader changes

* Fix incorrect attribute name

* Make elevationVector depend on PROJECTION_GLOBE_VIEW

* Address review feedback

* Inject precision qualifiers very first

* Reduce shader instructions by splitting function mix_globe_mercator

* Add missing change to extract pow instruction out of vertex shader

* Expose prelude precision qualifiers for native

* Adjust precision qualifiers in globe atmosphere shader to fix an issue on Android

Co-authored-by: Daniel Eke <daniel.eke@mapbox.com>
  • Loading branch information
karimnaaji and endanke committed Sep 20, 2021
1 parent 2f62bba commit 5e069ff
Show file tree
Hide file tree
Showing 14 changed files with 265 additions and 74 deletions.
22 changes: 16 additions & 6 deletions src/render/draw_symbol.js
Original file line number Diff line number Diff line change
Expand Up @@ -244,11 +244,17 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate
let sortFeaturesByKey = false;

const depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly);

const mercCenter = [0, 0];
const variablePlacement = layer.layout.get('text-variable-anchor');

const tileRenderState: Array<SymbolTileRenderState> = [];
const defines = painter.terrain && pitchWithMap ? ['PITCH_WITH_MAP_TERRAIN'] : null;

const defines = ([]: any);
if (painter.terrain && pitchWithMap) {
defines.push('PITCH_WITH_MAP_TERRAIN');
}
if (alongLine) {
defines.push('PROJECTED_POS_ON_VIEWPORT');
}

for (const coord of coords) {
const tile = sourceCache.getTile(coord);
Expand All @@ -265,6 +271,7 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate

const program = painter.useProgram(getSymbolProgramName(isSDF, isText, bucket), programConfiguration, defines);
const size = symbolSize.evaluateSizeForZoom(sizeData, tr.zoom);
const coordId = [coord.canonical.x, coord.canonical.y, 1 << coord.canonical.z];

let texSize: [number, number];
let texSizeIcon: [number, number] = [0, 0];
Expand Down Expand Up @@ -319,16 +326,19 @@ function drawLayerSymbols(painter, sourceCache, layer, coords, isText, translate
if (!bucket.iconsInText) {
uniformValues = symbolSDFUniformValues(sizeData.kind,
size, rotateInShader, pitchWithMap, painter, matrix,
uLabelPlaneMatrix, uglCoordMatrix, isText, texSize, true);
uLabelPlaneMatrix, uglCoordMatrix, isText, texSize, true,
coordId, 0.0, painter.identityMat, mercCenter);
} else {
uniformValues = symbolTextAndIconUniformValues(sizeData.kind,
size, rotateInShader, pitchWithMap, painter, matrix,
uLabelPlaneMatrix, uglCoordMatrix, texSize, texSizeIcon);
uLabelPlaneMatrix, uglCoordMatrix, texSize, texSizeIcon,
coordId, 0.0, painter.identityMat, mercCenter);
}
} else {
uniformValues = symbolIconUniformValues(sizeData.kind,
size, rotateInShader, pitchWithMap, painter, matrix,
uLabelPlaneMatrix, uglCoordMatrix, isText, texSize);
uLabelPlaneMatrix, uglCoordMatrix, isText, texSize,
coordId, 0.0, painter.identityMat, mercCenter);
}

const state = {
Expand Down
24 changes: 21 additions & 3 deletions src/render/program.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
// @flow

import {prelude, preludeTerrain, preludeFog, preludeCommonSource} from '../shaders/shaders.js';
import {
prelude,
preludeFragPrecisionQualifiers,
preludeVertPrecisionQualifiers,
preludeTerrain,
preludeFog,
preludeCommonSource
} from '../shaders/shaders.js';
import assert from 'assert';
import ProgramConfiguration from '../data/program_configuration.js';
import VertexArrayObject from './vertex_array_object.js';
Expand Down Expand Up @@ -78,8 +85,19 @@ class Program<Us: UniformBindings> {
let defines = configuration ? configuration.defines() : [];
defines = defines.concat(fixedDefines.map((define) => `#define ${define}`));

const fragmentSource = defines.concat(prelude.fragmentSource, preludeCommonSource, preludeFog.fragmentSource, source.fragmentSource).join('\n');
const vertexSource = defines.concat(prelude.vertexSource, preludeCommonSource, preludeFog.vertexSource, preludeTerrain.vertexSource, source.vertexSource).join('\n');
const fragmentSource = defines.concat(
preludeFragPrecisionQualifiers,
preludeCommonSource,
prelude.fragmentSource,
preludeFog.fragmentSource,
source.fragmentSource).join('\n');
const vertexSource = defines.concat(
preludeVertPrecisionQualifiers,
preludeCommonSource,
prelude.vertexSource,
preludeFog.vertexSource,
preludeTerrain.vertexSource,
source.vertexSource).join('\n');
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
if (gl.isContextLost()) {
this.failedToCreate = true;
Expand Down
45 changes: 40 additions & 5 deletions src/render/program/symbol_program.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Uniform1i,
Uniform1f,
Uniform2f,
Uniform3f,
UniformMatrix4f
} from '../uniform_binding.js';
import {extend} from '../../util/util.js';
Expand All @@ -29,6 +30,10 @@ export type SymbolIconUniformsType = {|
'u_is_text': Uniform1i,
'u_pitch_with_map': Uniform1i,
'u_texsize': Uniform2f,
'u_tile_id': Uniform3f,
'u_zoom_transition': Uniform1f,
'u_inv_rot_matrix': UniformMatrix4f,
'u_merc_center': Uniform2f,
'u_texture': Uniform1i
|};

Expand All @@ -51,6 +56,10 @@ export type SymbolSDFUniformsType = {|
'u_texture': Uniform1i,
'u_gamma_scale': Uniform1f,
'u_device_pixel_ratio': Uniform1f,
'u_tile_id': Uniform3f,
'u_zoom_transition': Uniform1f,
'u_inv_rot_matrix': UniformMatrix4f,
'u_merc_center': Uniform2f,
'u_is_halo': Uniform1i
|};

Expand Down Expand Up @@ -96,6 +105,10 @@ const symbolIconUniforms = (context: Context, locations: UniformLocations): Symb
'u_is_text': new Uniform1i(context, locations.u_is_text),
'u_pitch_with_map': new Uniform1i(context, locations.u_pitch_with_map),
'u_texsize': new Uniform2f(context, locations.u_texsize),
'u_tile_id': new Uniform3f(context, locations.u_tile_id),
'u_zoom_transition': new Uniform1f(context, locations.u_zoom_transition),
'u_inv_rot_matrix': new UniformMatrix4f(context, locations.u_inv_rot_matrix),
'u_merc_center': new Uniform2f(context, locations.u_merc_center),
'u_texture': new Uniform1i(context, locations.u_texture)
});

Expand All @@ -118,6 +131,10 @@ const symbolSDFUniforms = (context: Context, locations: UniformLocations): Symbo
'u_texture': new Uniform1i(context, locations.u_texture),
'u_gamma_scale': new Uniform1f(context, locations.u_gamma_scale),
'u_device_pixel_ratio': new Uniform1f(context, locations.u_device_pixel_ratio),
'u_tile_id': new Uniform3f(context, locations.u_tile_id),
'u_zoom_transition': new Uniform1f(context, locations.u_zoom_transition),
'u_inv_rot_matrix': new UniformMatrix4f(context, locations.u_inv_rot_matrix),
'u_merc_center': new Uniform2f(context, locations.u_merc_center),
'u_is_halo': new Uniform1i(context, locations.u_is_halo)
});

Expand Down Expand Up @@ -155,7 +172,11 @@ const symbolIconUniformValues = (
labelPlaneMatrix: Float32Array,
glCoordMatrix: Float32Array,
isText: boolean,
texSize: [number, number]
texSize: [number, number],
tileID: [number, number, number],
zoomTransition: number,
invRotMatrix: Float32Array,
mercCenter: [number, number]
): UniformValues<SymbolIconUniformsType> => {
const transform = painter.transform;

Expand All @@ -175,6 +196,10 @@ const symbolIconUniformValues = (
'u_is_text': +isText,
'u_pitch_with_map': +pitchWithMap,
'u_texsize': texSize,
'u_tile_id': tileID,
'u_zoom_transition': zoomTransition,
'u_inv_rot_matrix': invRotMatrix,
'u_merc_center': mercCenter,
'u_texture': 0
};
};
Expand All @@ -190,13 +215,18 @@ const symbolSDFUniformValues = (
glCoordMatrix: Float32Array,
isText: boolean,
texSize: [number, number],
isHalo: boolean
isHalo: boolean,
tileID: [number, number, number],
zoomTransition: number,
invRotMatrix: Float32Array,
mercCenter: [number, number]
): UniformValues<SymbolSDFUniformsType> => {
const {cameraToCenterDistance, _pitch} = painter.transform;

return extend(symbolIconUniformValues(functionType, size,
rotateInShader, pitchWithMap, painter, matrix, labelPlaneMatrix,
glCoordMatrix, isText, texSize), {
glCoordMatrix, isText, texSize, tileID, zoomTransition,
invRotMatrix, mercCenter), {
'u_gamma_scale': pitchWithMap ? cameraToCenterDistance * Math.cos(painter.terrain ? 0 : _pitch) : 1,
'u_device_pixel_ratio': browser.devicePixelRatio,
'u_is_halo': +isHalo
Expand All @@ -213,11 +243,16 @@ const symbolTextAndIconUniformValues = (
labelPlaneMatrix: Float32Array,
glCoordMatrix: Float32Array,
texSizeSDF: [number, number],
texSizeIcon: [number, number]
texSizeIcon: [number, number],
tileID: [number, number, number],
zoomTransition: number,
invRotMatrix: Float32Array,
mercCenter: [number, number]
): UniformValues<SymbolIconUniformsType> => {
return extend(symbolSDFUniformValues(functionType, size,
rotateInShader, pitchWithMap, painter, matrix, labelPlaneMatrix,
glCoordMatrix, true, texSizeSDF, true), {
glCoordMatrix, true, texSizeSDF, true, tileID, zoomTransition,
invRotMatrix, mercCenter), {
'u_texsize_icon': texSizeIcon,
'u_texture_icon': 1
});
Expand Down
18 changes: 1 addition & 17 deletions src/shaders/_prelude.fragment.glsl
Original file line number Diff line number Diff line change
@@ -1,20 +1,4 @@
#ifdef GL_ES
precision mediump float;
#else

#if !defined(lowp)
#define lowp
#endif

#if !defined(mediump)
#define mediump
#endif

#if !defined(highp)
#define highp
#endif

#endif
// NOTE: This prelude is injected in the fragment shader only

highp vec3 hash(highp vec2 p) {
highp vec3 p3 = fract(p.xyx * vec3(443.8975, 397.2973, 491.1871));
Expand Down
1 change: 1 addition & 0 deletions src/shaders/_prelude.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#define EPSILON 0.0000001
#define PI 3.141592653589793
#define EXTENT 8192.0

#ifdef FOG

Expand Down
38 changes: 27 additions & 11 deletions src/shaders/_prelude.vertex.glsl
Original file line number Diff line number Diff line change
@@ -1,20 +1,36 @@
#ifdef GL_ES
precision highp float;
#else
// NOTE: This prelude is injected in the vertex shader only

#if !defined(lowp)
#define lowp
#endif
float wrap(float n, float min, float max) {
float d = max - min;
float w = mod(mod(n - min, d) + d, d) + min;
return (w == min) ? max : w;
}

#if !defined(mediump)
#define mediump
#endif
vec3 mercator_tile_position(mat4 matrix, vec2 tile_anchor, vec3 tile_id, vec2 mercator_center) {
#if defined(PROJECTION_GLOBE_VIEW) && !defined(PROJECTED_POS_ON_VIEWPORT)
// tile_id.z contains pow(2.0, coord.canonical.z)
float tiles = tile_id.z;

vec2 mercator = (tile_anchor / EXTENT + tile_id.xy) / tiles;
mercator -= mercator_center;
mercator.x = wrap(mercator.x, -0.5, 0.5);

#if !defined(highp)
#define highp
vec4 mercator_tile = vec4(mercator.xy * EXTENT, EXTENT / (2.0 * PI), 1.0);
mercator_tile = matrix * mercator_tile;

return mercator_tile.xyz;
#else
return vec3(0.0);
#endif
}

vec3 mix_globe_mercator(vec3 globe, vec3 mercator, float t) {
#if defined(PROJECTION_GLOBE_VIEW) && !defined(PROJECTED_POS_ON_VIEWPORT)
return mix(globe, mercator, t);
#else
return globe;
#endif
}

// Unpack a pair of values that have been packed into a single float.
// The packed values are assumed to be 8-bit unsigned integers, and are
Expand Down
38 changes: 22 additions & 16 deletions src/shaders/_prelude_terrain.vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,28 @@
#define ELEVATION_SCALE 7.0
#define ELEVATION_OFFSET 450.0

#ifdef PROJECTION_GLOBE_VIEW

uniform vec3 u_tile_tl_up;
uniform vec3 u_tile_tr_up;
uniform vec3 u_tile_br_up;
uniform vec3 u_tile_bl_up;
uniform float u_tile_up_scale;
vec3 elevationVector(vec2 pos) {
vec2 uv = pos / EXTENT;
vec3 up = normalize(mix(
mix(u_tile_tl_up, u_tile_tr_up, uv.xxx),
mix(u_tile_bl_up, u_tile_br_up, uv.xxx),
uv.yyy));
return up * u_tile_up_scale;
}

#else

vec3 elevationVector(vec2 pos) { return vec3(0, 0, 1); }

#endif

#ifdef TERRAIN

#ifdef TERRAIN_DEM_FLOAT_FORMAT
Expand All @@ -22,24 +44,9 @@ uniform float u_exaggeration;
uniform float u_meter_to_dem;
uniform mat4 u_label_plane_matrix_inv;

uniform vec3 u_tile_tl_up;
uniform vec3 u_tile_tr_up;
uniform vec3 u_tile_br_up;
uniform vec3 u_tile_bl_up;
uniform float u_tile_up_scale;

uniform sampler2D u_depth;
uniform vec2 u_depth_size_inv;

vec3 elevationVector(vec2 pos) {
vec2 uv = pos / 8192.0;
vec3 up = normalize(mix(
mix(u_tile_tl_up, u_tile_tr_up, uv.xxx),
mix(u_tile_bl_up, u_tile_br_up, uv.xxx),
uv.yyy));
return up * u_tile_up_scale;
}

vec4 tileUvToDemSample(vec2 uv, float dem_size, float dem_scale, vec2 dem_tl) {
vec2 pos = dem_size * (uv * dem_scale + dem_tl) + 1.0;
vec2 f = fract(pos);
Expand Down Expand Up @@ -195,6 +202,5 @@ float elevationFromUint16(float word) {
float elevation(vec2 pos) { return 0.0; }
bool isOccluded(vec4 frag) { return false; }
float occlusionFade(vec4 frag) { return 1.0; }
vec3 elevationVector(vec2 pos) { return vec3(0, 0, 1); }

#endif
4 changes: 2 additions & 2 deletions src/shaders/globe_atmosphere.fragment.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ uniform float u_radius;
uniform vec2 u_screen_size;

uniform float u_opacity;
uniform float u_fadeout_range;
uniform highp float u_fadeout_range;
uniform vec3 u_start_color;
uniform vec3 u_end_color;
uniform float u_pixel_ratio;

void main() {
vec2 fragCoord = gl_FragCoord.xy / u_pixel_ratio;
highp vec2 fragCoord = gl_FragCoord.xy / u_pixel_ratio;
fragCoord.y = u_screen_size.y - fragCoord.y;
float distFromCenter = length(fragCoord - u_center);

Expand Down
23 changes: 22 additions & 1 deletion src/shaders/globe_depth.vertex.glsl
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
uniform mat4 u_proj_matrix;
uniform mat4 u_globe_matrix;
uniform mat4 u_merc_matrix;
uniform mat4 u_up_vector_matrix;
uniform float u_zoom_transition;
uniform vec2 u_merc_center;

attribute vec3 a_globe_pos;
attribute vec2 a_merc_pos;
attribute vec2 a_uv;

varying float v_depth;

void main() {
gl_Position = u_globe_matrix * vec4(a_globe_pos + elevationVector(a_uv * 8192.0) * elevation(a_uv * 8192.0), 1.0);
vec2 uv = a_uv * EXTENT;
vec4 up_vector = u_up_vector_matrix * vec4(elevationVector(uv), 1.0);
float height = elevation(uv);

vec4 globe = u_globe_matrix * vec4(a_globe_pos + up_vector.xyz * height, 1.0);

vec4 mercator = vec4(a_merc_pos, height, 1.0);
mercator.xy -= u_merc_center;
mercator.x = wrap(mercator.x, -0.5, 0.5);
mercator = u_merc_matrix * mercator;

vec3 position = mix(globe.xyz, mercator.xyz, u_zoom_transition);

gl_Position = u_proj_matrix * vec4(position, 1.0);

v_depth = gl_Position.z / gl_Position.w;
}

0 comments on commit 5e069ff

Please sign in to comment.