Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use separate attribute elements for line normals #5073

Merged
merged 2 commits into from
Aug 8, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions src/data/bucket/line_bucket.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const createElementArrayType = require('../element_array_type');
const loadGeometry = require('../load_geometry');
const EXTENT = require('../extent');
const vectorTileFeatureTypes = require('@mapbox/vector-tile').VectorTileFeature.types;
const {packUint8ToFloat} = require('../../shaders/encode_attribute');

import type {BucketParameters} from '../bucket';
import type {ProgramInterface} from '../program_configuration';
Expand Down Expand Up @@ -46,7 +47,7 @@ const MAX_LINE_DISTANCE = Math.pow(2, LINE_DISTANCE_BUFFER_BITS - 1) / LINE_DIST

const lineInterface = {
layoutAttributes: [
{name: 'a_pos', components: 2, type: 'Int16'},
{name: 'a_pos_normal', components: 3, type: 'Int16'},
{name: 'a_data', components: 4, type: 'Uint8'}
],
paintAttributes: [
Expand All @@ -61,11 +62,12 @@ const lineInterface = {
elementArrayType: createElementArrayType()
};

function addLineVertex(layoutVertexBuffer, point, extrude, tx, ty, dir, linesofar) {
function addLineVertex(layoutVertexBuffer, point: Point, extrude: Point, round: boolean, up: boolean, dir: number, linesofar: number) {
layoutVertexBuffer.emplaceBack(
// a_pos
(point.x << 1) | tx,
(point.y << 1) | ty,
// a_pos_normal
point.x,
point.y,
packUint8ToFloat(round ? 1 : 0, up ? 1 : 0),
// a_data
// add 128 to store a byte in an unsigned byte
Math.round(EXTRUDE_SCALE * extrude.x) + 128,
Expand Down Expand Up @@ -391,15 +393,14 @@ class LineBucket extends Bucket {
endRight: number,
round: boolean,
segment: Segment) {
const tx = round ? 1 : 0;
let extrude;
const arrays = this.arrays;
const layoutVertexArray = arrays.layoutVertexArray;
const elementArray = arrays.elementArray;

extrude = normal.clone();
if (endLeft) extrude._sub(normal.perp()._mult(endLeft));
addLineVertex(layoutVertexArray, currentVertex, extrude, tx, 0, endLeft, distance);
addLineVertex(layoutVertexArray, currentVertex, extrude, round, false, endLeft, distance);
this.e3 = segment.vertexLength++;
if (this.e1 >= 0 && this.e2 >= 0) {
elementArray.emplaceBack(this.e1, this.e2, this.e3);
Expand All @@ -410,7 +411,7 @@ class LineBucket extends Bucket {

extrude = normal.mult(-1);
if (endRight) extrude._sub(normal.perp()._mult(endRight));
addLineVertex(layoutVertexArray, currentVertex, extrude, tx, 1, -endRight, distance);
addLineVertex(layoutVertexArray, currentVertex, extrude, round, true, -endRight, distance);
this.e3 = segment.vertexLength++;
if (this.e1 >= 0 && this.e2 >= 0) {
elementArray.emplaceBack(this.e1, this.e2, this.e3);
Expand All @@ -433,24 +434,23 @@ class LineBucket extends Bucket {
* Add a single new vertex and a triangle using two previous vertices.
* This adds a pie slice triangle near a join to simulate round joins
*
* @param {Object} currentVertex the line vertex to add buffer vertices for
* @param {number} distance the distance from the beggining of the line to the vertex
* @param {Object} extrude the offset of the new vertex from the currentVertex
* @param {boolean} whether the line is turning left or right at this angle
* @param currentVertex the line vertex to add buffer vertices for
* @param distance the distance from the beggining of the line to the vertex
* @param extrude the offset of the new vertex from the currentVertex
* @param lineTurnsLeft whether the line is turning left or right at this angle
* @private
*/
addPieSliceVertex(currentVertex: Point,
distance: number,
extrude: Point,
lineTurnsLeft: boolean,
segment: Segment) {
const ty = lineTurnsLeft ? 1 : 0;
extrude = extrude.mult(lineTurnsLeft ? -1 : 1);
const arrays = this.arrays;
const layoutVertexArray = arrays.layoutVertexArray;
const elementArray = arrays.elementArray;

addLineVertex(layoutVertexArray, currentVertex, extrude, 0, ty, 0, distance);
addLineVertex(layoutVertexArray, currentVertex, extrude, false, lineTurnsLeft, 0, distance);
this.e3 = segment.vertexLength++;
if (this.e1 >= 0 && this.e2 >= 0) {
elementArray.emplaceBack(this.e1, this.e2, this.e3);
Expand Down
3 changes: 2 additions & 1 deletion src/data/extent.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
*
* * Vertex buffer store positions as signed 16 bit integers.
* * One bit is lost for signedness to support tile buffers.
* * 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
*
Expand Down
20 changes: 9 additions & 11 deletions src/shaders/line.vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
// #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;
Expand Down Expand Up @@ -41,20 +41,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;

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 halfwidth = width / 2.0;
offset = -1.0 * offset;
offset = -1.0 * offset;

float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);
float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;
Expand All @@ -71,9 +72,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;

Expand Down
19 changes: 9 additions & 10 deletions src/shaders/line_pattern.vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// 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;
Expand Down Expand Up @@ -43,19 +43,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 halfwidth = width / 2.0;
offset = -1.0 * offset;
offset = -1.0 * offset;

float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);
float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;
Expand All @@ -72,9 +74,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;

Expand Down
19 changes: 9 additions & 10 deletions src/shaders/line_sdf.vertex.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// 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;
Expand Down Expand Up @@ -52,20 +52,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 halfwidth = width / 2.0;
offset = -1.0 * offset;

float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0);
float outset = gapwidth + halfwidth * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING;

Expand All @@ -81,9 +83,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;

Expand Down