summaryrefslogtreecommitdiff
path: root/src/mbgl/shaders/symbol_icon.cpp
diff options
context:
space:
mode:
authorAnsis Brammanis <brammanis@gmail.com>2017-06-16 10:42:33 -0400
committerAnsis Brammanis <brammanis@gmail.com>2017-07-11 09:10:24 -0700
commite514138b691615be24f484986c40f486223df82a (patch)
tree4cab221d92f66feefd132818a700c47cc67ef245 /src/mbgl/shaders/symbol_icon.cpp
parent77734cfe1b9e77a0058fa3e0db79e3c20a264165 (diff)
downloadqtlocation-mapboxgl-e514138b691615be24f484986c40f486223df82a.tar.gz
[core] improve legibility of labels that follow lines
port https://github.com/mapbox/mapbox-gl-js/pull/4781 This improves legibility of labels that follow lines in pitched views. The previous approach used the limited information in the shader to calculate put the glyph in approximatelyright place. The new approach does this more accurately by doing it on the cpu where we have access to the entire line geometry.
Diffstat (limited to 'src/mbgl/shaders/symbol_icon.cpp')
-rw-r--r--src/mbgl/shaders/symbol_icon.cpp70
1 files changed, 28 insertions, 42 deletions
diff --git a/src/mbgl/shaders/symbol_icon.cpp b/src/mbgl/shaders/symbol_icon.cpp
index 8960e02c28..cb00cdad05 100644
--- a/src/mbgl/shaders/symbol_icon.cpp
+++ b/src/mbgl/shaders/symbol_icon.cpp
@@ -7,17 +7,16 @@ namespace shaders {
const char* symbol_icon::name = "symbol_icon";
const char* symbol_icon::vertexSource = R"MBGL_SHADER(
+const float PI = 3.141592653589793;
+
attribute vec4 a_pos_offset;
-attribute vec2 a_label_pos;
attribute vec4 a_data;
+attribute vec3 a_projected_pos;
-// icon-size data (see symbol_sdf.vertex.glsl for more)
-attribute vec3 a_size;
uniform bool u_is_size_zoom_constant;
uniform bool u_is_size_feature_constant;
uniform highp float u_size_t; // used to interpolate between zoom stops when size is a composite function
uniform highp float u_size; // used when size is both zoom and feature constant
-uniform highp float u_layout_size; // used when size is feature constant
uniform highp float u_camera_to_center_distance;
uniform highp float u_pitch;
uniform highp float u_collision_y_stretch;
@@ -31,13 +30,12 @@ varying lowp float opacity;
uniform lowp float u_opacity;
#endif
-// matrix is for the vertex position.
uniform mat4 u_matrix;
+uniform mat4 u_label_plane_matrix;
+uniform mat4 u_gl_coord_matrix;
uniform bool u_is_text;
-uniform highp float u_zoom;
-uniform bool u_rotate_with_map;
-uniform vec2 u_extrude_scale;
+uniform bool u_pitch_with_map;
uniform vec2 u_texsize;
@@ -56,61 +54,49 @@ void main() {
vec2 a_offset = a_pos_offset.zw;
vec2 a_tex = a_data.xy;
- highp vec2 label_data = unpack_float(a_data[2]);
- highp float a_labelminzoom = label_data[0];
- highp vec2 a_zoom = unpack_float(a_data[3]);
- highp float a_minzoom = a_zoom[0];
- highp float a_maxzoom = a_zoom[1];
+ vec2 a_size = a_data.zw;
+
+ highp vec2 angle_labelminzoom = unpack_float(a_projected_pos[2]);
+ highp float segment_angle = -angle_labelminzoom[0] / 255.0 * 2.0 * PI;
+ mediump float a_labelminzoom = angle_labelminzoom[1];
float size;
- // In order to accommodate placing labels around corners in
- // symbol-placement: line, each glyph in a label could have multiple
- // "quad"s only one of which should be shown at a given zoom level.
- // The min/max zoom assigned to each quad is based on the font size at
- // the vector tile's zoom level, which might be different than at the
- // currently rendered zoom level if text-size is zoom-dependent.
- // Thus, we compensate for this difference by calculating an adjustment
- // based on the scale of rendered text size relative to layout text size.
- highp float layoutSize;
if (!u_is_size_zoom_constant && !u_is_size_feature_constant) {
size = mix(a_size[0], a_size[1], u_size_t) / 10.0;
- layoutSize = a_size[2] / 10.0;
} else if (u_is_size_zoom_constant && !u_is_size_feature_constant) {
size = a_size[0] / 10.0;
- layoutSize = size;
} else if (!u_is_size_zoom_constant && u_is_size_feature_constant) {
size = u_size;
- layoutSize = u_layout_size;
} else {
size = u_size;
- layoutSize = u_size;
}
- float fontScale = u_is_text ? size / 24.0 : size;
+ vec4 projectedPoint = u_matrix * vec4(a_pos, 0, 1);
+ highp float camera_to_anchor_distance = projectedPoint.w;
+ // See comments in symbol_sdf.vertex
+ highp float distance_ratio = u_pitch_with_map ?
+ camera_to_anchor_distance / u_camera_to_center_distance :
+ u_camera_to_center_distance / camera_to_anchor_distance;
+ highp float perspective_ratio = 0.5 + 0.5 * distance_ratio;
- highp float zoomAdjust = log2(size / layoutSize);
- highp float adjustedZoom = (u_zoom - zoomAdjust) * 10.0;
- // result: z = 0 if a_minzoom <= adjustedZoom < a_maxzoom, and 1 otherwise
- highp float z = 2.0 - step(a_minzoom, adjustedZoom) - (1.0 - step(a_maxzoom, adjustedZoom));
+ size *= perspective_ratio;
- vec4 projectedPoint = u_matrix * vec4(a_label_pos, 0, 1);
- highp float camera_to_anchor_distance = projectedPoint.w;
- highp float perspective_ratio = 1.0 + 0.5*((camera_to_anchor_distance / u_camera_to_center_distance) - 1.0);
+ float fontScale = u_is_text ? size / 24.0 : size;
- vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (a_offset / 64.0);
- if (u_rotate_with_map) {
- gl_Position = u_matrix * vec4(a_pos + extrude, 0, 1);
- gl_Position.z += z * gl_Position.w;
- } else {
- gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0);
- }
+ highp float angle_sin = sin(segment_angle);
+ highp float angle_cos = cos(segment_angle);
+ mat2 rotation_matrix = mat2(angle_cos, -1.0 * angle_sin, angle_sin, angle_cos);
+
+ vec4 projected_pos = u_label_plane_matrix * vec4(a_projected_pos.xy, 0.0, 1.0);
+ gl_Position = u_gl_coord_matrix * vec4(projected_pos.xy / projected_pos.w + rotation_matrix * (a_offset / 64.0 * fontScale), 0.0, 1.0);
v_tex = a_tex / u_texsize;
// See comments in symbol_sdf.vertex
highp float incidence_stretch = camera_to_anchor_distance / (u_camera_to_center_distance * cos(u_pitch));
highp float collision_adjustment = max(1.0, incidence_stretch / u_collision_y_stretch);
- highp float perspective_zoom_adjust = log2(perspective_ratio * collision_adjustment) * 10.0;
+ highp float collision_perspective_ratio = 1.0 + 0.5*((camera_to_anchor_distance / u_camera_to_center_distance) - 1.0);
+ highp float perspective_zoom_adjust = floor(log2(collision_perspective_ratio * collision_adjustment) * 10.0);
v_fade_tex = vec2((a_labelminzoom + perspective_zoom_adjust) / 255.0, 0.0);
}