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

feat: PolylinesLayer typed arrays input. #1949

Merged
merged 24 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
f45ad58
package-lock updated
Dec 14, 2023
0c057bc
Merge remote-tracking branch 'upstream/master'
Dec 26, 2023
23dbe18
Merge remote-tracking branch 'upstream/master'
Jan 24, 2024
62ab6ea
Merge remote-tracking branch 'upstream/master'
Jan 26, 2024
1e47198
Merge remote-tracking branch 'upstream/master'
Jan 30, 2024
584d17d
Merge remote-tracking branch 'upstream/master'
Feb 1, 2024
beb8949
Merge remote-tracking branch 'upstream/master'
Feb 21, 2024
07ded84
build: package-lock updated
Feb 21, 2024
6ec8fe8
Merge remote-tracking branch 'upstream/master'
Feb 26, 2024
59b3f36
Merge remote-tracking branch 'upstream/master'
Feb 29, 2024
8248e2f
refactor(polylines): Private PolylinesLayer extends deck.gl PathLayer
Mar 5, 2024
f2e21b8
feat(PolylinesLayer): Typed array inputs
Mar 5, 2024
b9eb079
feat(polylineLayer): ZIncreasingDownwards is applied in vertex shader
Mar 5, 2024
96e2fd1
tests(storybook): Story with polylinesLayer and typed arrays added
Mar 5, 2024
4bf2f9e
update(polylinesLayer): import type
Mar 5, 2024
e4d47c8
tests(storybook): polylines story renamed, snapshots updated
Mar 5, 2024
d7ed4c7
fix(polylinesLayer): pickable default restored to true
Mar 5, 2024
c0ca7df
feat(polylinesLayer): depthTest is optional
Mar 5, 2024
05e61d4
Merge branch 'master' into PolylinesLayerImprovement
LeonidPolukhin Mar 5, 2024
3dd2e53
tests(storybook): huge polylines layer snapshot updated
Mar 5, 2024
28fdffa
Merge branch 'PolylinesLayerImprovement' of https://github.com/Leonid…
Mar 5, 2024
42c1ee7
test(storybook): polylines snapshots updated
Mar 5, 2024
5af47fd
tests(storybook): snoke tests switched off for huge polylines
Mar 5, 2024
587c8bf
tests(storybook): huge polyline snapshots deleted
Mar 5, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) 2015 - 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

export default `\
#version 300 es
#define SHADER_NAME path-layer-fragment-shader

precision highp float;

uniform float miterLimit;

in vec4 vColor;
in vec2 vCornerOffset;
in float vMiterLength;
/*
* vPathPosition represents the relative coordinates of the current fragment on the path segment.
* vPathPosition.x - position along the width of the path, between [-1, 1]. 0 is the center line.
* vPathPosition.y - position along the length of the path, between [0, L / width].
*/
in vec2 vPathPosition;
in float vPathLength;
in float vJointType;

out vec4 fragColor;

void main(void) {
geometry.uv = vPathPosition;

if (vPathPosition.y < 0.0 || vPathPosition.y > vPathLength) {
// if joint is rounded, test distance from the corner
if (vJointType > 0.5 && length(vCornerOffset) > 1.0) {
discard;
}
// trim miter
if (vJointType < 0.5 && vMiterLength > miterLimit + 1.0) {
discard;
}
}
fragColor = vColor;

DECKGL_FILTER_COLOR(fragColor, geometry);
}
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,256 @@
// Copyright (c) 2015 - 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

export default `\
#version 300 es
#define SHADER_NAME path-layer-vertex-shader

in vec2 positions;

in float instanceTypes;
in vec3 instanceStartPositions;
in vec3 instanceEndPositions;
in vec3 instanceLeftPositions;
in vec3 instanceRightPositions;
in vec3 instanceLeftPositions64Low;
in vec3 instanceStartPositions64Low;
in vec3 instanceEndPositions64Low;
in vec3 instanceRightPositions64Low;
in float instanceStrokeWidths;
in vec4 instanceColors;
in vec3 instancePickingColors;

uniform float widthScale;
uniform float widthMinPixels;
uniform float widthMaxPixels;
uniform float jointType;
uniform float capType;
uniform float miterLimit;
uniform bool billboard;
uniform int widthUnits;

uniform float opacity;
uniform bool ZIncreasingDownwards;

out vec4 vColor;
out vec2 vCornerOffset;
out float vMiterLength;
out vec2 vPathPosition;
out float vPathLength;
out float vJointType;

const float EPSILON = 0.001;
const vec3 ZERO_OFFSET = vec3(0.0);

float flipIfTrue(bool flag) {
return -(float(flag) * 2. - 1.);
}

// calculate line join positions
vec3 getLineJoinOffset(
vec3 prevPoint, vec3 currPoint, vec3 nextPoint,
vec2 width
) {
bool isEnd = positions.x > 0.0;
// side of the segment - -1: left, 0: center, 1: right
float sideOfPath = positions.y;
float isJoint = float(sideOfPath == 0.0);

vec3 deltaA3 = (currPoint - prevPoint);
vec3 deltaB3 = (nextPoint - currPoint);

mat3 rotationMatrix;
bool needsRotation = !billboard && project_needs_rotation(currPoint, rotationMatrix);
if (needsRotation) {
deltaA3 = deltaA3 * rotationMatrix;
deltaB3 = deltaB3 * rotationMatrix;
}
vec2 deltaA = deltaA3.xy / width;
vec2 deltaB = deltaB3.xy / width;

float lenA = length(deltaA);
float lenB = length(deltaB);

vec2 dirA = lenA > 0. ? normalize(deltaA) : vec2(0.0, 0.0);
vec2 dirB = lenB > 0. ? normalize(deltaB) : vec2(0.0, 0.0);

vec2 perpA = vec2(-dirA.y, dirA.x);
vec2 perpB = vec2(-dirB.y, dirB.x);

// tangent of the corner
vec2 tangent = dirA + dirB;
tangent = length(tangent) > 0. ? normalize(tangent) : perpA;
// direction of the corner
vec2 miterVec = vec2(-tangent.y, tangent.x);
// direction of the segment
vec2 dir = isEnd ? dirA : dirB;
// direction of the extrusion
vec2 perp = isEnd ? perpA : perpB;
// length of the segment
float L = isEnd ? lenA : lenB;

// A = angle of the corner
float sinHalfA = abs(dot(miterVec, perp));
float cosHalfA = abs(dot(dirA, miterVec));

// -1: right, 1: left
float turnDirection = flipIfTrue(dirA.x * dirB.y >= dirA.y * dirB.x);

// relative position to the corner:
// -1: inside (smaller side of the angle)
// 0: center
// 1: outside (bigger side of the angle)
float cornerPosition = sideOfPath * turnDirection;

float miterSize = 1.0 / max(sinHalfA, EPSILON);
// trim if inside corner extends further than the line segment
miterSize = mix(
min(miterSize, max(lenA, lenB) / max(cosHalfA, EPSILON)),
miterSize,
step(0.0, cornerPosition)
);

vec2 offsetVec = mix(miterVec * miterSize, perp, step(0.5, cornerPosition))
* (sideOfPath + isJoint * turnDirection);

// special treatment for start cap and end cap
bool isStartCap = lenA == 0.0 || (!isEnd && (instanceTypes == 1.0 || instanceTypes == 3.0));
bool isEndCap = lenB == 0.0 || (isEnd && (instanceTypes == 2.0 || instanceTypes == 3.0));
bool isCap = isStartCap || isEndCap;

// extend out a triangle to envelope the round cap
if (isCap) {
offsetVec = mix(perp * sideOfPath, dir * capType * 4.0 * flipIfTrue(isStartCap), isJoint);
vJointType = capType;
} else {
vJointType = jointType;
}

// Generate variables for fragment shader
vPathLength = L;
vCornerOffset = offsetVec;
vMiterLength = dot(vCornerOffset, miterVec * turnDirection);
vMiterLength = isCap ? isJoint : vMiterLength;

vec2 offsetFromStartOfPath = vCornerOffset + deltaA * float(isEnd);
vPathPosition = vec2(
dot(offsetFromStartOfPath, perp),
dot(offsetFromStartOfPath, dir)
);
geometry.uv = vPathPosition;

float isValid = step(instanceTypes, 3.5);
vec3 offset = vec3(offsetVec * width * isValid, 0.0);

if (needsRotation) {
offset = rotationMatrix * offset;
}
return offset;
}

// In clipspace extrusion, if a line extends behind the camera, clip it to avoid visual artifacts
void clipLine(inout vec4 position, vec4 refPosition) {
if (position.w < EPSILON) {
float r = (EPSILON - refPosition.w) / (position.w - refPosition.w);
position = refPosition + (position - refPosition) * r;
}
}

void main() {
geometry.pickingColor = instancePickingColors;

vColor = vec4(instanceColors.rgb, instanceColors.a * opacity);
vec3 leftPosition = instanceLeftPositions;
vec3 startPosition = instanceStartPositions;
vec3 leftPos64Low = instanceLeftPositions64Low;
vec3 startPos64Low = instanceStartPositions64Low;

vec3 rightposition = instanceRightPositions;
vec3 endPosition = instanceEndPositions;
vec3 rightPos64Low = instanceRightPositions64Low;
vec3 endPos64Low = instanceEndPositions64Low;

if(ZIncreasingDownwards) {
leftPosition.z *= -1.0;
startPosition.z *= -1.0;
leftPos64Low.z *= -1.0;
startPos64Low.z *= -1.0;
rightposition.z *= -1.0;
endPosition.z *= -1.0;
rightPos64Low.z *= -1.0;
endPos64Low.z *= -1.0;
}

float isEnd = positions.x;

vec3 prevPosition = mix(leftPosition, startPosition, isEnd);
vec3 prevPosition64Low = mix(leftPos64Low, startPos64Low, isEnd);

vec3 currPosition = mix(startPosition, endPosition, isEnd);
vec3 currPosition64Low = mix(startPos64Low, endPos64Low, isEnd);

vec3 nextPosition = mix(endPosition, rightposition, isEnd);
vec3 nextPosition64Low = mix(endPos64Low, rightPos64Low, isEnd);

geometry.worldPosition = currPosition;
vec2 widthPixels = vec2(clamp(
project_size_to_pixel(instanceStrokeWidths * widthScale, widthUnits),
widthMinPixels, widthMaxPixels) / 2.0);
vec3 width;

if (billboard) {
// Extrude in clipspace
vec4 prevPositionScreen = project_position_to_clipspace(prevPosition, prevPosition64Low, ZERO_OFFSET);
vec4 currPositionScreen = project_position_to_clipspace(currPosition, currPosition64Low, ZERO_OFFSET, geometry.position);
vec4 nextPositionScreen = project_position_to_clipspace(nextPosition, nextPosition64Low, ZERO_OFFSET);

clipLine(prevPositionScreen, currPositionScreen);
clipLine(nextPositionScreen, currPositionScreen);
clipLine(currPositionScreen, mix(nextPositionScreen, prevPositionScreen, isEnd));

width = vec3(widthPixels, 0.0);
DECKGL_FILTER_SIZE(width, geometry);

vec3 offset = getLineJoinOffset(
prevPositionScreen.xyz / prevPositionScreen.w,
currPositionScreen.xyz / currPositionScreen.w,
nextPositionScreen.xyz / nextPositionScreen.w,
project_pixel_size_to_clipspace(width.xy)
);

DECKGL_FILTER_GL_POSITION(currPositionScreen, geometry);
gl_Position = vec4(currPositionScreen.xyz + offset * currPositionScreen.w, currPositionScreen.w);
} else {
// Extrude in commonspace
prevPosition = project_position(prevPosition, prevPosition64Low);
currPosition = project_position(currPosition, currPosition64Low);
nextPosition = project_position(nextPosition, nextPosition64Low);

width = vec3(project_pixel_size(widthPixels), 0.0);
DECKGL_FILTER_SIZE(width, geometry);

vec3 offset = getLineJoinOffset(prevPosition, currPosition, nextPosition, width.xy);
geometry.position = vec4(currPosition + offset, 1.0);
gl_Position = project_common_position_to_clipspace(geometry.position);
DECKGL_FILTER_GL_POSITION(gl_Position, geometry);
}
DECKGL_FILTER_COLOR(vColor, geometry);
}
`;
Loading
Loading