diff options
author | Ansis Brammanis <brammanis@gmail.com> | 2017-06-23 11:55:01 -0400 |
---|---|---|
committer | Ansis Brammanis <brammanis@gmail.com> | 2017-06-23 11:55:01 -0400 |
commit | a14db0d12e08845543759da40cde7fc72caf727c (patch) | |
tree | 37fb524ea9b9222fdf32da9155d10a1afa26639f | |
parent | b07472823c3560c9b79253ba2f9ac544ad6bd5ae (diff) | |
download | qtlocation-mapboxgl-a14db0d12e08845543759da40cde7fc72caf727c.tar.gz |
use real size for symbol projection and update shaders
-rw-r--r-- | src/mbgl/layout/symbol_layout.cpp | 8 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_projection.cpp | 27 | ||||
-rw-r--r-- | src/mbgl/layout/symbol_projection.hpp | 3 | ||||
-rw-r--r-- | src/mbgl/programs/attributes.hpp | 2 | ||||
-rw-r--r-- | src/mbgl/programs/symbol_program.cpp | 12 | ||||
-rw-r--r-- | src/mbgl/programs/symbol_program.hpp | 39 | ||||
-rw-r--r-- | src/mbgl/renderer/painters/painter_symbol.cpp | 6 | ||||
-rw-r--r-- | src/mbgl/shaders/symbol_icon.cpp | 70 | ||||
-rw-r--r-- | src/mbgl/shaders/symbol_sdf.cpp | 176 |
9 files changed, 126 insertions, 217 deletions
diff --git a/src/mbgl/layout/symbol_layout.cpp b/src/mbgl/layout/symbol_layout.cpp index 01615e1ea3..d3ed8455a0 100644 --- a/src/mbgl/layout/symbol_layout.cpp +++ b/src/mbgl/layout/symbol_layout.cpp @@ -592,10 +592,10 @@ void SymbolLayout::addSymbol(Buffer& buffer, uint16_t index = segment.vertexLength; // coordinates (2 triangles) - buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, tl, labelAnchor, tex.x, tex.y, sizeData)); - buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, tr, labelAnchor, tex.x + tex.w, tex.y, sizeData)); - buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, bl, labelAnchor, tex.x, tex.y + tex.h, sizeData)); - buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(anchorPoint, br, labelAnchor, tex.x + tex.w, tex.y + tex.h, sizeData)); + buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(labelAnchor, tl, tex.x, tex.y, sizeData)); + buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(labelAnchor, tr, tex.x + tex.w, tex.y, sizeData)); + buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(labelAnchor, bl, tex.x, tex.y + tex.h, sizeData)); + buffer.vertices.emplace_back(SymbolLayoutAttributes::vertex(labelAnchor, br, tex.x + tex.w, tex.y + tex.h, sizeData)); auto dynamicVertex = SymbolDynamicLayoutAttributes::vertex(anchorPoint, 0, placementZoom); buffer.dynamicVertices.emplace_back(dynamicVertex); diff --git a/src/mbgl/layout/symbol_projection.cpp b/src/mbgl/layout/symbol_projection.cpp index 64d5a3b451..41dd525646 100644 --- a/src/mbgl/layout/symbol_projection.cpp +++ b/src/mbgl/layout/symbol_projection.cpp @@ -49,6 +49,18 @@ namespace mbgl { return { static_cast<float>(pos[0] / pos[3]), static_cast<float>(pos[1] / pos[3]) }; } + float evaluateSizeForFeature(const ZoomEvaluatedSize& zoomEvaluatedSize, const PlacedSymbol& placedSymbol) { + if (zoomEvaluatedSize.isFeatureConstant) { + return zoomEvaluatedSize.size; + } else { + if (zoomEvaluatedSize.isZoomConstant) { + return placedSymbol.lowerSize; + } else { + return placedSymbol.lowerSize + zoomEvaluatedSize.sizeT * (placedSymbol.upperSize - placedSymbol.lowerSize); + } + } + } + bool isVisible(const vec4& anchorPos, const float placementZoom, const std::array<double, 2>& clippingBuffer, const FrameHistory& frameHistory) { const float x = anchorPos[0] / anchorPos[3]; const float y = anchorPos[1] / anchorPos[3]; @@ -160,17 +172,14 @@ namespace mbgl { } void reprojectLineLabels(SymbolBucket& bucket, const mat4& posMatrix, const bool isText, const style::SymbolPropertyValues& values, - //const RenderTile& tile, const TransformState& state) { - const RenderTile&, const TransformState& state, const FrameHistory& frameHistory) { - // const sizeData = isText ? bucket.textSizeData : bucket.iconSizeData; - // const partiallyEvaluatedSize = symbolSize.evaluateSizeForZoom(sizeData, painter.transform, layer, isText); + const RenderTile& tile, const SymbolSizeBinder& sizeBinder, const TransformState& state, const FrameHistory& frameHistory) { + + const ZoomEvaluatedSize partiallyEvaluatedSize = sizeBinder.evaluateForZoom(state.getZoom()); const std::array<double, 2> clippingBuffer = {{ 256.0 / state.getSize().width * 2.0 + 1.0, 256.0 / state.getSize().height }}; - //TODO - const float pixelsToTileUnits = 1.0; const mat4 labelPlaneMatrix = getLabelPlaneMatrix(posMatrix, values.pitchAlignment == style::AlignmentType::Map, - values.rotationAlignment == style::AlignmentType::Map, state, pixelsToTileUnits); + values.rotationAlignment == style::AlignmentType::Map, state, tile.id.pixelsToTileUnits(1, state.getZoom())); gl::VertexVector<SymbolDynamicLayoutAttributes::Vertex>& dynamicVertexArray = isText ? bucket.text.dynamicVertices : @@ -200,9 +209,7 @@ namespace mbgl { const float cameraToAnchorDistance = anchorPos[3]; const float perspectiveRatio = 1 + 0.5 * ((cameraToAnchorDistance / state.getCameraToCenterDistance()) - 1.0); - - //const fontSize = symbolSize.evaluateSizeForFeature(sizeData, partiallyEvaluatedSize, symbol); - const float fontSize = 16; + const float fontSize = evaluateSizeForFeature(partiallyEvaluatedSize, placedSymbol); const float pitchScaledFontSize = values.pitchAlignment == style::AlignmentType::Map ? fontSize * perspectiveRatio : fontSize / perspectiveRatio; diff --git a/src/mbgl/layout/symbol_projection.hpp b/src/mbgl/layout/symbol_projection.hpp index ce584d82cf..8d5f471d3f 100644 --- a/src/mbgl/layout/symbol_projection.hpp +++ b/src/mbgl/layout/symbol_projection.hpp @@ -8,6 +8,7 @@ namespace mbgl { class SymbolBucket; class RenderTile; class FrameHistory; + class SymbolSizeBinder; namespace style { class SymbolPropertyValues; } @@ -16,6 +17,6 @@ namespace mbgl { mat4 getGlCoordMatrix(const mat4& posMatrix, const bool pitchWithMap, const bool rotateWithMap, const TransformState& state, const float pixelsToTileUnits); void reprojectLineLabels(SymbolBucket&, const mat4& posMatrix, const bool isText, const style::SymbolPropertyValues&, - const RenderTile&, const TransformState&, const FrameHistory& frameHistory); + const RenderTile&, const SymbolSizeBinder& sizeBinder, const TransformState&, const FrameHistory& frameHistory); } // end namespace mbgl diff --git a/src/mbgl/programs/attributes.hpp b/src/mbgl/programs/attributes.hpp index 581da0b550..6e15055bcc 100644 --- a/src/mbgl/programs/attributes.hpp +++ b/src/mbgl/programs/attributes.hpp @@ -23,7 +23,7 @@ inline uint16_t packUint8Pair(T a, T b) { MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_pos); MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_extrude); MBGL_DEFINE_ATTRIBUTE(int16_t, 4, a_pos_offset); -MBGL_DEFINE_ATTRIBUTE(uint16_t, 3, a_projected_pos); +MBGL_DEFINE_ATTRIBUTE(float, 3, a_projected_pos); MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_label_pos); MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_anchor_pos); MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, a_texture_pos); diff --git a/src/mbgl/programs/symbol_program.cpp b/src/mbgl/programs/symbol_program.cpp index e7f53fc541..2aee09fa7f 100644 --- a/src/mbgl/programs/symbol_program.cpp +++ b/src/mbgl/programs/symbol_program.cpp @@ -11,7 +11,7 @@ namespace mbgl { using namespace style; -static_assert(sizeof(SymbolLayoutVertex) == 20, "expected SymbolLayoutVertex size"); +static_assert(sizeof(SymbolLayoutVertex) == 16, "expected SymbolLayoutVertex size"); std::unique_ptr<SymbolSizeBinder> SymbolSizeBinder::create(const float tileZoom, const style::DataDrivenPropertyValue<float>& sizeProperty, @@ -70,8 +70,6 @@ Values makeValues(const bool isText, uniforms::u_gl_coord_matrix::Value{glCoordMatrix}, uniforms::u_extrude_scale::Value{ extrudeScale }, uniforms::u_texsize::Value{ texsize }, - uniforms::u_zoom::Value{ float(state.getZoom()) }, - uniforms::u_rotate_with_map::Value{ values.rotationAlignment == AlignmentType::Map }, uniforms::u_texture::Value{ 0 }, uniforms::u_fadetexture::Value{ 1 }, uniforms::u_is_text::Value{ isText }, @@ -114,9 +112,9 @@ typename SymbolSDFProgram<PaintProperties>::UniformValues SymbolSDFProgram<Paint const TransformState& state, const SymbolSDFPart part) { - const float gammaScale = (values.pitchAlignment == AlignmentType::Map - ? std::cos(state.getPitch()) - : 1.0) * state.getCameraToCenterDistance(); + const float gammaScale = values.pitchAlignment == AlignmentType::Map + ? std::cos(state.getPitch()) * state.getCameraToCenterDistance() + : 1.0; return makeValues<SymbolSDFProgram<PaintProperties>::UniformValues>( isText, @@ -127,8 +125,6 @@ typename SymbolSDFProgram<PaintProperties>::UniformValues SymbolSDFProgram<Paint tile, state, uniforms::u_gamma_scale::Value{ gammaScale }, - uniforms::u_bearing::Value{ -1.0f * state.getAngle() }, - uniforms::u_aspect_ratio::Value{ (state.getSize().width * 1.0f) / (state.getSize().height * 1.0f) }, uniforms::u_pitch_with_map::Value{ values.pitchAlignment == AlignmentType::Map }, uniforms::u_is_halo::Value{ part == SymbolSDFPart::Halo } ); diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 348f9b4fc9..95727d2c84 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -31,10 +31,8 @@ class TransformState; namespace uniforms { MBGL_DEFINE_UNIFORM_MATRIX(double, 4, u_gl_coord_matrix); MBGL_DEFINE_UNIFORM_MATRIX(double, 4, u_label_plane_matrix); -MBGL_DEFINE_UNIFORM_SCALAR(bool, u_rotate_with_map); MBGL_DEFINE_UNIFORM_SCALAR(bool, u_pitch_with_map); MBGL_DEFINE_UNIFORM_SCALAR(gl::TextureUnit, u_texture); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_aspect_ratio); MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_halo); MBGL_DEFINE_UNIFORM_SCALAR(float, u_gamma_scale); @@ -43,34 +41,27 @@ MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_size_zoom_constant); MBGL_DEFINE_UNIFORM_SCALAR(bool, u_is_size_feature_constant); MBGL_DEFINE_UNIFORM_SCALAR(float, u_size_t); MBGL_DEFINE_UNIFORM_SCALAR(float, u_size); -MBGL_DEFINE_UNIFORM_SCALAR(float, u_layout_size); MBGL_DEFINE_UNIFORM_SCALAR(float, u_max_camera_distance); } // namespace uniforms struct SymbolLayoutAttributes : gl::Attributes< attributes::a_pos_offset, - attributes::a_label_pos, attributes::a_data<uint16_t, 4>> { - static Vertex vertex(Point<float> a, + static Vertex vertex(Point<float> labelAnchor, Point<float> o, - Point<float> labelAnchor, uint16_t tx, uint16_t ty, const Range<float>& sizeData) { return Vertex { // combining pos and offset to reduce number of vertex attributes passed to shader (8 max for some devices) {{ - static_cast<int16_t>(a.x), - static_cast<int16_t>(a.y), + static_cast<int16_t>(labelAnchor.x), + static_cast<int16_t>(labelAnchor.y), static_cast<int16_t>(::round(o.x * 64)), // use 1/64 pixels for placement static_cast<int16_t>(::round(o.y * 64)) }}, {{ - static_cast<int16_t>(labelAnchor.x), - static_cast<int16_t>(labelAnchor.y) - }}, - {{ tx, ty, static_cast<uint16_t>(sizeData.min * 10), @@ -84,11 +75,11 @@ struct SymbolDynamicLayoutAttributes : gl::Attributes<attributes::a_projected_po static Vertex vertex(Point<float> anchorPoint, float labelAngle, float labelminzoom) { return Vertex { {{ - static_cast<uint16_t>(anchorPoint.x), - static_cast<uint16_t>(anchorPoint.y), - mbgl::attributes::packUint8Pair( + anchorPoint.x, + anchorPoint.y, + static_cast<float>(mbgl::attributes::packUint8Pair( static_cast<uint8_t>(std::fmod(labelAngle + 2 * M_PI, 2 * M_PI) / (2 * M_PI) * 255), - static_cast<uint8_t>(labelminzoom * 10)) + static_cast<uint8_t>(labelminzoom * 10))) }} }; } @@ -113,8 +104,7 @@ public: uniforms::u_is_size_zoom_constant, uniforms::u_is_size_feature_constant, uniforms::u_size_t, - uniforms::u_size, - uniforms::u_layout_size>; + uniforms::u_size>; using UniformValues = Uniforms::Values; static std::unique_ptr<SymbolSizeBinder> create(const float tileZoom, @@ -130,8 +120,7 @@ public: uniforms::u_is_size_zoom_constant::Value{ u.isZoomConstant }, uniforms::u_is_size_feature_constant::Value{ u.isFeatureConstant}, uniforms::u_size_t::Value{ u.sizeT }, - uniforms::u_size::Value{ u.size }, - uniforms::u_layout_size::Value{ u.layoutSize } + uniforms::u_size::Value{ u.size } }; } }; @@ -352,8 +341,6 @@ class SymbolIconProgram : public SymbolProgram< uniforms::u_gl_coord_matrix, uniforms::u_extrude_scale, uniforms::u_texsize, - uniforms::u_zoom, - uniforms::u_rotate_with_map, uniforms::u_texture, uniforms::u_fadetexture, uniforms::u_is_text, @@ -391,8 +378,6 @@ class SymbolSDFProgram : public SymbolProgram< uniforms::u_gl_coord_matrix, uniforms::u_extrude_scale, uniforms::u_texsize, - uniforms::u_zoom, - uniforms::u_rotate_with_map, uniforms::u_texture, uniforms::u_fadetexture, uniforms::u_is_text, @@ -401,8 +386,6 @@ class SymbolSDFProgram : public SymbolProgram< uniforms::u_pitch, uniforms::u_max_camera_distance, uniforms::u_gamma_scale, - uniforms::u_bearing, - uniforms::u_aspect_ratio, uniforms::u_pitch_with_map, uniforms::u_is_halo>, PaintProperties> @@ -417,8 +400,6 @@ public: uniforms::u_gl_coord_matrix, uniforms::u_extrude_scale, uniforms::u_texsize, - uniforms::u_zoom, - uniforms::u_rotate_with_map, uniforms::u_texture, uniforms::u_fadetexture, uniforms::u_is_text, @@ -427,8 +408,6 @@ public: uniforms::u_pitch, uniforms::u_max_camera_distance, uniforms::u_gamma_scale, - uniforms::u_bearing, - uniforms::u_aspect_ratio, uniforms::u_pitch_with_map, uniforms::u_is_halo>, PaintProperties>; diff --git a/src/mbgl/renderer/painters/painter_symbol.cpp b/src/mbgl/renderer/painters/painter_symbol.cpp index 3db33cdd32..58f4235717 100644 --- a/src/mbgl/renderer/painters/painter_symbol.cpp +++ b/src/mbgl/renderer/painters/painter_symbol.cpp @@ -75,7 +75,7 @@ void Painter::renderSymbol(PaintParameters& parameters, bucket.layout.get<IconRotationAlignment>() == AlignmentType::Map; if (alongLine) { - reprojectLineLabels(bucket, tile.matrix, false, values, tile, state, frameHistory); + reprojectLineLabels(bucket, tile.matrix, false, values, tile, *(bucket.iconSizeBinder), state, frameHistory); context.updateVertexBuffer(std::move(bucket.icon.dynamicVertices), *bucket.icon.dynamicVertexBuffer); } @@ -129,8 +129,10 @@ void Painter::renderSymbol(PaintParameters& parameters, bucket.layout.get<TextRotationAlignment>() == AlignmentType::Map; if (alongLine) { - reprojectLineLabels(bucket, tile.matrix, true, values, tile, state, frameHistory); + reprojectLineLabels(bucket, tile.matrix, true, values, tile, *(bucket.textSizeBinder), state, frameHistory); context.updateVertexBuffer(std::move(bucket.text.dynamicVertices), *bucket.text.dynamicVertexBuffer); + } else { + return; } const Size texsize = geometryTile.glyphAtlasTexture->size; diff --git a/src/mbgl/shaders/symbol_icon.cpp b/src/mbgl/shaders/symbol_icon.cpp index 720ba2eeeb..a5f1c30c59 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; @@ -32,13 +31,12 @@ 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; @@ -58,61 +56,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 = floor(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); } diff --git a/src/mbgl/shaders/symbol_sdf.cpp b/src/mbgl/shaders/symbol_sdf.cpp index 17ba69c202..40d7e4f2aa 100644 --- a/src/mbgl/shaders/symbol_sdf.cpp +++ b/src/mbgl/shaders/symbol_sdf.cpp @@ -10,7 +10,6 @@ const char* symbol_sdf::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; @@ -20,14 +19,11 @@ attribute vec3 a_projected_pos; // For source functions, we bind only one value per vertex: the value of {text,icon}-size evaluated for the current feature. // For composite functions: // [ text-size(lowerZoomStop, feature), -// text-size(upperZoomStop, feature), -// layoutSize == text-size(layoutZoomLevel, feature) ] -attribute vec3 a_size; +// text-size(upperZoomStop, feature) ] 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 #ifndef HAS_UNIFORM_u_fill_color @@ -75,39 +71,20 @@ uniform lowp float u_halo_blur; #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 bool u_pitch_with_map; uniform highp float u_pitch; -uniform highp float u_bearing; -uniform highp float u_aspect_ratio; uniform highp float u_camera_to_center_distance; -uniform highp float u_max_camera_distance; uniform highp float u_collision_y_stretch; -uniform vec2 u_extrude_scale; uniform vec2 u_texsize; -varying vec2 v_tex; -varying vec2 v_fade_tex; -varying float v_gamma_scale; -varying float v_size; - -// Used below to move the vertex out of the clip space for when the current -// zoom is out of the glyph's zoom range. -highp float clipUnusedGlyphAngles(const highp float render_size, - const highp float layout_size, - const highp float min_zoom, - const highp float max_zoom) { - highp float zoom_adjust = log2(render_size / layout_size); - highp float adjusted_zoom = (u_zoom - zoom_adjust) * 10.0; - // result: 0 if min_zoom <= adjusted_zoom < max_zoom, and 1 otherwise - return 2.0 - step(min_zoom, adjusted_zoom) - (1.0 - step(max_zoom, adjusted_zoom)); -} +varying vec4 v_data0; +varying vec2 v_data1; void main() { @@ -150,95 +127,49 @@ void main() { vec2 a_offset = a_pos_offset.zw; vec2 a_tex = a_data.xy; + 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; - //highp vec2 label_data = unpack_float(a_data[2]); - //highp float a_labelminzoom = label_data[0]; - //highp float a_lineangle = (label_data[1] / 256.0 * 2.0 * PI); - highp vec2 a_angle_zoom = unpack_float(a_projected_pos[2]); - highp float a_lineangle = a_angle_zoom[0] / 256.0 * 2.0 * PI; - highp float a_labelminzoom = a_angle_zoom[1]; - //highp vec2 a_zoom = unpack_float(a_data[3]); - highp float a_minzoom = 0.0;//a_zoom[0]; - highp float a_maxzoom = 250.0;//a_zoom[1]; - - // 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) { - v_size = mix(a_size[0], a_size[1], u_size_t) / 10.0; - layoutSize = a_size[2] / 10.0; + size = mix(a_size[0], a_size[1], u_size_t) / 10.0; } else if (u_is_size_zoom_constant && !u_is_size_feature_constant) { - v_size = a_size[0] / 10.0; - layoutSize = v_size; + size = a_size[0] / 10.0; } else if (!u_is_size_zoom_constant && u_is_size_feature_constant) { - v_size = u_size; - layoutSize = u_layout_size; + size = u_size; } else { - v_size = u_size; - layoutSize = u_size; + size = u_size; } - float fontScale = u_is_text ? v_size / 24.0 : v_size; - - vec4 projectedPoint = u_matrix * vec4(a_label_pos, 0, 1); + vec4 projectedPoint = u_matrix * vec4(a_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); - - // pitch-alignment: map - // rotation-alignment: map | viewport - if (u_pitch_with_map) { - highp float angle = u_rotate_with_map ? a_lineangle : u_bearing; - highp float asin = sin(angle); - highp float acos = cos(angle); - mat2 RotationMatrix = mat2(acos, asin, -1.0 * asin, acos); - vec2 offset = RotationMatrix * a_offset; - vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (offset / 64.0); - - gl_Position = u_matrix * vec4(a_pos + extrude, 0, 1); - gl_Position.z += clipUnusedGlyphAngles(v_size*perspective_ratio, layoutSize, a_minzoom, a_maxzoom) * gl_Position.w; - // pitch-alignment: viewport - // rotation-alignment: map - } else if (u_rotate_with_map) { - // foreshortening factor to apply on pitched maps - // as a label goes from horizontal <=> vertical in angle - // it goes from 0% foreshortening to up to around 70% foreshortening - highp float pitchfactor = 1.0 - cos(u_pitch * sin(u_pitch * 0.75)); - - // use the lineangle to position points a,b along the line - // project the points and calculate the label angle in projected space - // this calculation allows labels to be rendered unskewed on pitched maps - vec4 a = u_matrix * vec4(a_pos, 0, 1); - vec4 b = u_matrix * vec4(a_pos + vec2(cos(a_lineangle), sin(a_lineangle)), 0, 1); - highp float angle = atan((b[1] / b[3] - a[1] / a[3]) / u_aspect_ratio, b[0] / b[3] - a[0] / a[3]); - highp float asin = sin(angle); - highp float acos = cos(angle); - mat2 RotationMatrix = mat2(acos, -1.0 * asin, asin, acos); - highp float foreshortening = (1.0 - pitchfactor) + (pitchfactor * cos(angle * 2.0)); - - vec2 offset = RotationMatrix * (vec2(foreshortening, 1.0) * a_offset); - vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (offset / 64.0); - - gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0); - gl_Position.z += clipUnusedGlyphAngles(v_size * perspective_ratio, layoutSize, a_minzoom, a_maxzoom) * gl_Position.w; - // pitch-alignment: viewport - // rotation-alignment: viewport - } else { - vec2 extrude = fontScale * u_extrude_scale * perspective_ratio * (a_offset / 64.0); - gl_Position = u_matrix * vec4(a_pos, 0, 1) + vec4(extrude, 0, 0); - } - - gl_Position.z += - step(u_max_camera_distance * u_camera_to_center_distance, camera_to_anchor_distance) * gl_Position.w; - - v_gamma_scale = gl_Position.w / perspective_ratio; - - v_tex = a_tex / u_texsize; + // If the label is pitched with the map, layout is done in pitched space, + // which makes labels in the distance smaller relative to viewport space. + // We counteract part of that effect by multiplying by the perspective ratio. + // If the label isn't pitched with the map, we do layout in viewport space, + // which makes labels in the distance larger relative to the features around + // them. We counteract part of that effect by dividing by the perspective ratio. + 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; + + size *= perspective_ratio; + + float fontScale = u_is_text ? size / 24.0 : size; + + 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); + float gamma_scale = gl_Position.w; + + vec2 tex = a_tex / u_texsize; // incidence_stretch is the ratio of how much y space a label takes up on a tile while drawn perpendicular to the viewport vs // how much space it would take up if it were drawn flat on the tile // Using law of sines, camera_to_anchor/sin(ground_angle) = camera_to_center/sin(incidence_angle) @@ -258,8 +189,12 @@ void main() { highp float collision_adjustment = max(1.0, incidence_stretch / u_collision_y_stretch); // Floor to 1/10th zoom to dodge precision issues that can cause partially hidden labels - highp float perspective_zoom_adjust = floor(log2(perspective_ratio * collision_adjustment) * 10.0); - v_fade_tex = vec2((a_labelminzoom + perspective_zoom_adjust) / 255.0, 0.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); + vec2 fade_tex = vec2((a_labelminzoom + perspective_zoom_adjust) / 255.0, 0.0); + + v_data0 = vec4(tex.x, tex.y, fade_tex.x, fade_tex.y); + v_data1 = vec2(gamma_scale, size); } )MBGL_SHADER"; @@ -309,10 +244,8 @@ uniform sampler2D u_fadetexture; uniform highp float u_gamma_scale; uniform bool u_is_text; -varying vec2 v_tex; -varying vec2 v_fade_tex; -varying float v_gamma_scale; -varying float v_size; +varying vec4 v_data0; +varying vec2 v_data1; void main() { @@ -341,7 +274,12 @@ void main() { #endif - float fontScale = u_is_text ? v_size / 24.0 : v_size; + vec2 tex = v_data0.xy; + vec2 fade_tex = v_data0.zw; + float gamma_scale = v_data1.x; + float size = v_data1.y; + + float fontScale = u_is_text ? size / 24.0 : size; lowp vec4 color = fill_color; highp float gamma = EDGE_GAMMA / (fontScale * u_gamma_scale); @@ -352,9 +290,9 @@ void main() { buff = (6.0 - halo_width / fontScale) / SDF_PX; } - lowp float dist = texture2D(u_texture, v_tex).a; - lowp float fade_alpha = texture2D(u_fadetexture, v_fade_tex).a; - highp float gamma_scaled = gamma * v_gamma_scale; + lowp float dist = texture2D(u_texture, tex).a; + lowp float fade_alpha = texture2D(u_fadetexture, fade_tex).a; + highp float gamma_scaled = gamma * gamma_scale; highp float alpha = smoothstep(buff - gamma_scaled, buff + gamma_scaled, dist) * fade_alpha; gl_FragColor = color * (alpha * opacity); |