in modules/layers/src/lane-layer/lane-layer.js [36:124]
getShaders() {
const shaders = super.getShaders();
shaders.vs = shaders.vs
.replace('attribute float instanceStrokeWidths', 'attribute vec3 instanceStrokeWidths')
.replace(
'instanceStrokeWidths * widthScale',
'(instanceStrokeWidths.x + instanceStrokeWidths.y + instanceStrokeWidths.z) * widthScale'
);
shaders.inject = {
'vs:#decl': `
uniform float strokeIndex;
attribute vec4 instanceDashArrays;
attribute float instanceStartRatio;
varying vec4 vDashArray;
varying vec2 vWidth;
varying float vPathOffset;
`,
'vs:#main-end': `
vDashArray = instanceDashArrays;
float totalWidth = instanceStrokeWidths.x + instanceStrokeWidths.y + instanceStrokeWidths.z;
if (strokeIndex == 0.0) {
vWidth = vec2(0.0, instanceStrokeWidths.x / totalWidth);
} else {
vWidth = vec2(1.0 - instanceStrokeWidths.z / totalWidth, 1.0);
}
// map to [-1.0, 1.0] space
vWidth = 1.0 - vWidth * 2.0;
vPathOffset = vPathLength * instanceStartRatio;
`,
'fs:#decl': `
uniform float dashAlignMode;
varying vec4 vDashArray;
varying vec2 vWidth;
varying float vPathOffset;
// mod doesn't work correctly for negative numbers
float mod2(float a, float b) {
return a - floor(a / b) * b;
}
float round(float x) {
return floor(x + 0.5);
}
`,
// if given position is in the gap part of the dashed line
// dashArray.x: solid stroke length, relative to width
// dashArray.y: gap length, relative to width
// alignMode:
// 0 - no adjustment
// o---- ---- ---- ---- o---- -o---- ---- o
// 1 - stretch to fit, draw half dash at each end for nicer joints
// o-- ---- ---- ---- --o-- --o-- ---- --o
'fs:#main-start': `
if (vPathPosition.x > vWidth.x || vPathPosition.x < vWidth.y) {
discard;
}
float solid1 = vDashArray.x;
float gap1 = solid1 + vDashArray.y;
float solid2 = gap1 + vDashArray.z;
float unitLength = solid2 + vDashArray.w;
if (unitLength > 0.0 && vDashArray.y > 0.0) {
unitLength = mix(
unitLength,
vPathLength / round(vPathLength / unitLength),
dashAlignMode
);
float offset = mix(vPathOffset, vDashArray.x / 2.0, dashAlignMode);
float unitPosition = mod2(vPathPosition.y + offset, unitLength);
if (unitPosition > solid1 && unitPosition < gap1 || unitPosition > solid2) {
discard;
}
}
`
};
return shaders;
}