[core] Use separate attribute component for line normals
Selective cherry pick of 822df3dd51
This commit is contained in:
@@ -19,7 +19,8 @@ constexpr float tileSize = 512;
|
||||
*
|
||||
* Positions are stored as signed 16bit integers.
|
||||
* One bit is lost for signedness to support features extending past the left edge of the tile.
|
||||
* One bit is lost because the line vertex buffer packs 1 bit of other data into the int.
|
||||
* One bit is lost because the line vertex buffer used to pack 1 bit of other data into the int.
|
||||
* This is no longer the case but we're reserving this bit anyway.
|
||||
* One bit is lost to support features extending past the extent on the right edge of the tile.
|
||||
* This leaves us with 2^13 = 8192
|
||||
*/
|
||||
|
||||
@@ -23,6 +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(int16_t, 3, a_pos_normal);
|
||||
MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, a_texture_pos);
|
||||
MBGL_DEFINE_ATTRIBUTE(int16_t, 3, a_normal);
|
||||
MBGL_DEFINE_ATTRIBUTE(uint16_t, 1, a_edgedistance);
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace mbgl {
|
||||
|
||||
using namespace style;
|
||||
|
||||
static_assert(sizeof(LineLayoutVertex) == 8, "expected LineLayoutVertex size");
|
||||
static_assert(sizeof(LineLayoutVertex) == 10, "expected LineLayoutVertex size");
|
||||
|
||||
template <class Values, class...Args>
|
||||
Values makeValues(const LinePaintProperties::Evaluated& properties,
|
||||
|
||||
@@ -31,7 +31,7 @@ MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_gl_units_to_pixels);
|
||||
} // namespace uniforms
|
||||
|
||||
struct LineLayoutAttributes : gl::Attributes<
|
||||
attributes::a_pos,
|
||||
attributes::a_pos_normal,
|
||||
attributes::a_data<uint8_t, 4>>
|
||||
{};
|
||||
|
||||
@@ -52,14 +52,16 @@ public:
|
||||
/*
|
||||
* @param p vertex position
|
||||
* @param e extrude normal
|
||||
* @param t texture normal
|
||||
* @param round whether the vertex uses a round line cap
|
||||
* @param up whether the line normal points up or down
|
||||
* @param dir direction of the line cap (-1/0/1)
|
||||
*/
|
||||
static LayoutVertex layoutVertex(Point<int16_t> p, Point<double> e, Point<bool> t, int8_t dir, int32_t linesofar = 0) {
|
||||
static LayoutVertex layoutVertex(Point<int16_t> p, Point<double> e, bool round, bool up, int8_t dir, int32_t linesofar = 0) {
|
||||
return LayoutVertex {
|
||||
{{
|
||||
static_cast<int16_t>((p.x * 2) | t.x),
|
||||
static_cast<int16_t>((p.y * 2) | t.y)
|
||||
p.x,
|
||||
p.y,
|
||||
static_cast<int16_t>(attributes::packUint8Pair(round ? 1 : 0, up ? 1 : 0))
|
||||
}},
|
||||
{{
|
||||
// add 128 to store a byte in an unsigned byte
|
||||
|
||||
@@ -398,7 +398,7 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate,
|
||||
Point<double> extrude = normal;
|
||||
if (endLeft)
|
||||
extrude = extrude - (util::perp(normal) * endLeft);
|
||||
vertices.emplace_back(LineProgram::layoutVertex(currentCoordinate, extrude, { round, false }, endLeft, distance * LINE_DISTANCE_SCALE));
|
||||
vertices.emplace_back(LineProgram::layoutVertex(currentCoordinate, extrude, round, false, endLeft, distance * LINE_DISTANCE_SCALE));
|
||||
e3 = vertices.vertexSize() - 1 - startVertex;
|
||||
if (e1 >= 0 && e2 >= 0) {
|
||||
triangleStore.emplace_back(e1, e2, e3);
|
||||
@@ -409,7 +409,7 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate,
|
||||
extrude = normal * -1.0;
|
||||
if (endRight)
|
||||
extrude = extrude - (util::perp(normal) * endRight);
|
||||
vertices.emplace_back(LineProgram::layoutVertex(currentCoordinate, extrude, { round, true }, -endRight, distance * LINE_DISTANCE_SCALE));
|
||||
vertices.emplace_back(LineProgram::layoutVertex(currentCoordinate, extrude, round, true, -endRight, distance * LINE_DISTANCE_SCALE));
|
||||
e3 = vertices.vertexSize() - 1 - startVertex;
|
||||
if (e1 >= 0 && e2 >= 0) {
|
||||
triangleStore.emplace_back(e1, e2, e3);
|
||||
@@ -434,7 +434,7 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex,
|
||||
std::size_t startVertex,
|
||||
std::vector<TriangleElement>& triangleStore) {
|
||||
Point<double> flippedExtrude = extrude * (lineTurnsLeft ? -1.0 : 1.0);
|
||||
vertices.emplace_back(LineProgram::layoutVertex(currentVertex, flippedExtrude, { false, lineTurnsLeft }, 0, distance * LINE_DISTANCE_SCALE));
|
||||
vertices.emplace_back(LineProgram::layoutVertex(currentVertex, flippedExtrude, false, lineTurnsLeft, 0, distance * LINE_DISTANCE_SCALE));
|
||||
e3 = vertices.vertexSize() - 1 - startVertex;
|
||||
if (e1 >= 0 && e2 >= 0) {
|
||||
triangleStore.emplace_back(e1, e2, e3);
|
||||
|
||||
@@ -21,7 +21,7 @@ const char* line::vertexSource = R"MBGL_SHADER(
|
||||
// #define scale 63.0
|
||||
#define scale 0.015873016
|
||||
|
||||
attribute vec2 a_pos;
|
||||
attribute vec3 a_pos_normal;
|
||||
attribute vec4 a_data;
|
||||
|
||||
uniform mat4 u_matrix;
|
||||
@@ -107,20 +107,21 @@ void main() {
|
||||
vec2 a_extrude = a_data.xy - 128.0;
|
||||
float a_direction = mod(a_data.z, 4.0) - 1.0;
|
||||
|
||||
// We store the texture normals in the most insignificant bit
|
||||
// transform y so that 0 => -1 and 1 => 1
|
||||
vec2 pos = a_pos_normal.xy;
|
||||
|
||||
// transform y normal so that 0 => -1 and 1 => 1
|
||||
// In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap
|
||||
// y is 1 if the normal points up, and -1 if it points down
|
||||
mediump vec2 normal = mod(a_pos, 2.0);
|
||||
mediump vec2 normal = unpack_float(a_pos_normal.z);
|
||||
normal.y = sign(normal.y - 0.5);
|
||||
|
||||
v_normal = normal;
|
||||
|
||||
|
||||
// these transformations used to be applied in the JS and native code bases.
|
||||
// moved them into the shader for clarity and simplicity.
|
||||
// these transformations used to be applied in the JS and native code bases.
|
||||
// moved them into the shader for clarity and simplicity.
|
||||
gapwidth = gapwidth / 2.0;
|
||||
float width = u_width / 2.0;
|
||||
offset = -1.0 * offset;
|
||||
offset = -1.0 * offset;
|
||||
|
||||
float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);
|
||||
float outset = gapwidth + width * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;
|
||||
@@ -137,9 +138,6 @@ void main() {
|
||||
mediump float t = 1.0 - abs(u);
|
||||
mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);
|
||||
|
||||
// Remove the texture normal bit to get the position
|
||||
vec2 pos = floor(a_pos * 0.5);
|
||||
|
||||
vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);
|
||||
gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ const char* line_pattern::vertexSource = R"MBGL_SHADER(
|
||||
// Retina devices need a smaller distance to avoid aliasing.
|
||||
#define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0
|
||||
|
||||
attribute vec2 a_pos;
|
||||
attribute vec3 a_pos_normal;
|
||||
attribute vec4 a_data;
|
||||
|
||||
uniform mat4 u_matrix;
|
||||
@@ -97,19 +97,21 @@ void main() {
|
||||
float a_direction = mod(a_data.z, 4.0) - 1.0;
|
||||
float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE;
|
||||
|
||||
// We store the texture normals in the most insignificant bit
|
||||
// transform y so that 0 => -1 and 1 => 1
|
||||
vec2 pos = a_pos_normal.xy;
|
||||
|
||||
// transform y normal so that 0 => -1 and 1 => 1
|
||||
// In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap
|
||||
// y is 1 if the normal points up, and -1 if it points down
|
||||
mediump vec2 normal = mod(a_pos, 2.0);
|
||||
mediump vec2 normal = unpack_float(a_pos_normal.z);
|
||||
normal.y = sign(normal.y - 0.5);
|
||||
|
||||
v_normal = normal;
|
||||
|
||||
// these transformations used to be applied in the JS and native code bases.
|
||||
// moved them into the shader for clarity and simplicity.
|
||||
// these transformations used to be applied in the JS and native code bases.
|
||||
// moved them into the shader for clarity and simplicity.
|
||||
gapwidth = gapwidth / 2.0;
|
||||
float width = u_width / 2.0;
|
||||
offset = -1.0 * offset;
|
||||
offset = -1.0 * offset;
|
||||
|
||||
float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);
|
||||
float outset = gapwidth + width * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;
|
||||
@@ -126,9 +128,6 @@ void main() {
|
||||
mediump float t = 1.0 - abs(u);
|
||||
mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);
|
||||
|
||||
// Remove the texture normal bit to get the position
|
||||
vec2 pos = floor(a_pos * 0.5);
|
||||
|
||||
vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);
|
||||
gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ const char* line_sdf::vertexSource = R"MBGL_SHADER(
|
||||
// Retina devices need a smaller distance to avoid aliasing.
|
||||
#define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0
|
||||
|
||||
attribute vec2 a_pos;
|
||||
attribute vec3 a_pos_normal;
|
||||
attribute vec4 a_data;
|
||||
|
||||
uniform mat4 u_matrix;
|
||||
@@ -116,20 +116,22 @@ void main() {
|
||||
float a_direction = mod(a_data.z, 4.0) - 1.0;
|
||||
float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE;
|
||||
|
||||
// We store the texture normals in the most insignificant bit
|
||||
// transform y so that 0 => -1 and 1 => 1
|
||||
vec2 pos = a_pos_normal.xy;
|
||||
|
||||
// transform y normal so that 0 => -1 and 1 => 1
|
||||
// In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap
|
||||
// y is 1 if the normal points up, and -1 if it points down
|
||||
mediump vec2 normal = mod(a_pos, 2.0);
|
||||
mediump vec2 normal = unpack_float(a_pos_normal.z);
|
||||
normal.y = sign(normal.y - 0.5);
|
||||
|
||||
v_normal = normal;
|
||||
|
||||
// these transformations used to be applied in the JS and native code bases.
|
||||
// moved them into the shader for clarity and simplicity.
|
||||
// these transformations used to be applied in the JS and native code bases.
|
||||
// moved them into the shader for clarity and simplicity.
|
||||
gapwidth = gapwidth / 2.0;
|
||||
float width = u_width / 2.0;
|
||||
offset = -1.0 * offset;
|
||||
|
||||
|
||||
float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);
|
||||
float outset = gapwidth + width * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;
|
||||
|
||||
@@ -145,9 +147,6 @@ void main() {
|
||||
mediump float t = 1.0 - abs(u);
|
||||
mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t);
|
||||
|
||||
// Remove the texture normal bit to get the position
|
||||
vec2 pos = floor(a_pos * 0.5);
|
||||
|
||||
vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0);
|
||||
gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user