[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.
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/map/transform_state.hpp>
|
||||
#include <mbgl/style/layers/symbol_layer_impl.hpp>
|
||||
#include <mbgl/layout/symbol_projection.hpp>
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/util/enum.hpp>
|
||||
#include <mbgl/math/clamp.hpp>
|
||||
@@ -10,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,
|
||||
@@ -33,6 +34,7 @@ Values makeValues(const bool isText,
|
||||
const style::SymbolPropertyValues& values,
|
||||
const Size& texsize,
|
||||
const std::array<float, 2>& pixelsToGLUnits,
|
||||
const bool alongLine,
|
||||
const RenderTile& tile,
|
||||
const TransformState& state,
|
||||
Args&&... args) {
|
||||
@@ -46,21 +48,41 @@ Values makeValues(const bool isText,
|
||||
pixelsToGLUnits[1] * state.getCameraToCenterDistance()
|
||||
}};
|
||||
}
|
||||
|
||||
const float pixelsToTileUnits = tile.id.pixelsToTileUnits(1.0, state.getZoom());
|
||||
const bool pitchWithMap = values.pitchAlignment == style::AlignmentType::Map;
|
||||
const bool rotateWithMap = values.rotationAlignment == style::AlignmentType::Map;
|
||||
|
||||
mat4 labelPlaneMatrix;
|
||||
if (alongLine) {
|
||||
// For labels that follow lines the first part of the projection is handled on the cpu.
|
||||
// Pass an identity matrix because no transformation needs to be done in the vertex shader.
|
||||
matrix::identity(labelPlaneMatrix);
|
||||
} else {
|
||||
labelPlaneMatrix = getLabelPlaneMatrix(tile.matrix, pitchWithMap, rotateWithMap, state, pixelsToTileUnits);
|
||||
}
|
||||
|
||||
mat4 glCoordMatrix = getGlCoordMatrix(tile.matrix, pitchWithMap, rotateWithMap, state, pixelsToTileUnits);
|
||||
|
||||
return Values {
|
||||
uniforms::u_matrix::Value{ tile.translatedMatrix(values.translate,
|
||||
values.translateAnchor,
|
||||
state) },
|
||||
uniforms::u_label_plane_matrix::Value{labelPlaneMatrix},
|
||||
uniforms::u_gl_coord_matrix::Value{ tile.translateVtxMatrix(glCoordMatrix,
|
||||
values.translate,
|
||||
values.translateAnchor,
|
||||
state,
|
||||
true) },
|
||||
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 },
|
||||
uniforms::u_collision_y_stretch::Value{ tile.tile.yStretch() },
|
||||
uniforms::u_camera_to_center_distance::Value{ state.getCameraToCenterDistance() },
|
||||
uniforms::u_pitch::Value{ state.getPitch() },
|
||||
uniforms::u_pitch_with_map::Value{ pitchWithMap },
|
||||
uniforms::u_max_camera_distance::Value{ values.maxCameraDistance },
|
||||
std::forward<Args>(args)...
|
||||
};
|
||||
@@ -71,6 +93,7 @@ SymbolIconProgram::uniformValues(const bool isText,
|
||||
const style::SymbolPropertyValues& values,
|
||||
const Size& texsize,
|
||||
const std::array<float, 2>& pixelsToGLUnits,
|
||||
const bool alongLine,
|
||||
const RenderTile& tile,
|
||||
const TransformState& state)
|
||||
{
|
||||
@@ -79,6 +102,7 @@ SymbolIconProgram::uniformValues(const bool isText,
|
||||
values,
|
||||
texsize,
|
||||
pixelsToGLUnits,
|
||||
alongLine,
|
||||
tile,
|
||||
state
|
||||
);
|
||||
@@ -90,25 +114,24 @@ typename SymbolSDFProgram<PaintProperties>::UniformValues SymbolSDFProgram<Paint
|
||||
const style::SymbolPropertyValues& values,
|
||||
const Size& texsize,
|
||||
const std::array<float, 2>& pixelsToGLUnits,
|
||||
const bool alongLine,
|
||||
const RenderTile& tile,
|
||||
const TransformState& state,
|
||||
const SymbolSDFPart part)
|
||||
{
|
||||
const float gammaScale = (values.pitchAlignment == AlignmentType::Map
|
||||
? std::cos(state.getPitch())
|
||||
: 1.0) * state.getCameraToCenterDistance();
|
||||
? std::cos(state.getPitch()) * state.getCameraToCenterDistance()
|
||||
: 1.0);
|
||||
|
||||
return makeValues<SymbolSDFProgram<PaintProperties>::UniformValues>(
|
||||
isText,
|
||||
values,
|
||||
texsize,
|
||||
pixelsToGLUnits,
|
||||
alongLine,
|
||||
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 }
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user