@deck.gl/extensions 9.0.0-beta.9 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/collision-filter/collision-filter-effect.d.ts +4 -2
  2. package/dist/collision-filter/collision-filter-effect.d.ts.map +1 -1
  3. package/dist/collision-filter/collision-filter-effect.js +10 -9
  4. package/dist/collision-filter/collision-filter-pass.d.ts +3 -2
  5. package/dist/collision-filter/collision-filter-pass.d.ts.map +1 -1
  6. package/dist/collision-filter/collision-filter-pass.js +5 -7
  7. package/dist/data-filter/data-filter-extension.d.ts +1 -1
  8. package/dist/data-filter/data-filter-extension.d.ts.map +1 -1
  9. package/dist/data-filter/data-filter-extension.js +1 -1
  10. package/dist/dist.dev.js +475 -479
  11. package/dist/fill-style/fill-style-extension.d.ts +2 -30
  12. package/dist/fill-style/fill-style-extension.d.ts.map +1 -1
  13. package/dist/fill-style/fill-style-extension.js +1 -3
  14. package/dist/index.cjs +427 -421
  15. package/dist/index.cjs.map +4 -4
  16. package/dist/mask/mask-effect.d.ts +5 -4
  17. package/dist/mask/mask-effect.d.ts.map +1 -1
  18. package/dist/mask/mask-effect.js +9 -11
  19. package/dist/mask/mask-pass.d.ts +4 -3
  20. package/dist/mask/mask-pass.d.ts.map +1 -1
  21. package/dist/mask/mask-pass.js +17 -9
  22. package/dist/path-style/path-style-extension.d.ts.map +1 -1
  23. package/dist/path-style/path-style-extension.js +1 -0
  24. package/dist/terrain/terrain-effect.d.ts +4 -5
  25. package/dist/terrain/terrain-effect.d.ts.map +1 -1
  26. package/dist/terrain/terrain-effect.js +6 -15
  27. package/dist/terrain/terrain-pass.d.ts +1 -0
  28. package/dist/terrain/terrain-pass.d.ts.map +1 -1
  29. package/dist/terrain/terrain-pass.js +24 -16
  30. package/dist/terrain/terrain-picking-pass.d.ts.map +1 -1
  31. package/dist/terrain/terrain-picking-pass.js +9 -8
  32. package/dist/terrain/utils.d.ts.map +1 -1
  33. package/dist/terrain/utils.js +1 -0
  34. package/dist.min.js +23 -23
  35. package/package.json +5 -5
  36. package/src/collision-filter/collision-filter-effect.ts +22 -22
  37. package/src/collision-filter/collision-filter-pass.ts +7 -11
  38. package/src/data-filter/data-filter-extension.ts +1 -1
  39. package/src/fill-style/fill-style-extension.ts +3 -4
  40. package/src/mask/mask-effect.ts +30 -19
  41. package/src/mask/mask-pass.ts +22 -16
  42. package/src/path-style/path-style-extension.ts +1 -0
  43. package/src/terrain/terrain-effect.ts +9 -18
  44. package/src/terrain/terrain-pass.ts +37 -34
  45. package/src/terrain/terrain-picking-pass.ts +19 -23
  46. package/src/terrain/utils.ts +1 -0
package/dist/dist.dev.js CHANGED
@@ -1208,7 +1208,7 @@ void main() {
1208
1208
  4: "vec4"
1209
1209
  };
1210
1210
  var DataFilterExtension = class extends import_core4.LayerExtension {
1211
- constructor(opts) {
1211
+ constructor(opts = {}) {
1212
1212
  super({ ...defaultOptions, ...opts });
1213
1213
  }
1214
1214
  getShaders(extension) {
@@ -2101,11 +2101,7 @@ vec4_dot_fp64(a, tmp, out_val[i]);
2101
2101
  printRowMajor: true,
2102
2102
  _cartographicRadians: false
2103
2103
  };
2104
- globalThis.mathgl = globalThis.mathgl || {
2105
- config: {
2106
- ...DEFAULT_CONFIG
2107
- }
2108
- };
2104
+ globalThis.mathgl = globalThis.mathgl || { config: { ...DEFAULT_CONFIG } };
2109
2105
  var config = globalThis.mathgl.config;
2110
2106
  function isArray(value) {
2111
2107
  return Array.isArray(value) || ArrayBuffer.isView(value) && !(value instanceof DataView);
@@ -2533,7 +2529,7 @@ vec4_dot_fp64(a, tmp, out_val[i]);
2533
2529
  return out;
2534
2530
  }
2535
2531
  function str(a) {
2536
- return "vec3(".concat(a[0], ", ").concat(a[1], ", ").concat(a[2], ")");
2532
+ return `vec3(${a[0]}, ${a[1]}, ${a[2]})`;
2537
2533
  }
2538
2534
  function exactEquals(a, b) {
2539
2535
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2];
@@ -2883,6 +2879,7 @@ in float instanceOffsets;
2883
2879
  }
2884
2880
  prevP = p;
2885
2881
  }
2882
+ result[geometrySize - 1] = 0;
2886
2883
  return result;
2887
2884
  }
2888
2885
  };
@@ -2999,9 +2996,7 @@ const float FILL_UV_SCALE = 512.0 / 40000000.0;
2999
2996
  type: "image",
3000
2997
  value: null,
3001
2998
  async: true,
3002
- parameters: {
3003
- minFilter: "linear"
3004
- }
2999
+ parameters: { lodMaxClamp: 0 }
3005
3000
  },
3006
3001
  fillPatternMapping: { type: "object", value: {}, async: true },
3007
3002
  fillPatternMask: true,
@@ -3193,7 +3188,7 @@ in vec2 clip_commonPosition;
3193
3188
  ClipExtension.extensionName = "ClipExtension";
3194
3189
 
3195
3190
  // src/collision-filter/collision-filter-extension.ts
3196
- var import_core20 = __toESM(require_core(), 1);
3191
+ var import_core16 = __toESM(require_core(), 1);
3197
3192
 
3198
3193
  // src/collision-filter/shader-module.ts
3199
3194
  var import_core12 = __toESM(require_core(), 1);
@@ -3294,7 +3289,7 @@ float collision_isVisible(vec2 texCoords, vec3 pickingColor) {
3294
3289
  };
3295
3290
 
3296
3291
  // src/collision-filter/collision-filter-effect.ts
3297
- var import_core19 = __toESM(require_core(), 1);
3292
+ var import_core15 = __toESM(require_core(), 1);
3298
3293
 
3299
3294
  // src/collision-filter/collision-filter-pass.ts
3300
3295
  var import_core13 = __toESM(require_core(), 1);
@@ -3302,16 +3297,11 @@ float collision_isVisible(vec2 texCoords, vec3 pickingColor) {
3302
3297
  renderCollisionMap(target, options) {
3303
3298
  const padding = 1;
3304
3299
  const clearColor = [0, 0, 0, 0];
3305
- return this.device.withParametersWebGL(
3306
- {
3307
- scissorTest: true,
3308
- scissor: [padding, padding, target.width - 2 * padding, target.height - 2 * padding],
3309
- blend: false,
3310
- depthTest: true,
3311
- depthRange: [0, 1]
3312
- },
3313
- () => this.render({ ...options, clearColor, target, pass: "collision" })
3314
- );
3300
+ const scissorRect = [padding, padding, target.width - 2 * padding, target.height - 2 * padding];
3301
+ this.render({ ...options, clearColor, scissorRect, target, pass: "collision" });
3302
+ }
3303
+ getLayerParameters(layer, layerIndex, viewport) {
3304
+ return { ...layer.props.parameters, blend: false, depthRange: [0, 1], depthTest: true };
3315
3305
  }
3316
3306
  getModuleParameters() {
3317
3307
  return {
@@ -3325,419 +3315,83 @@ float collision_isVisible(vec2 texCoords, vec3 pickingColor) {
3325
3315
  }
3326
3316
  };
3327
3317
 
3328
- // src/mask/mask-effect.ts
3329
- var import_core16 = __toESM(require_core(), 1);
3330
-
3331
- // src/mask/mask-pass.ts
3332
- var import_core14 = __toESM(require_core(), 1);
3333
- var MaskPass = class extends import_core14._LayersPass {
3334
- constructor(device, props) {
3335
- super(device, props);
3336
- const { mapSize = 2048 } = props;
3337
- this.maskMap = device.createTexture({
3338
- format: "rgba8unorm",
3339
- width: mapSize,
3340
- height: mapSize,
3341
- sampler: {
3342
- minFilter: "linear",
3343
- magFilter: "linear",
3344
- addressModeU: "clamp-to-edge",
3345
- addressModeV: "clamp-to-edge"
3346
- }
3347
- });
3348
- this.fbo = device.createFramebuffer({
3349
- id: "maskmap",
3350
- width: mapSize,
3351
- height: mapSize,
3352
- colorAttachments: [this.maskMap]
3353
- });
3354
- }
3355
- render(options) {
3356
- const colorMask = [false, false, false, false];
3357
- colorMask[options.channel] = true;
3358
- const clearColor = [255, 255, 255, 255];
3359
- return this.device.withParametersWebGL(
3360
- {
3361
- blend: true,
3362
- blendFunc: [GLEnum.ZERO, GLEnum.ONE],
3363
- blendEquation: GLEnum.FUNC_SUBTRACT,
3364
- colorMask,
3365
- depthTest: false
3366
- },
3367
- () => super.render({ ...options, clearColor, target: this.fbo, pass: "mask" })
3368
- );
3369
- }
3370
- shouldDrawLayer(layer) {
3371
- return layer.props.operation.includes("mask");
3372
- }
3373
- delete() {
3374
- this.fbo.delete();
3375
- this.maskMap.delete();
3376
- }
3377
- };
3378
-
3379
- // src/utils/projection-utils.ts
3380
- var import_core15 = __toESM(require_core(), 1);
3381
- function joinLayerBounds(layers, viewport) {
3382
- const bounds = [Infinity, Infinity, -Infinity, -Infinity];
3383
- for (const layer of layers) {
3384
- const layerBounds = layer.getBounds();
3385
- if (layerBounds) {
3386
- const bottomLeftCommon = layer.projectPosition(layerBounds[0], { viewport, autoOffset: false });
3387
- const topRightCommon = layer.projectPosition(layerBounds[1], { viewport, autoOffset: false });
3388
- bounds[0] = Math.min(bounds[0], bottomLeftCommon[0]);
3389
- bounds[1] = Math.min(bounds[1], bottomLeftCommon[1]);
3390
- bounds[2] = Math.max(bounds[2], topRightCommon[0]);
3391
- bounds[3] = Math.max(bounds[3], topRightCommon[1]);
3392
- }
3393
- }
3394
- if (Number.isFinite(bounds[0])) {
3395
- return bounds;
3396
- }
3397
- return null;
3398
- }
3399
- var MAX_VIEWPORT_SIZE = 2048;
3400
- function makeViewport(opts) {
3401
- const { bounds, viewport, border = 0 } = opts;
3402
- const { isGeospatial } = viewport;
3403
- if (bounds[2] <= bounds[0] || bounds[3] <= bounds[1]) {
3404
- return null;
3405
- }
3406
- const centerWorld = viewport.unprojectPosition([
3407
- (bounds[0] + bounds[2]) / 2,
3408
- (bounds[1] + bounds[3]) / 2,
3409
- 0
3410
- ]);
3411
- let { width, height, zoom } = opts;
3412
- if (zoom === void 0) {
3413
- width = width - border * 2;
3414
- height = height - border * 2;
3415
- const scale2 = Math.min(width / (bounds[2] - bounds[0]), height / (bounds[3] - bounds[1]));
3416
- zoom = Math.min(Math.log2(scale2), 20);
3417
- } else if (!width || !height) {
3418
- const scale2 = 2 ** zoom;
3419
- width = Math.round(Math.abs(bounds[2] - bounds[0]) * scale2);
3420
- height = Math.round(Math.abs(bounds[3] - bounds[1]) * scale2);
3421
- const maxSize = MAX_VIEWPORT_SIZE - border * 2;
3422
- if (width > maxSize || height > maxSize) {
3423
- const r = maxSize / Math.max(width, height);
3424
- width = Math.round(width * r);
3425
- height = Math.round(height * r);
3426
- zoom += Math.log2(r);
3427
- }
3428
- }
3429
- return isGeospatial ? new import_core15.WebMercatorViewport({
3430
- id: viewport.id,
3431
- x: border,
3432
- y: border,
3433
- width,
3434
- height,
3435
- longitude: centerWorld[0],
3436
- latitude: centerWorld[1],
3437
- zoom,
3438
- orthographic: true
3439
- }) : new import_core15.OrthographicViewport({
3440
- id: viewport.id,
3441
- x: border,
3442
- y: border,
3443
- width,
3444
- height,
3445
- target: centerWorld,
3446
- zoom,
3447
- flipY: false
3448
- });
3449
- }
3450
- function getViewportBounds(viewport, zRange) {
3451
- let viewportBoundsWorld;
3452
- if (zRange && zRange.length === 2) {
3453
- const [minZ, maxZ] = zRange;
3454
- const bounds0 = viewport.getBounds({ z: minZ });
3455
- const bounds1 = viewport.getBounds({ z: maxZ });
3456
- viewportBoundsWorld = [
3457
- Math.min(bounds0[0], bounds1[0]),
3458
- Math.min(bounds0[1], bounds1[1]),
3459
- Math.max(bounds0[2], bounds1[2]),
3460
- Math.max(bounds0[3], bounds1[3])
3461
- ];
3462
- } else {
3463
- viewportBoundsWorld = viewport.getBounds();
3464
- }
3465
- const viewportBottomLeftCommon = viewport.projectPosition(viewportBoundsWorld.slice(0, 2));
3466
- const viewportTopRightCommon = viewport.projectPosition(viewportBoundsWorld.slice(2, 4));
3467
- return [
3468
- viewportBottomLeftCommon[0],
3469
- viewportBottomLeftCommon[1],
3470
- viewportTopRightCommon[0],
3471
- viewportTopRightCommon[1]
3472
- ];
3473
- }
3474
- function getRenderBounds(layerBounds, viewport, zRange) {
3475
- if (!layerBounds) {
3476
- return [0, 0, 1, 1];
3477
- }
3478
- const viewportBounds = getViewportBounds(viewport, zRange);
3479
- const paddedBounds = doubleBounds(viewportBounds);
3480
- if (layerBounds[2] - layerBounds[0] <= paddedBounds[2] - paddedBounds[0] && layerBounds[3] - layerBounds[1] <= paddedBounds[3] - paddedBounds[1]) {
3481
- return layerBounds;
3482
- }
3483
- return [
3484
- Math.max(layerBounds[0], paddedBounds[0]),
3485
- Math.max(layerBounds[1], paddedBounds[1]),
3486
- Math.min(layerBounds[2], paddedBounds[2]),
3487
- Math.min(layerBounds[3], paddedBounds[3])
3488
- ];
3489
- }
3490
- function doubleBounds(bounds) {
3491
- const dx = bounds[2] - bounds[0];
3492
- const dy = bounds[3] - bounds[1];
3493
- const centerX = (bounds[0] + bounds[2]) / 2;
3494
- const centerY = (bounds[1] + bounds[3]) / 2;
3495
- return [centerX - dx, centerY - dy, centerX + dx, centerY + dy];
3496
- }
3497
-
3498
- // src/mask/mask-effect.ts
3499
- var MaskEffect = class {
3318
+ // src/collision-filter/collision-filter-effect.ts
3319
+ var DOWNSCALE = 2;
3320
+ var CollisionFilterEffect = class {
3500
3321
  constructor() {
3501
- this.id = "mask-effect";
3322
+ this.id = "collision-filter-effect";
3502
3323
  this.props = null;
3503
3324
  this.useInPicking = true;
3504
- this.order = 0;
3505
- this.channels = [];
3506
- this.masks = null;
3325
+ this.order = 1;
3326
+ this.channels = {};
3327
+ this.collisionFBOs = {};
3507
3328
  }
3508
- preRender(device, { layers, layerFilter, viewports, onViewportActive, views, isPicking }) {
3509
- let didRender = false;
3510
- if (!this.dummyMaskMap) {
3511
- this.dummyMaskMap = device.createTexture({
3512
- width: 1,
3513
- height: 1
3514
- });
3515
- }
3329
+ setup(context) {
3330
+ this.context = context;
3331
+ const { device } = context;
3332
+ this.dummyCollisionMap = device.createTexture({ width: 1, height: 1 });
3333
+ this.collisionFilterPass = new CollisionFilterPass(device, { id: "default-collision-filter" });
3334
+ }
3335
+ preRender({
3336
+ effects: allEffects,
3337
+ layers,
3338
+ layerFilter,
3339
+ viewports,
3340
+ onViewportActive,
3341
+ views,
3342
+ isPicking,
3343
+ preRenderStats = {}
3344
+ }) {
3345
+ const { device } = this.context;
3516
3346
  if (isPicking) {
3517
- return { didRender };
3518
- }
3519
- const maskLayers = layers.filter((l) => l.props.visible && l.props.operation.includes("mask"));
3520
- if (maskLayers.length === 0) {
3521
- this.masks = null;
3522
- this.channels.length = 0;
3523
- return { didRender };
3347
+ return;
3524
3348
  }
3525
- this.masks = {};
3526
- if (!this.maskPass) {
3527
- this.maskPass = new MaskPass(device, { id: "default-mask" });
3528
- this.maskMap = this.maskPass.maskMap;
3349
+ const collisionLayers = layers.filter(
3350
+ ({ props: { visible, collisionEnabled } }) => visible && collisionEnabled
3351
+ );
3352
+ if (collisionLayers.length === 0) {
3353
+ this.channels = {};
3354
+ return;
3529
3355
  }
3530
- const channelMap = this._sortMaskChannels(maskLayers);
3356
+ const effects = allEffects?.filter((e) => e.useInPicking && preRenderStats[e.id]);
3357
+ const maskEffectRendered = preRenderStats["mask-effect"]?.didRender;
3358
+ const channels = this._groupByCollisionGroup(device, collisionLayers);
3531
3359
  const viewport = viewports[0];
3532
- const viewportChanged = !this.lastViewport || !this.lastViewport.equals(viewport);
3533
- if (viewport.resolution !== void 0) {
3534
- import_core16.log.warn("MaskExtension is not supported in GlobeView")();
3535
- return { didRender };
3536
- }
3537
- for (const maskId in channelMap) {
3538
- const result = this._renderChannel(channelMap[maskId], {
3360
+ const viewportChanged = !this.lastViewport || !this.lastViewport.equals(viewport) || maskEffectRendered;
3361
+ for (const collisionGroup in channels) {
3362
+ const collisionFBO = this.collisionFBOs[collisionGroup];
3363
+ const renderInfo = channels[collisionGroup];
3364
+ const [width, height] = device.canvasContext.getPixelSize();
3365
+ collisionFBO.resize({
3366
+ width: width / DOWNSCALE,
3367
+ height: height / DOWNSCALE
3368
+ });
3369
+ this._render(renderInfo, {
3370
+ effects,
3539
3371
  layerFilter,
3540
3372
  onViewportActive,
3541
3373
  views,
3542
3374
  viewport,
3543
3375
  viewportChanged
3544
3376
  });
3545
- didRender ||= result;
3546
3377
  }
3547
- return { didRender };
3548
3378
  }
3549
- _renderChannel(channelInfo, {
3379
+ _render(renderInfo, {
3380
+ effects,
3550
3381
  layerFilter,
3551
3382
  onViewportActive,
3552
3383
  views,
3553
3384
  viewport,
3554
3385
  viewportChanged
3555
3386
  }) {
3556
- let didRender = false;
3557
- const oldChannelInfo = this.channels[channelInfo.index];
3558
- if (!oldChannelInfo) {
3559
- return didRender;
3387
+ const { collisionGroup } = renderInfo;
3388
+ const oldRenderInfo = this.channels[collisionGroup];
3389
+ if (!oldRenderInfo) {
3390
+ return;
3560
3391
  }
3561
- const maskChanged = channelInfo === oldChannelInfo || channelInfo.layers.length !== oldChannelInfo.layers.length || channelInfo.layers.some(
3562
- (layer, i) => layer !== oldChannelInfo.layers[i] || layer.props.transitions
3563
- ) || channelInfo.layerBounds.some((b, i) => b !== oldChannelInfo.layerBounds[i]);
3564
- channelInfo.bounds = oldChannelInfo.bounds;
3565
- channelInfo.maskBounds = oldChannelInfo.maskBounds;
3566
- this.channels[channelInfo.index] = channelInfo;
3567
- if (maskChanged || viewportChanged) {
3568
- this.lastViewport = viewport;
3569
- const layerBounds = joinLayerBounds(channelInfo.layers, viewport);
3570
- channelInfo.bounds = layerBounds && getRenderBounds(layerBounds, viewport);
3571
- if (maskChanged || !equals(channelInfo.bounds, oldChannelInfo.bounds)) {
3572
- const { maskPass, maskMap } = this;
3573
- const maskViewport = layerBounds && makeViewport({
3574
- bounds: channelInfo.bounds,
3575
- viewport,
3576
- width: maskMap.width,
3577
- height: maskMap.height,
3578
- border: 1
3579
- });
3580
- channelInfo.maskBounds = maskViewport ? maskViewport.getBounds() : [0, 0, 1, 1];
3581
- maskPass.render({
3582
- pass: "mask",
3583
- channel: channelInfo.index,
3584
- layers: channelInfo.layers,
3585
- layerFilter,
3586
- viewports: maskViewport ? [maskViewport] : [],
3587
- onViewportActive,
3588
- views,
3589
- moduleParameters: {
3590
- devicePixelRatio: 1
3591
- }
3592
- });
3593
- didRender = true;
3594
- }
3595
- }
3596
- this.masks[channelInfo.id] = {
3597
- index: channelInfo.index,
3598
- bounds: channelInfo.maskBounds,
3599
- coordinateOrigin: channelInfo.coordinateOrigin,
3600
- coordinateSystem: channelInfo.coordinateSystem
3601
- };
3602
- return didRender;
3603
- }
3604
- _sortMaskChannels(maskLayers) {
3605
- const channelMap = {};
3606
- let channelCount = 0;
3607
- for (const layer of maskLayers) {
3608
- const { id } = layer.root;
3609
- let channelInfo = channelMap[id];
3610
- if (!channelInfo) {
3611
- if (++channelCount > 4) {
3612
- import_core16.log.warn("Too many mask layers. The max supported is 4")();
3613
- continue;
3614
- }
3615
- channelInfo = {
3616
- id,
3617
- index: this.channels.findIndex((c) => c?.id === id),
3618
- layers: [],
3619
- layerBounds: [],
3620
- coordinateOrigin: layer.root.props.coordinateOrigin,
3621
- coordinateSystem: layer.root.props.coordinateSystem
3622
- };
3623
- channelMap[id] = channelInfo;
3624
- }
3625
- channelInfo.layers.push(layer);
3626
- channelInfo.layerBounds.push(layer.getBounds());
3627
- }
3628
- for (let i = 0; i < 4; i++) {
3629
- const channelInfo = this.channels[i];
3630
- if (!channelInfo || !(channelInfo.id in channelMap)) {
3631
- this.channels[i] = null;
3632
- }
3633
- }
3634
- for (const maskId in channelMap) {
3635
- const channelInfo = channelMap[maskId];
3636
- if (channelInfo.index < 0) {
3637
- channelInfo.index = this.channels.findIndex((c) => !c);
3638
- this.channels[channelInfo.index] = channelInfo;
3639
- }
3640
- }
3641
- return channelMap;
3642
- }
3643
- getModuleParameters() {
3644
- return {
3645
- maskMap: this.masks ? this.maskMap : this.dummyMaskMap,
3646
- maskChannels: this.masks
3647
- };
3648
- }
3649
- cleanup() {
3650
- if (this.dummyMaskMap) {
3651
- this.dummyMaskMap.delete();
3652
- this.dummyMaskMap = void 0;
3653
- }
3654
- if (this.maskPass) {
3655
- this.maskPass.delete();
3656
- this.maskPass = void 0;
3657
- this.maskMap = void 0;
3658
- }
3659
- this.lastViewport = void 0;
3660
- this.masks = null;
3661
- this.channels.length = 0;
3662
- }
3663
- };
3664
-
3665
- // src/collision-filter/collision-filter-effect.ts
3666
- var DOWNSCALE = 2;
3667
- var CollisionFilterEffect = class {
3668
- constructor() {
3669
- this.id = "collision-filter-effect";
3670
- this.props = null;
3671
- this.useInPicking = true;
3672
- this.order = 1;
3673
- this.channels = {};
3674
- this.collisionFBOs = {};
3675
- }
3676
- preRender(device, {
3677
- effects: allEffects,
3678
- layers,
3679
- layerFilter,
3680
- viewports,
3681
- onViewportActive,
3682
- views,
3683
- isPicking,
3684
- preRenderStats = {}
3685
- }) {
3686
- if (!this.dummyCollisionMap) {
3687
- this.dummyCollisionMap = device.createTexture({ width: 1, height: 1 });
3688
- }
3689
- if (isPicking) {
3690
- return;
3691
- }
3692
- const collisionLayers = layers.filter(
3693
- ({ props: { visible, collisionEnabled } }) => visible && collisionEnabled
3694
- );
3695
- if (collisionLayers.length === 0) {
3696
- this.channels = {};
3697
- return;
3698
- }
3699
- if (!this.collisionFilterPass) {
3700
- this.collisionFilterPass = new CollisionFilterPass(device, { id: "default-collision-filter" });
3701
- }
3702
- const effects = allEffects?.filter((e) => e.constructor === MaskEffect);
3703
- const maskEffectRendered = preRenderStats["mask-effect"]?.didRender;
3704
- const channels = this._groupByCollisionGroup(device, collisionLayers);
3705
- const viewport = viewports[0];
3706
- const viewportChanged = !this.lastViewport || !this.lastViewport.equals(viewport) || maskEffectRendered;
3707
- for (const collisionGroup in channels) {
3708
- const collisionFBO = this.collisionFBOs[collisionGroup];
3709
- const renderInfo = channels[collisionGroup];
3710
- const [width, height] = device.canvasContext.getPixelSize();
3711
- collisionFBO.resize({
3712
- width: width / DOWNSCALE,
3713
- height: height / DOWNSCALE
3714
- });
3715
- this._render(renderInfo, {
3716
- effects,
3717
- layerFilter,
3718
- onViewportActive,
3719
- views,
3720
- viewport,
3721
- viewportChanged
3722
- });
3723
- }
3724
- }
3725
- _render(renderInfo, {
3726
- effects,
3727
- layerFilter,
3728
- onViewportActive,
3729
- views,
3730
- viewport,
3731
- viewportChanged
3732
- }) {
3733
- const { collisionGroup } = renderInfo;
3734
- const oldRenderInfo = this.channels[collisionGroup];
3735
- if (!oldRenderInfo) {
3736
- return;
3737
- }
3738
- const needsRender = viewportChanged || renderInfo === oldRenderInfo || !(0, import_core19._deepEqual)(oldRenderInfo.layers, renderInfo.layers, 1) || renderInfo.layerBounds.some((b, i) => !equals(b, oldRenderInfo.layerBounds[i])) || renderInfo.allLayersLoaded !== oldRenderInfo.allLayersLoaded || renderInfo.layers.some((layer) => layer.props.transitions);
3739
- this.channels[collisionGroup] = renderInfo;
3740
- if (needsRender) {
3392
+ const needsRender = viewportChanged || renderInfo === oldRenderInfo || !(0, import_core15._deepEqual)(oldRenderInfo.layers, renderInfo.layers, 1) || renderInfo.layerBounds.some((b, i) => !equals(b, oldRenderInfo.layerBounds[i])) || renderInfo.allLayersLoaded !== oldRenderInfo.allLayersLoaded || renderInfo.layers.some((layer) => layer.props.transitions);
3393
+ this.channels[collisionGroup] = renderInfo;
3394
+ if (needsRender) {
3741
3395
  this.lastViewport = viewport;
3742
3396
  const collisionFBO = this.collisionFBOs[collisionGroup];
3743
3397
  this.collisionFilterPass.renderCollisionMap(collisionFBO, {
@@ -3848,7 +3502,7 @@ float collision_isVisible(vec2 texCoords, vec3 pickingColor) {
3848
3502
  collisionGroup: { type: "string", value: "default" },
3849
3503
  collisionTestProps: {}
3850
3504
  };
3851
- var CollisionFilterExtension = class extends import_core20.LayerExtension {
3505
+ var CollisionFilterExtension = class extends import_core16.LayerExtension {
3852
3506
  getShaders() {
3853
3507
  return { modules: [shader_module_default2] };
3854
3508
  }
@@ -3889,7 +3543,7 @@ float collision_isVisible(vec2 texCoords, vec3 pickingColor) {
3889
3543
  var import_core22 = __toESM(require_core(), 1);
3890
3544
 
3891
3545
  // src/mask/shader-module.ts
3892
- var import_core21 = __toESM(require_core(), 1);
3546
+ var import_core17 = __toESM(require_core(), 1);
3893
3547
  var vs4 = glsl`
3894
3548
  uniform vec4 mask_bounds;
3895
3549
  uniform bool mask_maskByInstance;
@@ -3963,13 +3617,361 @@ in vec2 mask_texCoords;
3963
3617
  };
3964
3618
  var shader_module_default3 = {
3965
3619
  name: "mask",
3966
- dependencies: [import_core21.project],
3620
+ dependencies: [import_core17.project],
3967
3621
  vs: vs4,
3968
3622
  fs: fs3,
3969
3623
  inject: inject5,
3970
3624
  getUniforms: getMaskUniforms
3971
3625
  };
3972
3626
 
3627
+ // src/mask/mask-effect.ts
3628
+ var import_core20 = __toESM(require_core(), 1);
3629
+
3630
+ // src/mask/mask-pass.ts
3631
+ var import_core18 = __toESM(require_core(), 1);
3632
+ var MASK_BLENDING = {
3633
+ blendColorOperation: "subtract",
3634
+ blendColorSrcFactor: "zero",
3635
+ blendColorDstFactor: "one",
3636
+ blendAlphaOperation: "subtract",
3637
+ blendAlphaSrcFactor: "zero",
3638
+ blendAlphaDstFactor: "one"
3639
+ };
3640
+ var MaskPass = class extends import_core18._LayersPass {
3641
+ constructor(device, props) {
3642
+ super(device, props);
3643
+ const { mapSize = 2048 } = props;
3644
+ this.maskMap = device.createTexture({
3645
+ format: "rgba8unorm",
3646
+ width: mapSize,
3647
+ height: mapSize,
3648
+ sampler: {
3649
+ minFilter: "linear",
3650
+ magFilter: "linear",
3651
+ addressModeU: "clamp-to-edge",
3652
+ addressModeV: "clamp-to-edge"
3653
+ }
3654
+ });
3655
+ this.fbo = device.createFramebuffer({
3656
+ id: "maskmap",
3657
+ width: mapSize,
3658
+ height: mapSize,
3659
+ colorAttachments: [this.maskMap]
3660
+ });
3661
+ }
3662
+ render(options) {
3663
+ const colorMask = 2 ** options.channel;
3664
+ const clearColor = [255, 255, 255, 255];
3665
+ super.render({ ...options, clearColor, colorMask, target: this.fbo, pass: "mask" });
3666
+ }
3667
+ getLayerParameters(layer, layerIndex, viewport) {
3668
+ return {
3669
+ ...layer.props.parameters,
3670
+ blend: true,
3671
+ depthTest: false,
3672
+ ...MASK_BLENDING
3673
+ };
3674
+ }
3675
+ shouldDrawLayer(layer) {
3676
+ return layer.props.operation.includes("mask");
3677
+ }
3678
+ delete() {
3679
+ this.fbo.delete();
3680
+ this.maskMap.delete();
3681
+ }
3682
+ };
3683
+
3684
+ // src/utils/projection-utils.ts
3685
+ var import_core19 = __toESM(require_core(), 1);
3686
+ function joinLayerBounds(layers, viewport) {
3687
+ const bounds = [Infinity, Infinity, -Infinity, -Infinity];
3688
+ for (const layer of layers) {
3689
+ const layerBounds = layer.getBounds();
3690
+ if (layerBounds) {
3691
+ const bottomLeftCommon = layer.projectPosition(layerBounds[0], { viewport, autoOffset: false });
3692
+ const topRightCommon = layer.projectPosition(layerBounds[1], { viewport, autoOffset: false });
3693
+ bounds[0] = Math.min(bounds[0], bottomLeftCommon[0]);
3694
+ bounds[1] = Math.min(bounds[1], bottomLeftCommon[1]);
3695
+ bounds[2] = Math.max(bounds[2], topRightCommon[0]);
3696
+ bounds[3] = Math.max(bounds[3], topRightCommon[1]);
3697
+ }
3698
+ }
3699
+ if (Number.isFinite(bounds[0])) {
3700
+ return bounds;
3701
+ }
3702
+ return null;
3703
+ }
3704
+ var MAX_VIEWPORT_SIZE = 2048;
3705
+ function makeViewport(opts) {
3706
+ const { bounds, viewport, border = 0 } = opts;
3707
+ const { isGeospatial } = viewport;
3708
+ if (bounds[2] <= bounds[0] || bounds[3] <= bounds[1]) {
3709
+ return null;
3710
+ }
3711
+ const centerWorld = viewport.unprojectPosition([
3712
+ (bounds[0] + bounds[2]) / 2,
3713
+ (bounds[1] + bounds[3]) / 2,
3714
+ 0
3715
+ ]);
3716
+ let { width, height, zoom } = opts;
3717
+ if (zoom === void 0) {
3718
+ width = width - border * 2;
3719
+ height = height - border * 2;
3720
+ const scale2 = Math.min(width / (bounds[2] - bounds[0]), height / (bounds[3] - bounds[1]));
3721
+ zoom = Math.min(Math.log2(scale2), 20);
3722
+ } else if (!width || !height) {
3723
+ const scale2 = 2 ** zoom;
3724
+ width = Math.round(Math.abs(bounds[2] - bounds[0]) * scale2);
3725
+ height = Math.round(Math.abs(bounds[3] - bounds[1]) * scale2);
3726
+ const maxSize = MAX_VIEWPORT_SIZE - border * 2;
3727
+ if (width > maxSize || height > maxSize) {
3728
+ const r = maxSize / Math.max(width, height);
3729
+ width = Math.round(width * r);
3730
+ height = Math.round(height * r);
3731
+ zoom += Math.log2(r);
3732
+ }
3733
+ }
3734
+ return isGeospatial ? new import_core19.WebMercatorViewport({
3735
+ id: viewport.id,
3736
+ x: border,
3737
+ y: border,
3738
+ width,
3739
+ height,
3740
+ longitude: centerWorld[0],
3741
+ latitude: centerWorld[1],
3742
+ zoom,
3743
+ orthographic: true
3744
+ }) : new import_core19.OrthographicViewport({
3745
+ id: viewport.id,
3746
+ x: border,
3747
+ y: border,
3748
+ width,
3749
+ height,
3750
+ target: centerWorld,
3751
+ zoom,
3752
+ flipY: false
3753
+ });
3754
+ }
3755
+ function getViewportBounds(viewport, zRange) {
3756
+ let viewportBoundsWorld;
3757
+ if (zRange && zRange.length === 2) {
3758
+ const [minZ, maxZ] = zRange;
3759
+ const bounds0 = viewport.getBounds({ z: minZ });
3760
+ const bounds1 = viewport.getBounds({ z: maxZ });
3761
+ viewportBoundsWorld = [
3762
+ Math.min(bounds0[0], bounds1[0]),
3763
+ Math.min(bounds0[1], bounds1[1]),
3764
+ Math.max(bounds0[2], bounds1[2]),
3765
+ Math.max(bounds0[3], bounds1[3])
3766
+ ];
3767
+ } else {
3768
+ viewportBoundsWorld = viewport.getBounds();
3769
+ }
3770
+ const viewportBottomLeftCommon = viewport.projectPosition(viewportBoundsWorld.slice(0, 2));
3771
+ const viewportTopRightCommon = viewport.projectPosition(viewportBoundsWorld.slice(2, 4));
3772
+ return [
3773
+ viewportBottomLeftCommon[0],
3774
+ viewportBottomLeftCommon[1],
3775
+ viewportTopRightCommon[0],
3776
+ viewportTopRightCommon[1]
3777
+ ];
3778
+ }
3779
+ function getRenderBounds(layerBounds, viewport, zRange) {
3780
+ if (!layerBounds) {
3781
+ return [0, 0, 1, 1];
3782
+ }
3783
+ const viewportBounds = getViewportBounds(viewport, zRange);
3784
+ const paddedBounds = doubleBounds(viewportBounds);
3785
+ if (layerBounds[2] - layerBounds[0] <= paddedBounds[2] - paddedBounds[0] && layerBounds[3] - layerBounds[1] <= paddedBounds[3] - paddedBounds[1]) {
3786
+ return layerBounds;
3787
+ }
3788
+ return [
3789
+ Math.max(layerBounds[0], paddedBounds[0]),
3790
+ Math.max(layerBounds[1], paddedBounds[1]),
3791
+ Math.min(layerBounds[2], paddedBounds[2]),
3792
+ Math.min(layerBounds[3], paddedBounds[3])
3793
+ ];
3794
+ }
3795
+ function doubleBounds(bounds) {
3796
+ const dx = bounds[2] - bounds[0];
3797
+ const dy = bounds[3] - bounds[1];
3798
+ const centerX = (bounds[0] + bounds[2]) / 2;
3799
+ const centerY = (bounds[1] + bounds[3]) / 2;
3800
+ return [centerX - dx, centerY - dy, centerX + dx, centerY + dy];
3801
+ }
3802
+
3803
+ // src/mask/mask-effect.ts
3804
+ var MaskEffect = class {
3805
+ constructor() {
3806
+ this.id = "mask-effect";
3807
+ this.props = null;
3808
+ this.useInPicking = true;
3809
+ this.order = 0;
3810
+ this.channels = [];
3811
+ this.masks = null;
3812
+ }
3813
+ setup({ device }) {
3814
+ this.dummyMaskMap = device.createTexture({
3815
+ width: 1,
3816
+ height: 1
3817
+ });
3818
+ this.maskPass = new MaskPass(device, { id: "default-mask" });
3819
+ this.maskMap = this.maskPass.maskMap;
3820
+ }
3821
+ preRender({
3822
+ layers,
3823
+ layerFilter,
3824
+ viewports,
3825
+ onViewportActive,
3826
+ views,
3827
+ isPicking
3828
+ }) {
3829
+ let didRender = false;
3830
+ if (isPicking) {
3831
+ return { didRender };
3832
+ }
3833
+ const maskLayers = layers.filter((l) => l.props.visible && l.props.operation.includes("mask"));
3834
+ if (maskLayers.length === 0) {
3835
+ this.masks = null;
3836
+ this.channels.length = 0;
3837
+ return { didRender };
3838
+ }
3839
+ this.masks = {};
3840
+ const channelMap = this._sortMaskChannels(maskLayers);
3841
+ const viewport = viewports[0];
3842
+ const viewportChanged = !this.lastViewport || !this.lastViewport.equals(viewport);
3843
+ if (viewport.resolution !== void 0) {
3844
+ import_core20.log.warn("MaskExtension is not supported in GlobeView")();
3845
+ return { didRender };
3846
+ }
3847
+ for (const maskId in channelMap) {
3848
+ const result = this._renderChannel(channelMap[maskId], {
3849
+ layerFilter,
3850
+ onViewportActive,
3851
+ views,
3852
+ viewport,
3853
+ viewportChanged
3854
+ });
3855
+ didRender ||= result;
3856
+ }
3857
+ return { didRender };
3858
+ }
3859
+ _renderChannel(channelInfo, {
3860
+ layerFilter,
3861
+ onViewportActive,
3862
+ views,
3863
+ viewport,
3864
+ viewportChanged
3865
+ }) {
3866
+ let didRender = false;
3867
+ const oldChannelInfo = this.channels[channelInfo.index];
3868
+ if (!oldChannelInfo) {
3869
+ return didRender;
3870
+ }
3871
+ const maskChanged = channelInfo === oldChannelInfo || channelInfo.layers.length !== oldChannelInfo.layers.length || channelInfo.layers.some(
3872
+ (layer, i) => layer !== oldChannelInfo.layers[i] || layer.props.transitions
3873
+ ) || channelInfo.layerBounds.some((b, i) => b !== oldChannelInfo.layerBounds[i]);
3874
+ channelInfo.bounds = oldChannelInfo.bounds;
3875
+ channelInfo.maskBounds = oldChannelInfo.maskBounds;
3876
+ this.channels[channelInfo.index] = channelInfo;
3877
+ if (maskChanged || viewportChanged) {
3878
+ this.lastViewport = viewport;
3879
+ const layerBounds = joinLayerBounds(channelInfo.layers, viewport);
3880
+ channelInfo.bounds = layerBounds && getRenderBounds(layerBounds, viewport);
3881
+ if (maskChanged || !equals(channelInfo.bounds, oldChannelInfo.bounds)) {
3882
+ const { maskPass, maskMap } = this;
3883
+ const maskViewport = layerBounds && makeViewport({
3884
+ bounds: channelInfo.bounds,
3885
+ viewport,
3886
+ width: maskMap.width,
3887
+ height: maskMap.height,
3888
+ border: 1
3889
+ });
3890
+ channelInfo.maskBounds = maskViewport ? maskViewport.getBounds() : [0, 0, 1, 1];
3891
+ maskPass.render({
3892
+ pass: "mask",
3893
+ channel: channelInfo.index,
3894
+ layers: channelInfo.layers,
3895
+ layerFilter,
3896
+ viewports: maskViewport ? [maskViewport] : [],
3897
+ onViewportActive,
3898
+ views,
3899
+ moduleParameters: {
3900
+ devicePixelRatio: 1
3901
+ }
3902
+ });
3903
+ didRender = true;
3904
+ }
3905
+ }
3906
+ this.masks[channelInfo.id] = {
3907
+ index: channelInfo.index,
3908
+ bounds: channelInfo.maskBounds,
3909
+ coordinateOrigin: channelInfo.coordinateOrigin,
3910
+ coordinateSystem: channelInfo.coordinateSystem
3911
+ };
3912
+ return didRender;
3913
+ }
3914
+ _sortMaskChannels(maskLayers) {
3915
+ const channelMap = {};
3916
+ let channelCount = 0;
3917
+ for (const layer of maskLayers) {
3918
+ const { id } = layer.root;
3919
+ let channelInfo = channelMap[id];
3920
+ if (!channelInfo) {
3921
+ if (++channelCount > 4) {
3922
+ import_core20.log.warn("Too many mask layers. The max supported is 4")();
3923
+ continue;
3924
+ }
3925
+ channelInfo = {
3926
+ id,
3927
+ index: this.channels.findIndex((c) => c?.id === id),
3928
+ layers: [],
3929
+ layerBounds: [],
3930
+ coordinateOrigin: layer.root.props.coordinateOrigin,
3931
+ coordinateSystem: layer.root.props.coordinateSystem
3932
+ };
3933
+ channelMap[id] = channelInfo;
3934
+ }
3935
+ channelInfo.layers.push(layer);
3936
+ channelInfo.layerBounds.push(layer.getBounds());
3937
+ }
3938
+ for (let i = 0; i < 4; i++) {
3939
+ const channelInfo = this.channels[i];
3940
+ if (!channelInfo || !(channelInfo.id in channelMap)) {
3941
+ this.channels[i] = null;
3942
+ }
3943
+ }
3944
+ for (const maskId in channelMap) {
3945
+ const channelInfo = channelMap[maskId];
3946
+ if (channelInfo.index < 0) {
3947
+ channelInfo.index = this.channels.findIndex((c) => !c);
3948
+ this.channels[channelInfo.index] = channelInfo;
3949
+ }
3950
+ }
3951
+ return channelMap;
3952
+ }
3953
+ getModuleParameters() {
3954
+ return {
3955
+ maskMap: this.masks ? this.maskMap : this.dummyMaskMap,
3956
+ maskChannels: this.masks
3957
+ };
3958
+ }
3959
+ cleanup() {
3960
+ if (this.dummyMaskMap) {
3961
+ this.dummyMaskMap.delete();
3962
+ this.dummyMaskMap = void 0;
3963
+ }
3964
+ if (this.maskPass) {
3965
+ this.maskPass.delete();
3966
+ this.maskPass = void 0;
3967
+ this.maskMap = void 0;
3968
+ }
3969
+ this.lastViewport = void 0;
3970
+ this.masks = null;
3971
+ this.channels.length = 0;
3972
+ }
3973
+ };
3974
+
3973
3975
  // src/mask/mask-extension.ts
3974
3976
  var defaultProps7 = {
3975
3977
  maskId: "",
@@ -4154,6 +4156,7 @@ if ((terrain_mode == TERRAIN_MODE_USE_COVER) || (terrain_mode == TERRAIN_MODE_US
4154
4156
  id: opts.id,
4155
4157
  colorAttachments: [
4156
4158
  device.createTexture({
4159
+ id: opts.id,
4157
4160
  ...opts.float && {
4158
4161
  format: "rgba32float",
4159
4162
  type: GLEnum.FLOAT
@@ -4335,6 +4338,14 @@ if ((terrain_mode == TERRAIN_MODE_USE_COVER) || (terrain_mode == TERRAIN_MODE_US
4335
4338
 
4336
4339
  // src/terrain/terrain-pass.ts
4337
4340
  var import_core24 = __toESM(require_core(), 1);
4341
+ var TERRAIN_BLENDING = {
4342
+ blendColorOperation: "max",
4343
+ blendColorSrcFactor: "one",
4344
+ blendColorDstFactor: "one",
4345
+ blendAlphaOperation: "max",
4346
+ blendAlphaSrcFactor: "one",
4347
+ blendAlphaDstFactor: "one"
4348
+ };
4338
4349
  var TerrainPass = class extends import_core24._LayersPass {
4339
4350
  getRenderableLayers(viewport, opts) {
4340
4351
  const { layers } = opts;
@@ -4355,23 +4366,15 @@ if ((terrain_mode == TERRAIN_MODE_USE_COVER) || (terrain_mode == TERRAIN_MODE_US
4355
4366
  return;
4356
4367
  }
4357
4368
  target.resize(viewport);
4358
- this.device.withParametersWebGL(
4359
- {
4360
- clearColor: [0, 0, 0, 0],
4361
- blend: true,
4362
- blendFunc: [GLEnum.ONE, GLEnum.ONE],
4363
- blendEquation: GLEnum.MAX,
4364
- depthTest: false
4365
- },
4366
- () => this.render({
4367
- ...opts,
4368
- target,
4369
- pass: "terrain-height-map",
4370
- layers: opts.layers,
4371
- viewports: [viewport],
4372
- effects: []
4373
- })
4374
- );
4369
+ this.render({
4370
+ ...opts,
4371
+ target,
4372
+ pass: "terrain-height-map",
4373
+ layers: opts.layers,
4374
+ viewports: [viewport],
4375
+ effects: [],
4376
+ clearColor: [0, 0, 0, 0]
4377
+ });
4375
4378
  }
4376
4379
  renderTerrainCover(terrainCover, opts) {
4377
4380
  const target = terrainCover.getRenderFramebuffer();
@@ -4381,20 +4384,23 @@ if ((terrain_mode == TERRAIN_MODE_USE_COVER) || (terrain_mode == TERRAIN_MODE_US
4381
4384
  }
4382
4385
  const layers = terrainCover.filterLayers(opts.layers);
4383
4386
  target.resize(viewport);
4384
- this.device.withParametersWebGL(
4385
- {
4386
- clearColor: [0, 0, 0, 0],
4387
- depthTest: false
4388
- },
4389
- () => this.render({
4390
- ...opts,
4391
- target,
4392
- pass: `terrain-cover-${terrainCover.id}`,
4393
- layers,
4394
- effects: [],
4395
- viewports: [viewport]
4396
- })
4397
- );
4387
+ this.render({
4388
+ ...opts,
4389
+ target,
4390
+ pass: `terrain-cover-${terrainCover.id}`,
4391
+ layers,
4392
+ effects: [],
4393
+ viewports: [viewport],
4394
+ clearColor: [0, 0, 0, 0]
4395
+ });
4396
+ }
4397
+ getLayerParameters(layer, layerIndex, viewport) {
4398
+ return {
4399
+ ...layer.props.parameters,
4400
+ blend: true,
4401
+ depthTest: false,
4402
+ ...layer.props.operation.includes("terrain") && TERRAIN_BLENDING
4403
+ };
4398
4404
  }
4399
4405
  };
4400
4406
 
@@ -4432,30 +4438,27 @@ if ((terrain_mode == TERRAIN_MODE_USE_COVER) || (terrain_mode == TERRAIN_MODE_US
4432
4438
  layers.unshift(terrainLayer);
4433
4439
  }
4434
4440
  target.resize(viewport);
4435
- this.device.withParametersWebGL(
4436
- {
4437
- depthTest: false
4438
- },
4439
- () => this.render({
4440
- ...opts,
4441
- pickingFBO: target,
4442
- pass: `terrain-cover-picking-${terrainCover.id}`,
4443
- layers,
4444
- effects: [],
4445
- viewports: [viewport],
4446
- cullRect: void 0,
4447
- deviceRect: viewport,
4448
- pickZ: false
4449
- })
4450
- );
4441
+ this.render({
4442
+ ...opts,
4443
+ pickingFBO: target,
4444
+ pass: `terrain-cover-picking-${terrainCover.id}`,
4445
+ layers,
4446
+ effects: [],
4447
+ viewports: [viewport],
4448
+ cullRect: void 0,
4449
+ deviceRect: viewport,
4450
+ pickZ: false
4451
+ });
4451
4452
  }
4452
4453
  getLayerParameters(layer, layerIndex, viewport) {
4454
+ let parameters2;
4453
4455
  if (this.drawParameters[layer.id]) {
4454
- return this.drawParameters[layer.id];
4456
+ parameters2 = this.drawParameters[layer.id];
4457
+ } else {
4458
+ parameters2 = super.getLayerParameters(layer, layerIndex, viewport);
4459
+ parameters2.blend = true;
4455
4460
  }
4456
- const parameters2 = super.getLayerParameters(layer, layerIndex, viewport);
4457
- parameters2.blend = true;
4458
- return parameters2;
4461
+ return { ...parameters2, depthTest: false };
4459
4462
  }
4460
4463
  };
4461
4464
 
@@ -4540,7 +4543,7 @@ if ((terrain_mode == TERRAIN_MODE_USE_COVER) || (terrain_mode == TERRAIN_MODE_US
4540
4543
  this.isDrapingEnabled = false;
4541
4544
  this.terrainCovers = /* @__PURE__ */ new Map();
4542
4545
  }
4543
- initialize(device) {
4546
+ setup({ device, deck }) {
4544
4547
  this.dummyHeightMap = device.createTexture({
4545
4548
  width: 1,
4546
4549
  height: 1,
@@ -4553,17 +4556,9 @@ if ((terrain_mode == TERRAIN_MODE_USE_COVER) || (terrain_mode == TERRAIN_MODE_US
4553
4556
  } else {
4554
4557
  import_core26.log.warn("Terrain offset mode is not supported by this browser")();
4555
4558
  }
4556
- (0, import_core26.getShaderAssembler)().addDefaultModule(terrainModule);
4557
- }
4558
- preRender(device, opts) {
4559
- if (!this.dummyHeightMap) {
4560
- this.initialize(device);
4561
- for (const layer of opts.layers) {
4562
- if (layer.props.operation.includes("terrain")) {
4563
- layer.setChangeFlags({ extensionsChanged: true });
4564
- }
4565
- }
4566
- }
4559
+ deck._addDefaultShaderModule(terrainModule);
4560
+ }
4561
+ preRender(opts) {
4567
4562
  if (opts.pickZ) {
4568
4563
  this.isDrapingEnabled = false;
4569
4564
  return;
@@ -4601,7 +4596,7 @@ if ((terrain_mode == TERRAIN_MODE_USE_COVER) || (terrain_mode == TERRAIN_MODE_US
4601
4596
  terrainSkipRender: terrainDrawMode === "drape" || !layer.props.operation.includes("draw")
4602
4597
  };
4603
4598
  }
4604
- cleanup() {
4599
+ cleanup({ deck }) {
4605
4600
  if (this.dummyHeightMap) {
4606
4601
  this.dummyHeightMap.delete();
4607
4602
  this.dummyHeightMap = void 0;
@@ -4614,6 +4609,7 @@ if ((terrain_mode == TERRAIN_MODE_USE_COVER) || (terrain_mode == TERRAIN_MODE_US
4614
4609
  terrainCover.delete();
4615
4610
  }
4616
4611
  this.terrainCovers.clear();
4612
+ deck._removeDefaultShaderModule(terrainModule);
4617
4613
  }
4618
4614
  _updateHeightMap(terrainLayers, viewport, opts) {
4619
4615
  if (!this.heightMap) {