getShaders()

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;
  }