@deck.gl/extensions 9.0.34 → 9.1.0-beta.1

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 (128) hide show
  1. package/dist/brushing/brushing-extension.d.ts +1 -0
  2. package/dist/brushing/brushing-extension.d.ts.map +1 -1
  3. package/dist/brushing/brushing-extension.js +15 -19
  4. package/dist/brushing/shader-module.d.ts +8 -2
  5. package/dist/brushing/shader-module.d.ts.map +1 -1
  6. package/dist/brushing/shader-module.js +74 -50
  7. package/dist/clip/clip-extension.d.ts +5 -2
  8. package/dist/clip/clip-extension.d.ts.map +1 -1
  9. package/dist/clip/clip-extension.js +36 -42
  10. package/dist/collision-filter/collision-filter-effect.d.ts +4 -4
  11. package/dist/collision-filter/collision-filter-effect.d.ts.map +1 -1
  12. package/dist/collision-filter/collision-filter-effect.js +27 -13
  13. package/dist/collision-filter/collision-filter-extension.d.ts +1 -1
  14. package/dist/collision-filter/collision-filter-extension.d.ts.map +1 -1
  15. package/dist/collision-filter/collision-filter-extension.js +5 -6
  16. package/dist/collision-filter/collision-filter-pass.d.ts +7 -3
  17. package/dist/collision-filter/collision-filter-pass.d.ts.map +1 -1
  18. package/dist/collision-filter/collision-filter-pass.js +8 -3
  19. package/dist/collision-filter/shader-module.d.ts +3 -2
  20. package/dist/collision-filter/shader-module.d.ts.map +1 -1
  21. package/dist/collision-filter/shader-module.js +74 -52
  22. package/dist/data-filter/aggregator.d.ts +4 -10
  23. package/dist/data-filter/aggregator.d.ts.map +1 -1
  24. package/dist/data-filter/aggregator.js +14 -8
  25. package/dist/data-filter/data-filter-extension.d.ts.map +1 -1
  26. package/dist/data-filter/data-filter-extension.js +40 -38
  27. package/dist/data-filter/shader-module.d.ts +11 -4
  28. package/dist/data-filter/shader-module.d.ts.map +1 -1
  29. package/dist/data-filter/shader-module.js +189 -131
  30. package/dist/dist.dev.js +2699 -2028
  31. package/dist/fill-style/fill-style-extension.d.ts.map +1 -1
  32. package/dist/fill-style/fill-style-extension.js +11 -4
  33. package/dist/fill-style/shader-module.d.ts +64 -6
  34. package/dist/fill-style/shader-module.d.ts.map +1 -1
  35. package/dist/fill-style/shader-module.js +73 -51
  36. package/dist/fp64/fp64-extension.d.ts +1 -0
  37. package/dist/fp64/fp64-extension.d.ts.map +1 -1
  38. package/dist/fp64/fp64-extension.js +7 -19
  39. package/dist/fp64/project64.d.ts +2 -2
  40. package/dist/fp64/project64.d.ts.map +1 -1
  41. package/dist/fp64/project64.glsl.d.ts +1 -1
  42. package/dist/fp64/project64.glsl.d.ts.map +1 -1
  43. package/dist/fp64/project64.glsl.js +18 -21
  44. package/dist/fp64/project64.js +24 -24
  45. package/dist/index.cjs +1017 -523
  46. package/dist/index.cjs.map +3 -3
  47. package/dist/index.d.ts +1 -0
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +3 -0
  50. package/dist/mask/mask-effect.d.ts +5 -3
  51. package/dist/mask/mask-effect.d.ts.map +1 -1
  52. package/dist/mask/mask-effect.js +12 -5
  53. package/dist/mask/mask-extension.d.ts +1 -1
  54. package/dist/mask/mask-extension.d.ts.map +1 -1
  55. package/dist/mask/mask-extension.js +13 -8
  56. package/dist/mask/mask-pass.d.ts +38 -38
  57. package/dist/mask/mask-pass.d.ts.map +1 -1
  58. package/dist/mask/mask-pass.js +3 -0
  59. package/dist/mask/shader-module.d.ts +60 -3
  60. package/dist/mask/shader-module.d.ts.map +1 -1
  61. package/dist/mask/shader-module.js +73 -46
  62. package/dist/path-style/path-style-extension.d.ts.map +1 -1
  63. package/dist/path-style/path-style-extension.js +20 -24
  64. package/dist/path-style/shaders.glsl.d.ts.map +1 -1
  65. package/dist/path-style/shaders.glsl.js +11 -7
  66. package/dist/terrain/height-map-builder.d.ts.map +1 -1
  67. package/dist/terrain/height-map-builder.js +3 -0
  68. package/dist/terrain/shader-module.d.ts +60 -6
  69. package/dist/terrain/shader-module.d.ts.map +1 -1
  70. package/dist/terrain/shader-module.js +69 -61
  71. package/dist/terrain/terrain-cover.d.ts.map +1 -1
  72. package/dist/terrain/terrain-cover.js +3 -0
  73. package/dist/terrain/terrain-effect.d.ts +4 -2
  74. package/dist/terrain/terrain-effect.d.ts.map +1 -1
  75. package/dist/terrain/terrain-effect.js +31 -18
  76. package/dist/terrain/terrain-extension.d.ts.map +1 -1
  77. package/dist/terrain/terrain-extension.js +3 -0
  78. package/dist/terrain/terrain-pass.d.ts +43 -38
  79. package/dist/terrain/terrain-pass.d.ts.map +1 -1
  80. package/dist/terrain/terrain-pass.js +10 -0
  81. package/dist/terrain/terrain-picking-pass.d.ts +5 -0
  82. package/dist/terrain/terrain-picking-pass.d.ts.map +1 -1
  83. package/dist/terrain/terrain-picking-pass.js +10 -0
  84. package/dist/terrain/utils.d.ts.map +1 -1
  85. package/dist/terrain/utils.js +3 -0
  86. package/dist/utils/debug.d.ts +2 -2
  87. package/dist/utils/debug.d.ts.map +1 -1
  88. package/dist/utils/debug.js +3 -1
  89. package/dist/utils/projection-utils.d.ts.map +1 -1
  90. package/dist/utils/projection-utils.js +3 -0
  91. package/dist.min.js +1102 -817
  92. package/package.json +8 -8
  93. package/src/brushing/brushing-extension.ts +17 -20
  94. package/src/brushing/shader-module.ts +58 -47
  95. package/src/clip/clip-extension.ts +38 -40
  96. package/src/collision-filter/collision-filter-effect.ts +31 -20
  97. package/src/collision-filter/collision-filter-extension.ts +6 -7
  98. package/src/collision-filter/collision-filter-pass.ts +9 -3
  99. package/src/collision-filter/shader-module.ts +40 -22
  100. package/src/data-filter/aggregator.ts +23 -11
  101. package/src/data-filter/data-filter-extension.ts +68 -48
  102. package/src/data-filter/shader-module.ts +144 -84
  103. package/src/fill-style/fill-style-extension.ts +13 -5
  104. package/src/fill-style/shader-module.ts +84 -52
  105. package/src/fp64/fp64-extension.ts +8 -19
  106. package/src/fp64/project64.glsl.ts +18 -21
  107. package/src/fp64/project64.ts +27 -28
  108. package/src/index.ts +5 -0
  109. package/src/mask/mask-effect.ts +17 -7
  110. package/src/mask/mask-extension.ts +16 -9
  111. package/src/mask/mask-pass.ts +4 -0
  112. package/src/mask/shader-module.ts +63 -27
  113. package/src/path-style/path-style-extension.ts +27 -28
  114. package/src/path-style/shaders.glsl.ts +13 -7
  115. package/src/terrain/height-map-builder.ts +4 -0
  116. package/src/terrain/shader-module.ts +62 -44
  117. package/src/terrain/terrain-cover.ts +4 -0
  118. package/src/terrain/terrain-effect.ts +36 -19
  119. package/src/terrain/terrain-extension.ts +4 -0
  120. package/src/terrain/terrain-pass.ts +12 -0
  121. package/src/terrain/terrain-picking-pass.ts +12 -0
  122. package/src/terrain/utils.ts +4 -0
  123. package/src/utils/debug.ts +4 -0
  124. package/src/utils/projection-utils.ts +4 -0
  125. package/dist/utils/syntax-tags.d.ts +0 -6
  126. package/dist/utils/syntax-tags.d.ts.map +0 -1
  127. package/dist/utils/syntax-tags.js +0 -5
  128. package/src/utils/syntax-tags.ts +0 -5
package/dist/index.cjs CHANGED
@@ -38,32 +38,56 @@ var import_core2 = require("@deck.gl/core");
38
38
 
39
39
  // dist/brushing/shader-module.js
40
40
  var import_core = require("@deck.gl/core");
41
+ var uniformBlock = (
42
+ /* glsl */
43
+ `uniform brushingUniforms {
44
+ bool enabled;
45
+ highp int target;
46
+ vec2 mousePos;
47
+ float radius;
48
+ } brushing;
49
+ `
50
+ );
51
+ var vertex = (
52
+ /* glsl */
53
+ `
54
+ in vec2 brushingTargets;
55
+
56
+ out float brushing_isVisible;
57
+
58
+ bool brushing_isPointInRange(vec2 position) {
59
+ if (!brushing.enabled) {
60
+ return true;
61
+ }
62
+ vec2 source_commonspace = project_position(position);
63
+ vec2 target_commonspace = project_position(brushing.mousePos);
64
+ float distance = length((target_commonspace - source_commonspace) / project.commonUnitsPerMeter.xy);
65
+
66
+ return distance <= brushing.radius;
67
+ }
68
+
69
+ bool brushing_arePointsInRange(vec2 sourcePos, vec2 targetPos) {
70
+ return brushing_isPointInRange(sourcePos) || brushing_isPointInRange(targetPos);
71
+ }
72
+
73
+ void brushing_setVisible(bool visible) {
74
+ brushing_isVisible = float(visible);
75
+ }
76
+ `
77
+ );
41
78
  var vs = `
42
- uniform bool brushing_enabled;
43
- uniform int brushing_target;
44
- uniform vec2 brushing_mousePos;
45
- uniform float brushing_radius;
46
- in vec2 brushingTargets;
47
- out float brushing_isVisible;
48
- bool brushing_isPointInRange(vec2 position) {
49
- if (!brushing_enabled) {
50
- return true;
51
- }
52
- vec2 source_commonspace = project_position(position);
53
- vec2 target_commonspace = project_position(brushing_mousePos);
54
- float distance = length((target_commonspace - source_commonspace) / project_uCommonUnitsPerMeter.xy);
55
- return distance <= brushing_radius;
56
- }
57
- bool brushing_arePointsInRange(vec2 sourcePos, vec2 targetPos) {
58
- return brushing_isPointInRange(sourcePos) || brushing_isPointInRange(targetPos);
59
- }
60
- void brushing_setVisible(bool visible) {
61
- brushing_isVisible = float(visible);
62
- }
79
+ ${uniformBlock}
80
+ ${vertex}
63
81
  `;
82
+ var fragment = (
83
+ /* glsl */
84
+ `
85
+ in float brushing_isVisible;
86
+ `
87
+ );
64
88
  var fs = `
65
- uniform bool brushing_enabled;
66
- in float brushing_isVisible;
89
+ ${uniformBlock}
90
+ ${fragment}
67
91
  `;
68
92
  var TARGET = {
69
93
  source: 0,
@@ -72,29 +96,32 @@ var TARGET = {
72
96
  source_target: 3
73
97
  };
74
98
  var inject = {
75
- "vs:DECKGL_FILTER_GL_POSITION": `
76
- vec2 brushingTarget;
77
- vec2 brushingSource;
78
- if (brushing_target == 3) {
79
- brushingTarget = geometry.worldPositionAlt.xy;
80
- brushingSource = geometry.worldPosition.xy;
81
- } else if (brushing_target == 0) {
82
- brushingTarget = geometry.worldPosition.xy;
83
- } else if (brushing_target == 1) {
84
- brushingTarget = geometry.worldPositionAlt.xy;
85
- } else {
86
- brushingTarget = brushingTargets;
87
- }
88
- bool visible;
89
- if (brushing_target == 3) {
90
- visible = brushing_arePointsInRange(brushingSource, brushingTarget);
91
- } else {
92
- visible = brushing_isPointInRange(brushingTarget);
93
- }
94
- brushing_setVisible(visible);
95
- `,
99
+ "vs:DECKGL_FILTER_GL_POSITION": (
100
+ /* glsl */
101
+ `
102
+ vec2 brushingTarget;
103
+ vec2 brushingSource;
104
+ if (brushing.target == 3) {
105
+ brushingTarget = geometry.worldPositionAlt.xy;
106
+ brushingSource = geometry.worldPosition.xy;
107
+ } else if (brushing.target == 0) {
108
+ brushingTarget = geometry.worldPosition.xy;
109
+ } else if (brushing.target == 1) {
110
+ brushingTarget = geometry.worldPositionAlt.xy;
111
+ } else {
112
+ brushingTarget = brushingTargets;
113
+ }
114
+ bool visible;
115
+ if (brushing.target == 3) {
116
+ visible = brushing_arePointsInRange(brushingSource, brushingTarget);
117
+ } else {
118
+ visible = brushing_isPointInRange(brushingTarget);
119
+ }
120
+ brushing_setVisible(visible);
121
+ `
122
+ ),
96
123
  "fs:DECKGL_FILTER_COLOR": `
97
- if (brushing_enabled && brushing_isVisible < 0.5) {
124
+ if (brushing.enabled && brushing_isVisible < 0.5) {
98
125
  discard;
99
126
  }
100
127
  `
@@ -111,11 +138,17 @@ var shader_module_default = {
111
138
  }
112
139
  const { brushingEnabled = true, brushingRadius = 1e4, brushingTarget = "source", mousePosition, viewport } = opts;
113
140
  return {
114
- brushing_enabled: Boolean(brushingEnabled && mousePosition && viewport.containsPixel(mousePosition)),
115
- brushing_radius: brushingRadius,
116
- brushing_target: TARGET[brushingTarget] || 0,
117
- brushing_mousePos: mousePosition ? viewport.unproject([mousePosition.x - viewport.x, mousePosition.y - viewport.y]) : [0, 0]
141
+ enabled: Boolean(brushingEnabled && mousePosition && viewport.containsPixel(mousePosition)),
142
+ radius: brushingRadius,
143
+ target: TARGET[brushingTarget] || 0,
144
+ mousePos: mousePosition ? viewport.unproject([mousePosition.x - viewport.x, mousePosition.y - viewport.y]) : [0, 0]
118
145
  };
146
+ },
147
+ uniformTypes: {
148
+ enabled: "i32",
149
+ target: "i32",
150
+ mousePos: "vec2<f32>",
151
+ radius: "f32"
119
152
  }
120
153
  };
121
154
 
@@ -164,6 +197,18 @@ var BrushingExtension = class extends import_core2.LayerExtension {
164
197
  });
165
198
  }
166
199
  }
200
+ draw(params, extension) {
201
+ const { viewport, mousePosition } = params.context;
202
+ const { brushingEnabled, brushingRadius, brushingTarget } = this.props;
203
+ const brushingProps = {
204
+ viewport,
205
+ mousePosition,
206
+ brushingEnabled,
207
+ brushingRadius,
208
+ brushingTarget
209
+ };
210
+ this.setShaderModuleProps({ brushing: brushingProps });
211
+ }
167
212
  };
168
213
  BrushingExtension.defaultProps = defaultProps;
169
214
  BrushingExtension.extensionName = "BrushingExtension";
@@ -173,110 +218,147 @@ var brushing_extension_default = BrushingExtension;
173
218
  var import_core3 = require("@deck.gl/core");
174
219
 
175
220
  // dist/data-filter/shader-module.js
176
- var vs2 = `
177
- uniform bool filter_useSoftMargin;
178
- uniform bool filter_enabled;
179
- uniform bool filter_transformSize;
180
- uniform ivec4 filter_categoryBitMask;
221
+ var uniformBlock2 = (
222
+ /* glsl */
223
+ `uniform dataFilterUniforms {
224
+ bool useSoftMargin;
225
+ bool enabled;
226
+ bool transformSize;
227
+ bool transformColor;
228
+ #ifdef DATAFILTER_TYPE
229
+ DATAFILTER_TYPE min;
230
+ DATAFILTER_TYPE softMin;
231
+ DATAFILTER_TYPE softMax;
232
+ DATAFILTER_TYPE max;
233
+ #ifdef DATAFILTER_DOUBLE
234
+ DATAFILTER_TYPE min64High;
235
+ DATAFILTER_TYPE max64High;
236
+ #endif
237
+ #endif
238
+ #ifdef DATACATEGORY_TYPE
239
+ highp ivec4 categoryBitMask;
240
+ #endif
241
+ } dataFilter;
242
+ `
243
+ );
244
+ var vertex2 = (
245
+ /* glsl */
246
+ `
181
247
  #ifdef DATAFILTER_TYPE
182
- uniform DATAFILTER_TYPE filter_min;
183
- uniform DATAFILTER_TYPE filter_softMin;
184
- uniform DATAFILTER_TYPE filter_softMax;
185
- uniform DATAFILTER_TYPE filter_max;
186
- in DATAFILTER_TYPE filterValues;
248
+ in DATAFILTER_TYPE filterValues;
187
249
  #ifdef DATAFILTER_DOUBLE
188
- in DATAFILTER_TYPE filterValues64Low;
189
- uniform DATAFILTER_TYPE filter_min64High;
190
- uniform DATAFILTER_TYPE filter_max64High;
250
+ in DATAFILTER_TYPE filterValues64Low;
191
251
  #endif
192
252
  #endif
253
+
193
254
  #ifdef DATACATEGORY_TYPE
194
- in DATACATEGORY_TYPE filterCategoryValues;
255
+ in DATACATEGORY_TYPE filterCategoryValues;
195
256
  #endif
257
+
196
258
  out float dataFilter_value;
259
+
197
260
  float dataFilter_reduceValue(float value) {
198
- return value;
261
+ return value;
199
262
  }
200
263
  float dataFilter_reduceValue(vec2 value) {
201
- return min(value.x, value.y);
264
+ return min(value.x, value.y);
202
265
  }
203
266
  float dataFilter_reduceValue(vec3 value) {
204
- return min(min(value.x, value.y), value.z);
267
+ return min(min(value.x, value.y), value.z);
205
268
  }
206
269
  float dataFilter_reduceValue(vec4 value) {
207
- return min(min(value.x, value.y), min(value.z, value.w));
270
+ return min(min(value.x, value.y), min(value.z, value.w));
208
271
  }
272
+
209
273
  #ifdef DATAFILTER_TYPE
210
- void dataFilter_setValue(DATAFILTER_TYPE valueFromMin, DATAFILTER_TYPE valueFromMax) {
211
- if (filter_useSoftMargin) {
212
- DATAFILTER_TYPE leftInRange = mix(
213
- smoothstep(filter_min, filter_softMin, valueFromMin),
214
- step(filter_min, valueFromMin),
215
- step(filter_softMin, filter_min)
216
- );
217
- DATAFILTER_TYPE rightInRange = mix(
218
- 1.0 - smoothstep(filter_softMax, filter_max, valueFromMax),
219
- step(valueFromMax, filter_max),
220
- step(filter_max, filter_softMax)
221
- );
222
- dataFilter_value = dataFilter_reduceValue(leftInRange * rightInRange);
223
- } else {
224
- dataFilter_value = dataFilter_reduceValue(
225
- step(filter_min, valueFromMin) * step(valueFromMax, filter_max)
226
- );
227
- }
228
- }
274
+ void dataFilter_setValue(DATAFILTER_TYPE valueFromMin, DATAFILTER_TYPE valueFromMax) {
275
+ if (dataFilter.useSoftMargin) {
276
+ // smoothstep results are undefined if edge0 \u2265 edge1
277
+ // Fallback to ignore filterSoftRange if it is truncated by filterRange
278
+ DATAFILTER_TYPE leftInRange = mix(
279
+ smoothstep(dataFilter.min, dataFilter.softMin, valueFromMin),
280
+ step(dataFilter.min, valueFromMin),
281
+ step(dataFilter.softMin, dataFilter.min)
282
+ );
283
+ DATAFILTER_TYPE rightInRange = mix(
284
+ 1.0 - smoothstep(dataFilter.softMax, dataFilter.max, valueFromMax),
285
+ step(valueFromMax, dataFilter.max),
286
+ step(dataFilter.max, dataFilter.softMax)
287
+ );
288
+ dataFilter_value = dataFilter_reduceValue(leftInRange * rightInRange);
289
+ } else {
290
+ dataFilter_value = dataFilter_reduceValue(
291
+ step(dataFilter.min, valueFromMin) * step(valueFromMax, dataFilter.max)
292
+ );
293
+ }
294
+ }
229
295
  #endif
296
+
230
297
  #ifdef DATACATEGORY_TYPE
231
- void dataFilter_setCategoryValue(DATACATEGORY_TYPE category) {
232
- #if DATACATEGORY_CHANNELS == 1
233
- int dataFilter_masks = filter_categoryBitMask[int(category / 32.0)];
234
- #elif DATACATEGORY_CHANNELS == 2
235
- ivec2 dataFilter_masks = ivec2(
236
- filter_categoryBitMask[int(category.x / 32.0)],
237
- filter_categoryBitMask[int(category.y / 32.0) + 2]
238
- );
239
- #elif DATACATEGORY_CHANNELS == 3
240
- ivec3 dataFilter_masks = filter_categoryBitMask.xyz;
241
- #else
242
- ivec4 dataFilter_masks = filter_categoryBitMask;
243
- #endif
244
- DATACATEGORY_TYPE dataFilter_bits = DATACATEGORY_TYPE(dataFilter_masks) / pow(DATACATEGORY_TYPE(2.0), mod(category, 32.0));
245
- dataFilter_bits = mod(floor(dataFilter_bits), 2.0);
246
- #if DATACATEGORY_CHANNELS == 1
247
- if(dataFilter_bits == 0.0) dataFilter_value = 0.0;
248
- #else
249
- if(any(equal(dataFilter_bits, DATACATEGORY_TYPE(0.0)))) dataFilter_value = 0.0;
250
- #endif
251
- }
298
+ void dataFilter_setCategoryValue(DATACATEGORY_TYPE category) {
299
+ #if DATACATEGORY_CHANNELS == 1 // One 128-bit mask
300
+ int dataFilter_masks = dataFilter.categoryBitMask[int(category / 32.0)];
301
+ #elif DATACATEGORY_CHANNELS == 2 // Two 64-bit masks
302
+ ivec2 dataFilter_masks = ivec2(
303
+ dataFilter.categoryBitMask[int(category.x / 32.0)],
304
+ dataFilter.categoryBitMask[int(category.y / 32.0) + 2]
305
+ );
306
+ #elif DATACATEGORY_CHANNELS == 3 // Three 32-bit masks
307
+ ivec3 dataFilter_masks = dataFilter.categoryBitMask.xyz;
308
+ #else // Four 32-bit masks
309
+ ivec4 dataFilter_masks = dataFilter.categoryBitMask;
310
+ #endif
311
+
312
+ // Shift mask and extract relevant bits
313
+ DATACATEGORY_TYPE dataFilter_bits = DATACATEGORY_TYPE(dataFilter_masks) / pow(DATACATEGORY_TYPE(2.0), mod(category, 32.0));
314
+ dataFilter_bits = mod(floor(dataFilter_bits), 2.0);
315
+
316
+ #if DATACATEGORY_CHANNELS == 1
317
+ if(dataFilter_bits == 0.0) dataFilter_value = 0.0;
318
+ #else
319
+ if(any(equal(dataFilter_bits, DATACATEGORY_TYPE(0.0)))) dataFilter_value = 0.0;
320
+ #endif
321
+ }
252
322
  #endif
323
+ `
324
+ );
325
+ var vs2 = `
326
+ ${uniformBlock2}
327
+ ${vertex2}
253
328
  `;
254
- var fs2 = `
255
- uniform bool filter_transformColor;
329
+ var fragment2 = (
330
+ /* glsl */
331
+ `
256
332
  in float dataFilter_value;
333
+ `
334
+ );
335
+ var fs2 = `
336
+ ${uniformBlock2}
337
+ ${fragment2}
257
338
  `;
258
339
  function getUniforms(opts) {
259
340
  if (!opts || !("extensions" in opts)) {
260
341
  return {};
261
342
  }
262
- const { filterRange = [-1, 1], filterEnabled = true, filterTransformSize = true, filterTransformColor = true } = opts;
343
+ const { filterRange = [-1, 1], filterEnabled = true, filterTransformSize = true, filterTransformColor = true, categoryBitMask = [0, 0, 0, 0] } = opts;
263
344
  const filterSoftRange = opts.filterSoftRange || filterRange;
264
345
  return {
265
346
  ...Number.isFinite(filterRange[0]) ? {
266
- filter_min: filterRange[0],
267
- filter_softMin: filterSoftRange[0],
268
- filter_softMax: filterSoftRange[1],
269
- filter_max: filterRange[1]
347
+ min: filterRange[0],
348
+ softMin: filterSoftRange[0],
349
+ softMax: filterSoftRange[1],
350
+ max: filterRange[1]
270
351
  } : {
271
- filter_min: filterRange.map((r) => r[0]),
272
- filter_softMin: filterSoftRange.map((r) => r[0]),
273
- filter_softMax: filterSoftRange.map((r) => r[1]),
274
- filter_max: filterRange.map((r) => r[1])
352
+ min: filterRange.map((r) => r[0]),
353
+ softMin: filterSoftRange.map((r) => r[0]),
354
+ softMax: filterSoftRange.map((r) => r[1]),
355
+ max: filterRange.map((r) => r[1])
275
356
  },
276
- filter_enabled: filterEnabled,
277
- filter_useSoftMargin: Boolean(opts.filterSoftRange),
278
- filter_transformSize: filterEnabled && filterTransformSize,
279
- filter_transformColor: filterEnabled && filterTransformColor
357
+ enabled: filterEnabled,
358
+ useSoftMargin: Boolean(opts.filterSoftRange),
359
+ transformSize: filterEnabled && filterTransformSize,
360
+ transformColor: filterEnabled && filterTransformColor,
361
+ categoryBitMask
280
362
  };
281
363
  }
282
364
  function getUniforms64(opts) {
@@ -284,81 +366,119 @@ function getUniforms64(opts) {
284
366
  return {};
285
367
  }
286
368
  const uniforms = getUniforms(opts);
287
- if (Number.isFinite(uniforms.filter_min)) {
288
- const min64High = Math.fround(uniforms.filter_min);
289
- uniforms.filter_min -= min64High;
290
- uniforms.filter_softMin -= min64High;
291
- uniforms.filter_min64High = min64High;
292
- const max64High = Math.fround(uniforms.filter_max);
293
- uniforms.filter_max -= max64High;
294
- uniforms.filter_softMax -= max64High;
295
- uniforms.filter_max64High = max64High;
369
+ if (Number.isFinite(uniforms.min)) {
370
+ const min64High = Math.fround(uniforms.min);
371
+ uniforms.min -= min64High;
372
+ uniforms.softMin -= min64High;
373
+ uniforms.min64High = min64High;
374
+ const max64High = Math.fround(uniforms.max);
375
+ uniforms.max -= max64High;
376
+ uniforms.softMax -= max64High;
377
+ uniforms.max64High = max64High;
296
378
  } else {
297
- const min64High = uniforms.filter_min.map(Math.fround);
298
- uniforms.filter_min = uniforms.filter_min.map((x, i) => x - min64High[i]);
299
- uniforms.filter_softMin = uniforms.filter_softMin.map((x, i) => x - min64High[i]);
300
- uniforms.filter_min64High = min64High;
301
- const max64High = uniforms.filter_max.map(Math.fround);
302
- uniforms.filter_max = uniforms.filter_max.map((x, i) => x - max64High[i]);
303
- uniforms.filter_softMax = uniforms.filter_softMax.map((x, i) => x - max64High[i]);
304
- uniforms.filter_max64High = max64High;
379
+ const min64High = uniforms.min.map(Math.fround);
380
+ uniforms.min = uniforms.min.map((x, i) => x - min64High[i]);
381
+ uniforms.softMin = uniforms.softMin.map((x, i) => x - min64High[i]);
382
+ uniforms.min64High = min64High;
383
+ const max64High = uniforms.max.map(Math.fround);
384
+ uniforms.max = uniforms.max.map((x, i) => x - max64High[i]);
385
+ uniforms.softMax = uniforms.softMax.map((x, i) => x - max64High[i]);
386
+ uniforms.max64High = max64High;
305
387
  }
306
388
  return uniforms;
307
389
  }
308
390
  var inject2 = {
309
- "vs:#main-start": `
310
- dataFilter_value = 1.0;
311
- if (filter_enabled) {
312
- #ifdef DATAFILTER_TYPE
313
- #ifdef DATAFILTER_DOUBLE
314
- dataFilter_setValue(
315
- filterValues - filter_min64High + filterValues64Low,
316
- filterValues - filter_max64High + filterValues64Low
317
- );
318
- #else
319
- dataFilter_setValue(filterValues, filterValues);
320
- #endif
321
- #endif
322
- #ifdef DATACATEGORY_TYPE
323
- dataFilter_setCategoryValue(filterCategoryValues);
324
- #endif
325
- }
326
- `,
327
- "vs:#main-end": `
328
- if (dataFilter_value == 0.0) {
329
- gl_Position = vec4(0.);
330
- }
331
- `,
332
- "vs:DECKGL_FILTER_SIZE": `
333
- if (filter_transformSize) {
334
- size = size * dataFilter_value;
335
- }
336
- `,
337
- "fs:DECKGL_FILTER_COLOR": `
338
- if (dataFilter_value == 0.0) discard;
339
- if (filter_transformColor) {
340
- color.a *= dataFilter_value;
341
- }
342
- `
391
+ "vs:#main-start": (
392
+ /* glsl */
393
+ `
394
+ dataFilter_value = 1.0;
395
+ if (dataFilter.enabled) {
396
+ #ifdef DATAFILTER_TYPE
397
+ #ifdef DATAFILTER_DOUBLE
398
+ dataFilter_setValue(
399
+ filterValues - dataFilter.min64High + filterValues64Low,
400
+ filterValues - dataFilter.max64High + filterValues64Low
401
+ );
402
+ #else
403
+ dataFilter_setValue(filterValues, filterValues);
404
+ #endif
405
+ #endif
406
+
407
+ #ifdef DATACATEGORY_TYPE
408
+ dataFilter_setCategoryValue(filterCategoryValues);
409
+ #endif
410
+ }
411
+ `
412
+ ),
413
+ "vs:#main-end": (
414
+ /* glsl */
415
+ `
416
+ if (dataFilter_value == 0.0) {
417
+ gl_Position = vec4(0.);
418
+ }
419
+ `
420
+ ),
421
+ "vs:DECKGL_FILTER_SIZE": (
422
+ /* glsl */
423
+ `
424
+ if (dataFilter.transformSize) {
425
+ size = size * dataFilter_value;
426
+ }
427
+ `
428
+ ),
429
+ "fs:DECKGL_FILTER_COLOR": (
430
+ /* glsl */
431
+ `
432
+ if (dataFilter_value == 0.0) discard;
433
+ if (dataFilter.transformColor) {
434
+ color.a *= dataFilter_value;
435
+ }
436
+ `
437
+ )
343
438
  };
344
- var shaderModule = {
345
- name: "data-filter",
439
+ function uniformTypesFromOptions(opts) {
440
+ const { categorySize, filterSize, fp64: fp642 } = opts;
441
+ const uniformTypes = {
442
+ useSoftMargin: "i32",
443
+ enabled: "i32",
444
+ transformSize: "i32",
445
+ transformColor: "i32"
446
+ };
447
+ if (filterSize) {
448
+ const uniformFormat = filterSize === 1 ? "f32" : `vec${filterSize}<f32>`;
449
+ uniformTypes.min = uniformFormat;
450
+ uniformTypes.softMin = uniformFormat;
451
+ uniformTypes.softMax = uniformFormat;
452
+ uniformTypes.max = uniformFormat;
453
+ if (fp642) {
454
+ uniformTypes.min64High = uniformFormat;
455
+ uniformTypes.max64High = uniformFormat;
456
+ }
457
+ }
458
+ if (categorySize) {
459
+ uniformTypes.categoryBitMask = "vec4<i32>";
460
+ }
461
+ return uniformTypes;
462
+ }
463
+ var dataFilter = {
464
+ name: "dataFilter",
346
465
  vs: vs2,
347
466
  fs: fs2,
348
467
  inject: inject2,
349
- getUniforms
468
+ getUniforms,
469
+ uniformTypesFromOptions
350
470
  };
351
- var shaderModule64 = {
352
- name: "data-filter-fp64",
471
+ var dataFilter64 = {
472
+ name: "dataFilter",
353
473
  vs: vs2,
354
474
  fs: fs2,
355
475
  inject: inject2,
356
- getUniforms: getUniforms64
476
+ getUniforms: getUniforms64,
477
+ uniformTypesFromOptions
357
478
  };
358
479
 
359
480
  // dist/data-filter/aggregator.js
360
481
  var import_engine = require("@luma.gl/engine");
361
- var import_constants = require("@luma.gl/constants");
362
482
  var AGGREGATE_VS = `#version 300 es
363
483
  #define SHADER_NAME data-filter-vertex-shader
364
484
 
@@ -408,7 +528,9 @@ void main() {
408
528
  `;
409
529
  var FLOAT_TARGET_FEATURES = [
410
530
  "float32-renderable-webgl",
531
+ // ability to render to float texture
411
532
  "texture-blend-float-webgl"
533
+ // ability to blend when rendering to float texture
412
534
  ];
413
535
  function supportsFloatTarget(device) {
414
536
  return FLOAT_TARGET_FEATURES.every((feature) => device.features.has(feature));
@@ -421,7 +543,6 @@ function getFramebuffer(device, useFloatTarget) {
421
543
  colorAttachments: [
422
544
  device.createTexture({
423
545
  format: "rgba32float",
424
- type: 5126,
425
546
  mipmaps: false
426
547
  })
427
548
  ]
@@ -430,10 +551,10 @@ function getFramebuffer(device, useFloatTarget) {
430
551
  return device.createFramebuffer({
431
552
  width: 256,
432
553
  height: 64,
433
- colorAttachments: [device.createTexture({ format: "rgba8unorm", type: 5126, mipmaps: false })]
554
+ colorAttachments: [device.createTexture({ format: "rgba8unorm", mipmaps: false })]
434
555
  });
435
556
  }
436
- function getModel(device, shaderOptions, useFloatTarget) {
557
+ function getModel(device, bufferLayout, shaderOptions, useFloatTarget) {
437
558
  shaderOptions.defines.NON_INSTANCED_MODEL = 1;
438
559
  if (useFloatTarget) {
439
560
  shaderOptions.defines.FLOAT_TARGET = 1;
@@ -442,17 +563,22 @@ function getModel(device, shaderOptions, useFloatTarget) {
442
563
  id: "data-filter-aggregation-model",
443
564
  vertexCount: 1,
444
565
  isInstanced: false,
445
- drawMode: 0,
566
+ topology: "point-list",
446
567
  vs: AGGREGATE_VS,
447
568
  fs: AGGREGATE_FS,
569
+ bufferLayout,
448
570
  ...shaderOptions
449
571
  });
450
572
  }
451
573
  var parameters = {
452
574
  blend: true,
453
- blendFunc: [1, 1, 1, 1],
454
- blendEquation: [32774, 32774],
455
- depthTest: false
575
+ blendColorSrcFactor: "one",
576
+ blendColorDstFactor: "one",
577
+ blendAlphaSrcFactor: "one",
578
+ blendAlphaDstFactor: "one",
579
+ blendColorOperation: "add",
580
+ blendAlphaOperation: "add",
581
+ depthCompare: "never"
456
582
  };
457
583
 
458
584
  // dist/data-filter/data-filter-extension.js
@@ -494,7 +620,9 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
494
620
  defines.DATAFILTER_TYPE = DATA_TYPE_FROM_SIZE[filterSize];
495
621
  defines.DATAFILTER_DOUBLE = Boolean(fp642);
496
622
  }
497
- return { modules: [fp642 ? shaderModule64 : shaderModule], defines };
623
+ const module2 = fp642 ? dataFilter64 : dataFilter;
624
+ module2.uniformTypes = module2.uniformTypesFromOptions(extension.opts);
625
+ return { modules: [module2], defines };
498
626
  }
499
627
  initializeState(context, extension) {
500
628
  const attributeManager = this.getAttributeManager();
@@ -525,7 +653,7 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
525
653
  if (attributeManager && extension.opts.countItems) {
526
654
  const useFloatTarget = supportsFloatTarget(device);
527
655
  attributeManager.add({
528
- filterIndices: {
656
+ filterVertexIndices: {
529
657
  size: useFloatTarget ? 1 : 2,
530
658
  vertexOffset: 1,
531
659
  type: "unorm8",
@@ -544,7 +672,7 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
544
672
  }
545
673
  });
546
674
  const filterFBO = getFramebuffer(device, useFloatTarget);
547
- const filterModel = getModel(device, extension.getShaders.call(this, extension), useFloatTarget);
675
+ const filterModel = getModel(device, attributeManager.getBufferLayouts({ isInstanced: false }), extension.getShaders.call(this, extension), useFloatTarget);
548
676
  this.setState({ filterFBO, filterModel });
549
677
  }
550
678
  }
@@ -553,7 +681,10 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
553
681
  const attributeManager = this.getAttributeManager();
554
682
  const { categorySize } = extension.opts;
555
683
  if (this.state.filterModel) {
556
- const filterNeedsUpdate = ((_a = attributeManager.attributes.filterValues) == null ? void 0 : _a.needsUpdate()) || ((_b = attributeManager.attributes.filterCategoryValues) == null ? void 0 : _b.needsUpdate()) || props.filterEnabled !== oldProps.filterEnabled || props.filterRange !== oldProps.filterRange || props.filterSoftRange !== oldProps.filterSoftRange || props.filterCategories !== oldProps.filterCategories;
684
+ const filterNeedsUpdate = (
685
+ // attributeManager must be defined for filterModel to be set
686
+ ((_a = attributeManager.attributes.filterValues) == null ? void 0 : _a.needsUpdate()) || ((_b = attributeManager.attributes.filterCategoryValues) == null ? void 0 : _b.needsUpdate()) || props.filterEnabled !== oldProps.filterEnabled || props.filterRange !== oldProps.filterRange || props.filterSoftRange !== oldProps.filterSoftRange || props.filterCategories !== oldProps.filterCategories
687
+ );
557
688
  if (filterNeedsUpdate) {
558
689
  this.setState({ filterNeedsUpdate });
559
690
  }
@@ -576,29 +707,46 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
576
707
  const filterFBO = this.state.filterFBO;
577
708
  const filterModel = this.state.filterModel;
578
709
  const filterNeedsUpdate = this.state.filterNeedsUpdate;
579
- const { onFilteredItemsChange } = this.props;
580
710
  if (!this.state.categoryBitMask) {
581
711
  extension._updateCategoryBitMask.call(this, params, extension);
582
712
  }
583
- params.uniforms.filter_categoryBitMask = this.state.categoryBitMask;
713
+ const { onFilteredItemsChange, extensions, filterEnabled, filterRange, filterSoftRange, filterTransformSize, filterTransformColor, filterCategories } = this.props;
714
+ const dataFilterProps = {
715
+ extensions,
716
+ filterEnabled,
717
+ filterRange,
718
+ filterSoftRange,
719
+ filterTransformSize,
720
+ filterTransformColor,
721
+ filterCategories
722
+ };
723
+ if (this.state.categoryBitMask) {
724
+ dataFilterProps.categoryBitMask = this.state.categoryBitMask;
725
+ }
726
+ this.setShaderModuleProps({ dataFilter: dataFilterProps });
584
727
  if (filterNeedsUpdate && onFilteredItemsChange && filterModel) {
585
- const { attributes: { filterValues, filterCategoryValues, filterIndices } } = this.getAttributeManager();
728
+ const attributeManager = this.getAttributeManager();
729
+ const { attributes: { filterValues, filterCategoryValues, filterVertexIndices } } = attributeManager;
586
730
  filterModel.setVertexCount(this.getNumInstances());
587
- this.context.device.clearWebGL({ framebuffer: filterFBO, color: [0, 0, 0, 0] });
588
- filterModel.updateModuleSettings(params.moduleParameters);
589
- filterModel.setAttributes({
731
+ const attributes = {
590
732
  ...filterValues == null ? void 0 : filterValues.getValue(),
591
733
  ...filterCategoryValues == null ? void 0 : filterCategoryValues.getValue(),
592
- ...filterIndices == null ? void 0 : filterIndices.getValue()
734
+ ...filterVertexIndices == null ? void 0 : filterVertexIndices.getValue()
735
+ };
736
+ filterModel.setAttributes(attributes);
737
+ filterModel.shaderInputs.setProps({
738
+ dataFilter: dataFilterProps
593
739
  });
594
- filterModel.setUniforms(params.uniforms);
595
- filterModel.device.withParametersWebGL({
740
+ const viewport = [0, 0, filterFBO.width, filterFBO.height];
741
+ const renderPass = filterModel.device.beginRenderPass({
742
+ id: "data-filter-aggregation",
596
743
  framebuffer: filterFBO,
597
- ...parameters,
598
- viewport: [0, 0, filterFBO.width, filterFBO.height]
599
- }, () => {
600
- filterModel.draw(this.context.renderPass);
744
+ parameters: { viewport },
745
+ clearColor: [0, 0, 0, 0]
601
746
  });
747
+ filterModel.setParameters(parameters);
748
+ filterModel.draw(renderPass);
749
+ renderPass.end();
602
750
  const color = filterModel.device.readPixelsToArrayWebGL(filterFBO);
603
751
  let count = 0;
604
752
  for (let i = 0; i < color.length; i++) {
@@ -614,6 +762,11 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
614
762
  filterFBO == null ? void 0 : filterFBO.destroy();
615
763
  filterModel == null ? void 0 : filterModel.destroy();
616
764
  }
765
+ /**
766
+ * Updates the bitmask used on the GPU to perform the filter based on the
767
+ * `filterCategories` prop. The mapping between categories and bit in the bitmask
768
+ * is performed by `_getCategoryKey()`
769
+ */
617
770
  _updateCategoryBitMask(params, extension) {
618
771
  const { categorySize } = extension.opts;
619
772
  if (!categorySize)
@@ -636,6 +789,10 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
636
789
  }
637
790
  this.state.categoryBitMask = categoryBitMask;
638
791
  }
792
+ /**
793
+ * Returns an index of bit in the bitmask for a given category. If the category has
794
+ * not yet been assigned a bit, a new one is assigned.
795
+ */
639
796
  _getCategoryKey(category, channel) {
640
797
  const categoryMap = this.state.categoryMap[channel];
641
798
  if (!(category in categoryMap)) {
@@ -657,7 +814,11 @@ var import_core4 = require("@deck.gl/core");
657
814
 
658
815
  // dist/fp64/project64.glsl.js
659
816
  var project64_glsl_default = `const vec2 WORLD_SCALE_FP64 = vec2(81.4873275756836, 0.0000032873668232014097);
660
- uniform vec2 project_uViewProjectionMatrixFP64[16];
817
+ uniform project64Uniforms {
818
+ vec2 scale;
819
+ mat4 viewProjectionMatrix;
820
+ mat4 viewProjectionMatrix64Low;
821
+ } project64;
661
822
  void mercatorProject_fp64(vec4 lnglat_fp64, out vec2 out_val[2]) {
662
823
  #if defined(NVIDIA_FP64_WORKAROUND)
663
824
  out_val[0] = sum_fp64(radians_fp64(lnglat_fp64.xy), PI_FP64 * ONE);
@@ -683,7 +844,16 @@ project_position_fp64(position64xy, out_val);
683
844
  }
684
845
  vec4 project_common_position_to_clipspace_fp64(vec2 vertex_pos_modelspace[4]) {
685
846
  vec2 vertex_pos_clipspace[4];
686
- mat4_vec4_mul_fp64(project_uViewProjectionMatrixFP64, vertex_pos_modelspace,
847
+ vec2 viewProjectionMatrixFP64[16];
848
+ for (int i = 0; i < 4; i++) {
849
+ for (int j = 0; j < 4; j++) {
850
+ viewProjectionMatrixFP64[4 * i + j] = vec2(
851
+ project64.viewProjectionMatrix[j][i],
852
+ project64.viewProjectionMatrix64Low[j][i]
853
+ );
854
+ }
855
+ }
856
+ mat4_vec4_mul_fp64(viewProjectionMatrixFP64, vertex_pos_modelspace,
687
857
  vertex_pos_clipspace);
688
858
  return vec4(
689
859
  vertex_pos_clipspace[0].x,
@@ -724,7 +894,13 @@ var project64_default = {
724
894
  name: "project64",
725
895
  dependencies: [import_core4.project, import_shadertools.fp64],
726
896
  vs: project64_glsl_default,
727
- getUniforms: getUniforms2
897
+ getUniforms: getUniforms2,
898
+ uniformTypes: {
899
+ scale: "vec2<f32>",
900
+ // Cannot pass as vec2[16], so instead split into 2 mat4x4
901
+ viewProjectionMatrix: "mat4x4<f32>",
902
+ viewProjectionMatrix64Low: "mat4x4<f32>"
903
+ }
728
904
  };
729
905
  var getMemoizedUniforms = (0, import_core4._memoize)(calculateUniforms);
730
906
  function getUniforms2(opts) {
@@ -736,11 +912,20 @@ function getUniforms2(opts) {
736
912
  }
737
913
  function calculateUniforms({ viewProjectionMatrix, scale }) {
738
914
  const glViewProjectionMatrixFP64 = fp64ifyMatrix4(viewProjectionMatrix);
739
- const scaleFP64 = fp64ify(scale);
915
+ const viewProjectionMatrix64High = new Float32Array(16);
916
+ const viewProjectionMatrix64Low = new Float32Array(16);
917
+ for (let i = 0; i < 4; i++) {
918
+ for (let j = 0; j < 4; j++) {
919
+ const from = 4 * i + j;
920
+ const to = 4 * j + i;
921
+ viewProjectionMatrix64High[to] = glViewProjectionMatrixFP64[2 * from];
922
+ viewProjectionMatrix64Low[to] = glViewProjectionMatrixFP64[2 * from + 1];
923
+ }
924
+ }
740
925
  return {
741
- project_uViewProjectionMatrixFP64: glViewProjectionMatrixFP64,
742
- project64_uViewProjectionMatrix: glViewProjectionMatrixFP64,
743
- project64_uScale: scaleFP64
926
+ scale: fp64ify(scale),
927
+ viewProjectionMatrix: [...viewProjectionMatrix64High],
928
+ viewProjectionMatrix64Low: [...viewProjectionMatrix64Low]
744
929
  };
745
930
  }
746
931
 
@@ -755,6 +940,10 @@ var Fp64Extension = class extends import_core5.LayerExtension {
755
940
  modules: [project64_default]
756
941
  };
757
942
  }
943
+ draw(params, extension) {
944
+ const { viewport } = params.context;
945
+ this.setShaderModuleProps({ project64: { viewport } });
946
+ }
758
947
  };
759
948
  Fp64Extension.extensionName = "Fp64Extension";
760
949
  var fp64_extension_default = Fp64Extension;
@@ -777,19 +966,28 @@ vDashArray = instanceDashArrays;
777
966
  vDashOffset = instanceDashOffsets / width.x;
778
967
  `,
779
968
  "fs:#decl": `
780
- uniform float dashAlignMode;
781
- uniform float capType;
782
- uniform bool dashGapPickable;
969
+ uniform pathStyleUniforms {
970
+ float dashAlignMode;
971
+ bool dashGapPickable;
972
+ } pathStyle;
783
973
  in vec2 vDashArray;
784
974
  in float vDashOffset;
785
975
  `,
976
+ // if given position is in the gap part of the dashed line
977
+ // dashArray.x: solid stroke length, relative to width
978
+ // dashArray.y: gap length, relative to width
979
+ // alignMode:
980
+ // 0 - no adjustment
981
+ // o---- ---- ---- ---- o---- -o---- ---- o
982
+ // 1 - stretch to fit, draw half dash at each end for nicer joints
983
+ // o-- ---- ---- ---- --o-- --o-- ---- --o
786
984
  "fs:#main-start": `
787
985
  float solidLength = vDashArray.x;
788
986
  float gapLength = vDashArray.y;
789
987
  float unitLength = solidLength + gapLength;
790
988
  float offset;
791
989
  if (unitLength > 0.0) {
792
- if (dashAlignMode == 0.0) {
990
+ if (pathStyle.dashAlignMode == 0.0) {
793
991
  offset = vDashOffset;
794
992
  } else {
795
993
  unitLength = vPathLength / round(vPathLength / unitLength);
@@ -797,8 +995,8 @@ offset = solidLength / 2.0;
797
995
  }
798
996
  float unitOffset = mod(vPathPosition.y + offset, unitLength);
799
997
  if (gapLength > 0.0 && unitOffset > solidLength) {
800
- if (capType <= 0.5) {
801
- if (!(dashGapPickable && bool(picking.isActive))) {
998
+ if (path.capType <= 0.5) {
999
+ if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
802
1000
  discard;
803
1001
  }
804
1002
  } else {
@@ -807,7 +1005,7 @@ min(unitOffset - solidLength, unitLength - unitOffset),
807
1005
  vPathPosition.x
808
1006
  ));
809
1007
  if (distToEnd > 1.0) {
810
- if (!(dashGapPickable && bool(picking.isActive))) {
1008
+ if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
811
1009
  discard;
812
1010
  }
813
1011
  }
@@ -868,7 +1066,18 @@ var PathStyleExtension = class extends import_core6.LayerExtension {
868
1066
  if (extension.opts.offset) {
869
1067
  result = (0, import_core6._mergeShaders)(result, offsetShaders);
870
1068
  }
871
- return result;
1069
+ const { inject: inject6 } = result;
1070
+ const pathStyle = {
1071
+ name: "pathStyle",
1072
+ inject: inject6,
1073
+ uniformTypes: {
1074
+ dashAlignMode: "f32",
1075
+ dashGapPickable: "i32"
1076
+ }
1077
+ };
1078
+ return {
1079
+ modules: [pathStyle]
1080
+ };
872
1081
  }
873
1082
  initializeState(context, extension) {
874
1083
  const attributeManager = this.getAttributeManager();
@@ -898,16 +1107,16 @@ var PathStyleExtension = class extends import_core6.LayerExtension {
898
1107
  }
899
1108
  }
900
1109
  updateState(params, extension) {
901
- var _a;
902
1110
  if (!extension.isEnabled(this)) {
903
1111
  return;
904
1112
  }
905
- const uniforms = {};
906
1113
  if (extension.opts.dash) {
907
- uniforms.dashAlignMode = this.props.dashJustified ? 1 : 0;
908
- uniforms.dashGapPickable = Boolean(this.props.dashGapPickable);
1114
+ const pathStyleProps = {
1115
+ dashAlignMode: this.props.dashJustified ? 1 : 0,
1116
+ dashGapPickable: Boolean(this.props.dashGapPickable)
1117
+ };
1118
+ this.setShaderModuleProps({ pathStyle: pathStyleProps });
909
1119
  }
910
- (_a = this.state.model) == null ? void 0 : _a.setUniforms(uniforms);
911
1120
  }
912
1121
  getDashOffsets(path) {
913
1122
  const result = [0];
@@ -937,86 +1146,124 @@ var import_core9 = require("@deck.gl/core");
937
1146
 
938
1147
  // dist/fill-style/shader-module.js
939
1148
  var import_core8 = require("@deck.gl/core");
940
- var patternVs = `
1149
+ var uniformBlock3 = (
1150
+ /* glsl */
1151
+ `uniform fillUniforms {
1152
+ vec2 patternTextureSize;
1153
+ bool patternEnabled;
1154
+ bool patternMask;
1155
+ vec2 uvCoordinateOrigin;
1156
+ vec2 uvCoordinateOrigin64Low;
1157
+ } fill;
1158
+ `
1159
+ );
1160
+ var patternVs = (
1161
+ /* glsl */
1162
+ `
941
1163
  in vec4 fillPatternFrames;
942
1164
  in float fillPatternScales;
943
1165
  in vec2 fillPatternOffsets;
944
- uniform bool fill_patternEnabled;
945
- uniform vec2 fill_patternTextureSize;
1166
+
946
1167
  out vec2 fill_uv;
947
1168
  out vec4 fill_patternBounds;
948
1169
  out vec4 fill_patternPlacement;
1170
+ `
1171
+ );
1172
+ var vs3 = `
1173
+ ${uniformBlock3}
1174
+ ${patternVs}
949
1175
  `;
950
- var patternFs = `
951
- uniform bool fill_patternEnabled;
952
- uniform bool fill_patternMask;
1176
+ var patternFs = (
1177
+ /* glsl */
1178
+ `
953
1179
  uniform sampler2D fill_patternTexture;
954
- uniform vec2 fill_uvCoordinateOrigin;
955
- uniform vec2 fill_uvCoordinateOrigin64Low;
1180
+
956
1181
  in vec4 fill_patternBounds;
957
1182
  in vec4 fill_patternPlacement;
958
1183
  in vec2 fill_uv;
1184
+
959
1185
  const float FILL_UV_SCALE = 512.0 / 40000000.0;
1186
+ `
1187
+ );
1188
+ var fs3 = `
1189
+ ${uniformBlock3}
1190
+ ${patternFs}
960
1191
  `;
961
1192
  var inject3 = {
962
- "vs:DECKGL_FILTER_GL_POSITION": `
963
- fill_uv = geometry.position.xy;
964
- `,
965
- "vs:DECKGL_FILTER_COLOR": `
966
- if (fill_patternEnabled) {
967
- fill_patternBounds = fillPatternFrames / vec4(fill_patternTextureSize, fill_patternTextureSize);
968
- fill_patternPlacement.xy = fillPatternOffsets;
969
- fill_patternPlacement.zw = fillPatternScales * fillPatternFrames.zw;
970
- }
971
- `,
972
- "fs:DECKGL_FILTER_COLOR": `
973
- if (fill_patternEnabled) {
974
- vec2 scale = FILL_UV_SCALE * fill_patternPlacement.zw;
975
- vec2 patternUV = mod(mod(fill_uvCoordinateOrigin, scale) + fill_uvCoordinateOrigin64Low + fill_uv, scale) / scale;
976
- patternUV = mod(fill_patternPlacement.xy + patternUV, 1.0);
977
- vec2 texCoords = fill_patternBounds.xy + fill_patternBounds.zw * patternUV;
978
- vec4 patternColor = texture(fill_patternTexture, texCoords);
979
- color.a *= patternColor.a;
980
- if (!fill_patternMask) {
981
- color.rgb = patternColor.rgb;
982
- }
983
- }
984
- `
1193
+ "vs:DECKGL_FILTER_GL_POSITION": (
1194
+ /* glsl */
1195
+ `
1196
+ fill_uv = geometry.position.xy;
1197
+ `
1198
+ ),
1199
+ "vs:DECKGL_FILTER_COLOR": (
1200
+ /* glsl */
1201
+ `
1202
+ if (fill.patternEnabled) {
1203
+ fill_patternBounds = fillPatternFrames / vec4(fill.patternTextureSize, fill.patternTextureSize);
1204
+ fill_patternPlacement.xy = fillPatternOffsets;
1205
+ fill_patternPlacement.zw = fillPatternScales * fillPatternFrames.zw;
1206
+ }
1207
+ `
1208
+ ),
1209
+ "fs:DECKGL_FILTER_COLOR": (
1210
+ /* glsl */
1211
+ `
1212
+ if (fill.patternEnabled) {
1213
+ vec2 scale = FILL_UV_SCALE * fill_patternPlacement.zw;
1214
+ vec2 patternUV = mod(mod(fill.uvCoordinateOrigin, scale) + fill.uvCoordinateOrigin64Low + fill_uv, scale) / scale;
1215
+ patternUV = mod(fill_patternPlacement.xy + patternUV, 1.0);
1216
+
1217
+ vec2 texCoords = fill_patternBounds.xy + fill_patternBounds.zw * patternUV;
1218
+
1219
+ vec4 patternColor = texture(fill_patternTexture, texCoords);
1220
+ color.a *= patternColor.a;
1221
+ if (!fill.patternMask) {
1222
+ color.rgb = patternColor.rgb;
1223
+ }
1224
+ }
1225
+ `
1226
+ )
985
1227
  };
986
- function getPatternUniforms(opts, uniforms) {
1228
+ function getPatternUniforms(opts) {
987
1229
  if (!opts) {
988
1230
  return {};
989
1231
  }
1232
+ const uniforms = {};
990
1233
  if ("fillPatternTexture" in opts) {
991
1234
  const { fillPatternTexture } = opts;
992
- return {
993
- fill_patternTexture: fillPatternTexture,
994
- fill_patternTextureSize: [fillPatternTexture.width, fillPatternTexture.height]
995
- };
1235
+ uniforms.fill_patternTexture = fillPatternTexture;
1236
+ uniforms.patternTextureSize = [fillPatternTexture.width, fillPatternTexture.height];
996
1237
  }
997
- if ("viewport" in opts) {
1238
+ if ("project" in opts) {
998
1239
  const { fillPatternMask = true, fillPatternEnabled = true } = opts;
999
- const { project_uCommonOrigin: coordinateOriginCommon } = uniforms;
1240
+ const projectUniforms = import_core8.project.getUniforms(opts.project);
1241
+ const { commonOrigin: coordinateOriginCommon } = projectUniforms;
1000
1242
  const coordinateOriginCommon64Low = [
1001
1243
  (0, import_core8.fp64LowPart)(coordinateOriginCommon[0]),
1002
1244
  (0, import_core8.fp64LowPart)(coordinateOriginCommon[1])
1003
1245
  ];
1004
- return {
1005
- fill_uvCoordinateOrigin: coordinateOriginCommon.slice(0, 2),
1006
- fill_uvCoordinateOrigin64Low: coordinateOriginCommon64Low,
1007
- fill_patternMask: fillPatternMask,
1008
- fill_patternEnabled: fillPatternEnabled
1009
- };
1246
+ uniforms.uvCoordinateOrigin = coordinateOriginCommon.slice(0, 2);
1247
+ uniforms.uvCoordinateOrigin64Low = coordinateOriginCommon64Low;
1248
+ uniforms.patternMask = fillPatternMask;
1249
+ uniforms.patternEnabled = fillPatternEnabled;
1010
1250
  }
1011
- return {};
1251
+ return uniforms;
1012
1252
  }
1013
1253
  var patternShaders = {
1014
- name: "fill-pattern",
1015
- vs: patternVs,
1016
- fs: patternFs,
1254
+ name: "fill",
1255
+ vs: vs3,
1256
+ fs: fs3,
1017
1257
  inject: inject3,
1018
1258
  dependencies: [import_core8.project],
1019
- getUniforms: getPatternUniforms
1259
+ getUniforms: getPatternUniforms,
1260
+ uniformTypes: {
1261
+ patternTextureSize: "vec2<f32>",
1262
+ patternEnabled: "i32",
1263
+ patternMask: "i32",
1264
+ uvCoordinateOrigin: "vec2<f32>",
1265
+ uvCoordinateOrigin64Low: "vec2<f32>"
1266
+ }
1020
1267
  };
1021
1268
 
1022
1269
  // dist/fill-style/fill-style-extension.js
@@ -1095,10 +1342,14 @@ var FillStyleExtension = class extends import_core9.LayerExtension {
1095
1342
  if (!extension.isEnabled(this)) {
1096
1343
  return;
1097
1344
  }
1098
- const { fillPatternAtlas } = this.props;
1099
- this.setModuleParameters({
1345
+ const { fillPatternAtlas, fillPatternEnabled, fillPatternMask } = this.props;
1346
+ const fillProps = {
1347
+ project: params.shaderModuleProps.project,
1348
+ fillPatternEnabled,
1349
+ fillPatternMask,
1100
1350
  fillPatternTexture: fillPatternAtlas || this.state.emptyTexture
1101
- });
1351
+ };
1352
+ this.setShaderModuleProps({ fill: fillProps });
1102
1353
  }
1103
1354
  finalizeState() {
1104
1355
  const emptyTexture = this.state.emptyTexture;
@@ -1120,47 +1371,83 @@ var defaultProps5 = {
1120
1371
  clipBounds: [0, 0, 1, 1],
1121
1372
  clipByInstance: void 0
1122
1373
  };
1123
- var shaderFunction = `
1124
- uniform vec4 clip_bounds;
1374
+ var shaderFunction = (
1375
+ /* glsl */
1376
+ `
1377
+ uniform clipUniforms {
1378
+ vec4 bounds;
1379
+ } clip;
1380
+
1125
1381
  bool clip_isInBounds(vec2 position) {
1126
- return position.x >= clip_bounds[0] && position.y >= clip_bounds[1] && position.x < clip_bounds[2] && position.y < clip_bounds[3];
1382
+ return position.x >= clip.bounds[0] && position.y >= clip.bounds[1] && position.x < clip.bounds[2] && position.y < clip.bounds[3];
1127
1383
  }
1128
- `;
1384
+ `
1385
+ );
1129
1386
  var shaderModuleVs = {
1130
- name: "clip-vs",
1131
- vs: shaderFunction
1387
+ name: "clip",
1388
+ vs: shaderFunction,
1389
+ uniformTypes: {
1390
+ bounds: "vec4<f32>"
1391
+ }
1132
1392
  };
1133
1393
  var injectionVs = {
1134
- "vs:#decl": `
1394
+ "vs:#decl": (
1395
+ /* glsl */
1396
+ `
1135
1397
  out float clip_isVisible;
1136
- `,
1137
- "vs:DECKGL_FILTER_GL_POSITION": `
1138
- clip_isVisible = float(clip_isInBounds(geometry.worldPosition.xy));
1139
- `,
1140
- "fs:#decl": `
1398
+ `
1399
+ ),
1400
+ "vs:DECKGL_FILTER_GL_POSITION": (
1401
+ /* glsl */
1402
+ `
1403
+ clip_isVisible = float(clip_isInBounds(geometry.worldPosition.xy));
1404
+ `
1405
+ ),
1406
+ "fs:#decl": (
1407
+ /* glsl */
1408
+ `
1141
1409
  in float clip_isVisible;
1142
- `,
1143
- "fs:DECKGL_FILTER_COLOR": `
1144
- if (clip_isVisible < 0.5) discard;
1145
1410
  `
1411
+ ),
1412
+ "fs:DECKGL_FILTER_COLOR": (
1413
+ /* glsl */
1414
+ `
1415
+ if (clip_isVisible < 0.5) discard;
1416
+ `
1417
+ )
1146
1418
  };
1147
1419
  var shaderModuleFs = {
1148
- name: "clip-fs",
1149
- fs: shaderFunction
1420
+ name: "clip",
1421
+ fs: shaderFunction,
1422
+ uniformTypes: {
1423
+ bounds: "vec4<f32>"
1424
+ }
1150
1425
  };
1151
1426
  var injectionFs = {
1152
- "vs:#decl": `
1427
+ "vs:#decl": (
1428
+ /* glsl */
1429
+ `
1153
1430
  out vec2 clip_commonPosition;
1154
- `,
1155
- "vs:DECKGL_FILTER_GL_POSITION": `
1156
- clip_commonPosition = geometry.position.xy;
1157
- `,
1158
- "fs:#decl": `
1431
+ `
1432
+ ),
1433
+ "vs:DECKGL_FILTER_GL_POSITION": (
1434
+ /* glsl */
1435
+ `
1436
+ clip_commonPosition = geometry.position.xy;
1437
+ `
1438
+ ),
1439
+ "fs:#decl": (
1440
+ /* glsl */
1441
+ `
1159
1442
  in vec2 clip_commonPosition;
1160
- `,
1161
- "fs:DECKGL_FILTER_COLOR": `
1162
- if (!clip_isInBounds(clip_commonPosition)) discard;
1163
1443
  `
1444
+ ),
1445
+ "fs:DECKGL_FILTER_COLOR": (
1446
+ /* glsl */
1447
+ `
1448
+ if (!clip_isInBounds(clip_commonPosition)) discard;
1449
+ `
1450
+ )
1164
1451
  };
1165
1452
  var ClipExtension = class extends import_core10.LayerExtension {
1166
1453
  getShaders() {
@@ -1177,20 +1464,23 @@ var ClipExtension = class extends import_core10.LayerExtension {
1177
1464
  inject: injectionFs
1178
1465
  };
1179
1466
  }
1180
- draw({ uniforms }) {
1467
+ /* eslint-disable camelcase */
1468
+ draw() {
1181
1469
  const { clipBounds } = this.props;
1470
+ const clipProps = {};
1182
1471
  if (this.state.clipByInstance) {
1183
- uniforms.clip_bounds = clipBounds;
1472
+ clipProps.bounds = clipBounds;
1184
1473
  } else {
1185
1474
  const corner0 = this.projectPosition([clipBounds[0], clipBounds[1], 0]);
1186
1475
  const corner1 = this.projectPosition([clipBounds[2], clipBounds[3], 0]);
1187
- uniforms.clip_bounds = [
1476
+ clipProps.bounds = [
1188
1477
  Math.min(corner0[0], corner1[0]),
1189
1478
  Math.min(corner0[1], corner1[1]),
1190
1479
  Math.max(corner0[0], corner1[0]),
1191
1480
  Math.max(corner0[1], corner1[1])
1192
1481
  ];
1193
1482
  }
1483
+ this.setShaderModuleProps({ clip: clipProps });
1194
1484
  }
1195
1485
  };
1196
1486
  ClipExtension.defaultProps = defaultProps5;
@@ -1202,80 +1492,112 @@ var import_core15 = require("@deck.gl/core");
1202
1492
 
1203
1493
  // dist/collision-filter/shader-module.js
1204
1494
  var import_core11 = require("@deck.gl/core");
1205
- var vs3 = `
1495
+ var vs4 = (
1496
+ /* glsl */
1497
+ `
1206
1498
  in float collisionPriorities;
1499
+
1207
1500
  uniform sampler2D collision_texture;
1208
- uniform bool collision_sort;
1209
- uniform bool collision_enabled;
1501
+
1502
+ uniform collisionUniforms {
1503
+ bool sort;
1504
+ bool enabled;
1505
+ } collision;
1506
+
1210
1507
  vec2 collision_getCoords(vec4 position) {
1211
- vec4 collision_clipspace = project_common_position_to_clipspace(position);
1212
- return (1.0 + collision_clipspace.xy / collision_clipspace.w) / 2.0;
1508
+ vec4 collision_clipspace = project_common_position_to_clipspace(position);
1509
+ return (1.0 + collision_clipspace.xy / collision_clipspace.w) / 2.0;
1213
1510
  }
1511
+
1214
1512
  float collision_match(vec2 tex, vec3 pickingColor) {
1215
- vec4 collision_pickingColor = texture(collision_texture, tex);
1216
- float delta = dot(abs(collision_pickingColor.rgb - pickingColor), vec3(1.0));
1217
- float e = 0.001;
1218
- return step(delta, e);
1513
+ vec4 collision_pickingColor = texture(collision_texture, tex);
1514
+ float delta = dot(abs(collision_pickingColor.rgb - pickingColor), vec3(1.0));
1515
+ float e = 0.001;
1516
+ return step(delta, e);
1219
1517
  }
1518
+
1220
1519
  float collision_isVisible(vec2 texCoords, vec3 pickingColor) {
1221
- if (!collision_enabled) {
1222
- return 1.0;
1223
- }
1224
- const int N = 2;
1225
- float accumulator = 0.0;
1226
- vec2 step = vec2(1.0 / project_uViewportSize);
1227
- const float floatN = float(N);
1228
- vec2 delta = -floatN * step;
1229
- for(int i = -N; i <= N; i++) {
1230
- delta.x = -step.x * floatN;
1231
- for(int j = -N; j <= N; j++) {
1232
- accumulator += collision_match(texCoords + delta, pickingColor);
1233
- delta.x += step.x;
1234
- }
1235
- delta.y += step.y;
1236
- }
1237
- float W = 2.0 * floatN + 1.0;
1238
- return pow(accumulator / (W * W), 2.2);
1520
+ if (!collision.enabled) {
1521
+ return 1.0;
1522
+ }
1523
+
1524
+ // Visibility test, sample area of 5x5 pixels in order to fade in/out.
1525
+ // Due to the locality, the lookups will be cached
1526
+ // This reduces the flicker present when objects are shown/hidden
1527
+ const int N = 2;
1528
+ float accumulator = 0.0;
1529
+ vec2 step = vec2(1.0 / project.viewportSize);
1530
+
1531
+ const float floatN = float(N);
1532
+ vec2 delta = -floatN * step;
1533
+ for(int i = -N; i <= N; i++) {
1534
+ delta.x = -step.x * floatN;
1535
+ for(int j = -N; j <= N; j++) {
1536
+ accumulator += collision_match(texCoords + delta, pickingColor);
1537
+ delta.x += step.x;
1538
+ }
1539
+ delta.y += step.y;
1540
+ }
1541
+
1542
+ float W = 2.0 * floatN + 1.0;
1543
+ return pow(accumulator / (W * W), 2.2);
1239
1544
  }
1240
- `;
1545
+ `
1546
+ );
1241
1547
  var inject4 = {
1242
- "vs:#decl": `
1243
- float collision_fade = 1.0;
1244
- `,
1245
- "vs:DECKGL_FILTER_GL_POSITION": `
1246
- if (collision_sort) {
1247
- float collisionPriority = collisionPriorities;
1248
- position.z = -0.001 * collisionPriority * position.w;
1249
- }
1250
- if (collision_enabled) {
1251
- vec4 collision_common_position = project_position(vec4(geometry.worldPosition, 1.0));
1252
- vec2 collision_texCoords = collision_getCoords(collision_common_position);
1253
- collision_fade = collision_isVisible(collision_texCoords, geometry.pickingColor / 255.0);
1254
- if (collision_fade < 0.0001) {
1255
- position = vec4(0.0, 0.0, 2.0, 1.0);
1256
- }
1257
- }
1258
- `,
1259
- "vs:DECKGL_FILTER_COLOR": `
1260
- color.a *= collision_fade;
1548
+ "vs:#decl": (
1549
+ /* glsl */
1550
+ `
1551
+ float collision_fade = 1.0;
1261
1552
  `
1553
+ ),
1554
+ "vs:DECKGL_FILTER_GL_POSITION": (
1555
+ /* glsl */
1556
+ `
1557
+ if (collision.sort) {
1558
+ float collisionPriority = collisionPriorities;
1559
+ position.z = -0.001 * collisionPriority * position.w; // Support range -1000 -> 1000
1560
+ }
1561
+
1562
+ if (collision.enabled) {
1563
+ vec4 collision_common_position = project_position(vec4(geometry.worldPosition, 1.0));
1564
+ vec2 collision_texCoords = collision_getCoords(collision_common_position);
1565
+ collision_fade = collision_isVisible(collision_texCoords, geometry.pickingColor / 255.0);
1566
+ if (collision_fade < 0.0001) {
1567
+ // Position outside clip space bounds to discard
1568
+ position = vec4(0.0, 0.0, 2.0, 1.0);
1569
+ }
1570
+ }
1571
+ `
1572
+ ),
1573
+ "vs:DECKGL_FILTER_COLOR": (
1574
+ /* glsl */
1575
+ `
1576
+ color.a *= collision_fade;
1577
+ `
1578
+ )
1262
1579
  };
1263
- var getCollisionUniforms = (opts, uniforms) => {
1580
+ var getCollisionUniforms = (opts) => {
1264
1581
  if (!opts || !("dummyCollisionMap" in opts)) {
1265
1582
  return {};
1266
1583
  }
1267
- const { collisionFBO, drawToCollisionMap, dummyCollisionMap } = opts;
1584
+ const { enabled, collisionFBO, drawToCollisionMap, dummyCollisionMap } = opts;
1268
1585
  return {
1269
- collision_sort: Boolean(drawToCollisionMap),
1586
+ enabled: enabled && !drawToCollisionMap,
1587
+ sort: Boolean(drawToCollisionMap),
1270
1588
  collision_texture: !drawToCollisionMap && collisionFBO ? collisionFBO.colorAttachments[0] : dummyCollisionMap
1271
1589
  };
1272
1590
  };
1273
1591
  var shader_module_default2 = {
1274
1592
  name: "collision",
1275
1593
  dependencies: [import_core11.project],
1276
- vs: vs3,
1594
+ vs: vs4,
1277
1595
  inject: inject4,
1278
- getUniforms: getCollisionUniforms
1596
+ getUniforms: getCollisionUniforms,
1597
+ uniformTypes: {
1598
+ sort: "i32",
1599
+ enabled: "i32"
1600
+ }
1279
1601
  };
1280
1602
 
1281
1603
  // dist/collision-filter/collision-filter-effect.js
@@ -1294,14 +1616,16 @@ var CollisionFilterPass = class extends import_core12._LayersPass {
1294
1616
  getLayerParameters(layer, layerIndex, viewport) {
1295
1617
  return { ...layer.props.parameters, blend: false, depthRange: [0, 1], depthTest: true };
1296
1618
  }
1297
- getModuleParameters() {
1619
+ getShaderModuleProps() {
1298
1620
  return {
1299
- drawToCollisionMap: true,
1621
+ collision: {
1622
+ drawToCollisionMap: true
1623
+ },
1300
1624
  picking: {
1301
1625
  isActive: 1,
1302
1626
  isAttribute: false
1303
1627
  },
1304
- lightSources: {}
1628
+ lighting: { enabled: false }
1305
1629
  };
1306
1630
  }
1307
1631
  };
@@ -1330,6 +1654,7 @@ var CollisionFilterEffect = class {
1330
1654
  return;
1331
1655
  }
1332
1656
  const collisionLayers = layers.filter(
1657
+ // @ts-ignore
1333
1658
  ({ props: { visible, collisionEnabled } }) => visible && collisionEnabled
1334
1659
  );
1335
1660
  if (collisionLayers.length === 0) {
@@ -1365,7 +1690,12 @@ var CollisionFilterEffect = class {
1365
1690
  if (!oldRenderInfo) {
1366
1691
  return;
1367
1692
  }
1368
- const needsRender = viewportChanged || renderInfo === oldRenderInfo || !(0, import_core14._deepEqual)(oldRenderInfo.layers, renderInfo.layers, 1) || renderInfo.layerBounds.some((b, i) => !(0, import_core13.equals)(b, oldRenderInfo.layerBounds[i])) || renderInfo.allLayersLoaded !== oldRenderInfo.allLayersLoaded || renderInfo.layers.some((layer) => layer.props.transitions);
1693
+ const needsRender = viewportChanged || // If render info is new
1694
+ renderInfo === oldRenderInfo || // If sublayers have changed
1695
+ !(0, import_core14._deepEqual)(oldRenderInfo.layers, renderInfo.layers, 1) || // If a sublayer's bounds have been updated
1696
+ renderInfo.layerBounds.some((b, i) => !(0, import_core13.equals)(b, oldRenderInfo.layerBounds[i])) || // If a sublayer's isLoaded state has been updated
1697
+ renderInfo.allLayersLoaded !== oldRenderInfo.allLayersLoaded || // Some prop is in transition
1698
+ renderInfo.layers.some((layer) => layer.props.transitions);
1369
1699
  this.channels[collisionGroup] = renderInfo;
1370
1700
  if (needsRender) {
1371
1701
  this.lastViewport = viewport;
@@ -1379,17 +1709,28 @@ var CollisionFilterEffect = class {
1379
1709
  viewports: viewport ? [viewport] : [],
1380
1710
  onViewportActive,
1381
1711
  views,
1382
- moduleParameters: {
1383
- dummyCollisionMap: this.dummyCollisionMap,
1384
- devicePixelRatio: collisionFBO.device.canvasContext.getDevicePixelRatio() / DOWNSCALE
1712
+ shaderModuleProps: {
1713
+ collision: {
1714
+ enabled: true,
1715
+ // To avoid feedback loop forming between Framebuffer and active Texture.
1716
+ dummyCollisionMap: this.dummyCollisionMap
1717
+ },
1718
+ project: {
1719
+ // @ts-expect-error TODO - assuming WebGL context
1720
+ devicePixelRatio: collisionFBO.device.canvasContext.getDevicePixelRatio() / DOWNSCALE
1721
+ }
1385
1722
  }
1386
1723
  });
1387
1724
  }
1388
1725
  }
1726
+ /**
1727
+ * Group layers by collisionGroup
1728
+ * Returns a map from collisionGroup to render info
1729
+ */
1389
1730
  _groupByCollisionGroup(device, collisionLayers) {
1390
1731
  const channelMap = {};
1391
1732
  for (const layer of collisionLayers) {
1392
- const { collisionGroup } = layer.props;
1733
+ const collisionGroup = layer.props.collisionGroup;
1393
1734
  let channelInfo = channelMap[collisionGroup];
1394
1735
  if (!channelInfo) {
1395
1736
  channelInfo = { collisionGroup, layers: [], layerBounds: [], allLayersLoaded: true };
@@ -1416,10 +1757,18 @@ var CollisionFilterEffect = class {
1416
1757
  }
1417
1758
  return channelMap;
1418
1759
  }
1419
- getModuleParameters(layer) {
1420
- const { collisionGroup } = layer.props;
1760
+ getShaderModuleProps(layer) {
1761
+ const { collisionGroup, collisionEnabled } = layer.props;
1421
1762
  const { collisionFBOs, dummyCollisionMap } = this;
1422
- return { collisionFBO: collisionFBOs[collisionGroup], dummyCollisionMap };
1763
+ const collisionFBO = collisionFBOs[collisionGroup];
1764
+ const enabled = collisionEnabled && Boolean(collisionFBO);
1765
+ return {
1766
+ collision: {
1767
+ enabled,
1768
+ collisionFBO,
1769
+ dummyCollisionMap
1770
+ }
1771
+ };
1423
1772
  }
1424
1773
  cleanup() {
1425
1774
  if (this.dummyCollisionMap) {
@@ -1450,9 +1799,7 @@ var CollisionFilterEffect = class {
1450
1799
  format: "depth16unorm",
1451
1800
  width,
1452
1801
  height,
1453
- mipmaps: false,
1454
- dataFormat: 6402,
1455
- type: 5125
1802
+ mipmaps: false
1456
1803
  });
1457
1804
  this.collisionFBOs[collisionGroup] = device.createFramebuffer({
1458
1805
  id: `collision-${collisionGroup}`,
@@ -1483,12 +1830,10 @@ var CollisionFilterExtension = class extends import_core15.LayerExtension {
1483
1830
  getShaders() {
1484
1831
  return { modules: [shader_module_default2] };
1485
1832
  }
1486
- draw({ uniforms, context, moduleParameters }) {
1487
- const { collisionEnabled } = this.props;
1488
- const { collisionFBO, drawToCollisionMap } = moduleParameters;
1489
- const enabled = collisionEnabled && Boolean(collisionFBO);
1490
- uniforms.collision_enabled = enabled;
1491
- if (drawToCollisionMap) {
1833
+ /* eslint-disable camelcase */
1834
+ draw({ shaderModuleProps }) {
1835
+ var _a;
1836
+ if ((_a = shaderModuleProps.collision) == null ? void 0 : _a.drawToCollisionMap) {
1492
1837
  this.props = this.clone(this.props.collisionTestProps).props;
1493
1838
  }
1494
1839
  }
@@ -1520,63 +1865,101 @@ var import_core21 = require("@deck.gl/core");
1520
1865
 
1521
1866
  // dist/mask/shader-module.js
1522
1867
  var import_core16 = require("@deck.gl/core");
1523
- var vs4 = `
1524
- uniform vec4 mask_bounds;
1525
- uniform bool mask_maskByInstance;
1868
+ var uniformBlock4 = (
1869
+ /* glsl */
1870
+ `uniform maskUniforms {
1871
+ vec4 bounds;
1872
+ highp int channel;
1873
+ bool enabled;
1874
+ bool inverted;
1875
+ bool maskByInstance;
1876
+ } mask;
1877
+ `
1878
+ );
1879
+ var vertex3 = (
1880
+ /* glsl */
1881
+ `
1526
1882
  vec2 mask_getCoords(vec4 position) {
1527
- return (position.xy - mask_bounds.xy) / (mask_bounds.zw - mask_bounds.xy);
1883
+ return (position.xy - mask.bounds.xy) / (mask.bounds.zw - mask.bounds.xy);
1528
1884
  }
1885
+ `
1886
+ );
1887
+ var vs5 = `
1888
+ ${uniformBlock4}
1889
+ ${vertex3}
1529
1890
  `;
1530
- var fs3 = `
1891
+ var fragment3 = (
1892
+ /* glsl */
1893
+ `
1531
1894
  uniform sampler2D mask_texture;
1532
- uniform int mask_channel;
1533
- uniform bool mask_enabled;
1534
- uniform bool mask_inverted;
1895
+
1535
1896
  bool mask_isInBounds(vec2 texCoords) {
1536
- if (!mask_enabled) {
1537
- return true;
1538
- }
1539
- vec4 maskColor = texture(mask_texture, texCoords);
1540
- float maskValue = 1.0;
1541
- if (mask_channel == 0) {
1542
- maskValue = maskColor.r;
1543
- } else if (mask_channel == 1) {
1544
- maskValue = maskColor.g;
1545
- } else if (mask_channel == 2) {
1546
- maskValue = maskColor.b;
1547
- } else if (mask_channel == 3) {
1548
- maskValue = maskColor.a;
1549
- }
1550
- if (mask_inverted) {
1551
- return maskValue >= 0.5;
1552
- } else {
1553
- return maskValue < 0.5;
1554
- }
1897
+ if (!mask.enabled) {
1898
+ return true;
1899
+ }
1900
+ vec4 maskColor = texture(mask_texture, texCoords);
1901
+ float maskValue = 1.0;
1902
+ if (mask.channel == 0) {
1903
+ maskValue = maskColor.r;
1904
+ } else if (mask.channel == 1) {
1905
+ maskValue = maskColor.g;
1906
+ } else if (mask.channel == 2) {
1907
+ maskValue = maskColor.b;
1908
+ } else if (mask.channel == 3) {
1909
+ maskValue = maskColor.a;
1910
+ }
1911
+
1912
+ if (mask.inverted) {
1913
+ return maskValue >= 0.5;
1914
+ } else {
1915
+ return maskValue < 0.5;
1916
+ }
1555
1917
  }
1918
+ `
1919
+ );
1920
+ var fs4 = `
1921
+ ${uniformBlock4}
1922
+ ${fragment3}
1556
1923
  `;
1557
1924
  var inject5 = {
1558
- "vs:#decl": `
1925
+ "vs:#decl": (
1926
+ /* glsl */
1927
+ `
1559
1928
  out vec2 mask_texCoords;
1560
- `,
1561
- "vs:#main-end": `
1562
- vec4 mask_common_position;
1563
- if (mask_maskByInstance) {
1564
- mask_common_position = project_position(vec4(geometry.worldPosition, 1.0));
1565
- } else {
1566
- mask_common_position = geometry.position;
1567
- }
1568
- mask_texCoords = mask_getCoords(mask_common_position);
1569
- `,
1570
- "fs:#decl": `
1929
+ `
1930
+ ),
1931
+ "vs:#main-end": (
1932
+ /* glsl */
1933
+ `
1934
+ vec4 mask_common_position;
1935
+ if (mask.maskByInstance) {
1936
+ mask_common_position = project_position(vec4(geometry.worldPosition, 1.0));
1937
+ } else {
1938
+ mask_common_position = geometry.position;
1939
+ }
1940
+ mask_texCoords = mask_getCoords(mask_common_position);
1941
+ `
1942
+ ),
1943
+ "fs:#decl": (
1944
+ /* glsl */
1945
+ `
1571
1946
  in vec2 mask_texCoords;
1572
- `,
1573
- "fs:#main-start": `
1574
- if (mask_enabled) {
1575
- bool mask = mask_isInBounds(mask_texCoords);
1576
- fragColor = texture(mask_texture, mask_texCoords);
1577
- if (!mask) discard;
1578
- }
1579
1947
  `
1948
+ ),
1949
+ "fs:#main-start": (
1950
+ /* glsl */
1951
+ `
1952
+ if (mask.enabled) {
1953
+ bool mask = mask_isInBounds(mask_texCoords);
1954
+
1955
+ // Debug: show extent of render target
1956
+ // fragColor = vec4(mask_texCoords, 0.0, 1.0);
1957
+ // fragColor = texture(mask_texture, mask_texCoords);
1958
+
1959
+ if (!mask) discard;
1960
+ }
1961
+ `
1962
+ )
1580
1963
  };
1581
1964
  var getMaskUniforms = (opts) => {
1582
1965
  if (opts && "maskMap" in opts) {
@@ -1584,15 +1967,22 @@ var getMaskUniforms = (opts) => {
1584
1967
  mask_texture: opts.maskMap
1585
1968
  };
1586
1969
  }
1587
- return {};
1970
+ return opts || {};
1588
1971
  };
1589
1972
  var shader_module_default3 = {
1590
1973
  name: "mask",
1591
1974
  dependencies: [import_core16.project],
1592
- vs: vs4,
1593
- fs: fs3,
1975
+ vs: vs5,
1976
+ fs: fs4,
1594
1977
  inject: inject5,
1595
- getUniforms: getMaskUniforms
1978
+ getUniforms: getMaskUniforms,
1979
+ uniformTypes: {
1980
+ bounds: "vec4<f32>",
1981
+ channel: "i32",
1982
+ enabled: "i32",
1983
+ inverted: "i32",
1984
+ maskByInstance: "i32"
1985
+ }
1596
1986
  };
1597
1987
 
1598
1988
  // dist/mask/mask-effect.js
@@ -1821,13 +2211,26 @@ var MaskEffect = class {
1821
2211
  }
1822
2212
  return { didRender };
1823
2213
  }
2214
+ /* eslint-disable-next-line complexity */
1824
2215
  _renderChannel(channelInfo, { layerFilter, onViewportActive, views, viewport, viewportChanged }) {
1825
2216
  let didRender = false;
1826
2217
  const oldChannelInfo = this.channels[channelInfo.index];
1827
2218
  if (!oldChannelInfo) {
1828
2219
  return didRender;
1829
2220
  }
1830
- const maskChanged = channelInfo === oldChannelInfo || channelInfo.layers.length !== oldChannelInfo.layers.length || channelInfo.layers.some((layer, i) => layer !== oldChannelInfo.layers[i] || layer.props.transitions) || channelInfo.layerBounds.some((b, i) => b !== oldChannelInfo.layerBounds[i]);
2221
+ const maskChanged = (
2222
+ // If a channel is new
2223
+ channelInfo === oldChannelInfo || // If sublayers have changed
2224
+ channelInfo.layers.length !== oldChannelInfo.layers.length || channelInfo.layers.some((layer, i) => (
2225
+ // Layer instance is updated
2226
+ // Layer props might have changed
2227
+ // Undetermined props could have an effect on the output geometry of a mask layer,
2228
+ // for example getRadius+updateTriggers, radiusScale, modelMatrix
2229
+ layer !== oldChannelInfo.layers[i] || // Some prop is in transition
2230
+ layer.props.transitions
2231
+ )) || // If a sublayer's positions have been updated, the cached bounds will change shallowly
2232
+ channelInfo.layerBounds.some((b, i) => b !== oldChannelInfo.layerBounds[i])
2233
+ );
1831
2234
  channelInfo.bounds = oldChannelInfo.bounds;
1832
2235
  channelInfo.maskBounds = oldChannelInfo.maskBounds;
1833
2236
  this.channels[channelInfo.index] = channelInfo;
@@ -1853,8 +2256,10 @@ var MaskEffect = class {
1853
2256
  viewports: maskViewport ? [maskViewport] : [],
1854
2257
  onViewportActive,
1855
2258
  views,
1856
- moduleParameters: {
1857
- devicePixelRatio: 1
2259
+ shaderModuleProps: {
2260
+ project: {
2261
+ devicePixelRatio: 1
2262
+ }
1858
2263
  }
1859
2264
  });
1860
2265
  didRender = true;
@@ -1868,6 +2273,13 @@ var MaskEffect = class {
1868
2273
  };
1869
2274
  return didRender;
1870
2275
  }
2276
+ /**
2277
+ * Find a channel to render each mask into
2278
+ * If a maskId already exists, diff and update the existing channel
2279
+ * Otherwise replace a removed mask
2280
+ * Otherwise create a new channel
2281
+ * Returns a map from mask layer id to channel info
2282
+ */
1871
2283
  _sortMaskChannels(maskLayers) {
1872
2284
  const channelMap = {};
1873
2285
  let channelCount = 0;
@@ -1907,10 +2319,12 @@ var MaskEffect = class {
1907
2319
  }
1908
2320
  return channelMap;
1909
2321
  }
1910
- getModuleParameters() {
2322
+ getShaderModuleProps() {
1911
2323
  return {
1912
- maskMap: this.masks ? this.maskMap : this.dummyMaskMap,
1913
- maskChannels: this.masks
2324
+ mask: {
2325
+ maskMap: this.masks ? this.maskMap : this.dummyMaskMap,
2326
+ maskChannels: this.masks
2327
+ }
1914
2328
  };
1915
2329
  }
1916
2330
  cleanup() {
@@ -1950,30 +2364,33 @@ var MaskExtension = class extends import_core21.LayerExtension {
1950
2364
  modules: [shader_module_default3]
1951
2365
  };
1952
2366
  }
1953
- draw({ uniforms, context, moduleParameters }) {
1954
- uniforms.mask_maskByInstance = this.state.maskByInstance;
2367
+ /* eslint-disable camelcase */
2368
+ draw({ context, shaderModuleProps }) {
2369
+ const maskProps = {};
2370
+ maskProps.maskByInstance = Boolean(this.state.maskByInstance);
1955
2371
  const { maskId, maskInverted } = this.props;
1956
- const { maskChannels } = moduleParameters;
2372
+ const { maskChannels } = shaderModuleProps.mask || {};
1957
2373
  const { viewport } = context;
1958
2374
  if (maskChannels && maskChannels[maskId]) {
1959
2375
  const { index, bounds, coordinateOrigin: fromCoordinateOrigin } = maskChannels[maskId];
1960
2376
  let { coordinateSystem: fromCoordinateSystem } = maskChannels[maskId];
1961
- uniforms.mask_enabled = true;
1962
- uniforms.mask_channel = index;
1963
- uniforms.mask_inverted = maskInverted;
2377
+ maskProps.enabled = true;
2378
+ maskProps.channel = index;
2379
+ maskProps.inverted = maskInverted;
1964
2380
  if (fromCoordinateSystem === import_core21.COORDINATE_SYSTEM.DEFAULT) {
1965
2381
  fromCoordinateSystem = viewport.isGeospatial ? import_core21.COORDINATE_SYSTEM.LNGLAT : import_core21.COORDINATE_SYSTEM.CARTESIAN;
1966
2382
  }
1967
2383
  const opts = { modelMatrix: null, fromCoordinateOrigin, fromCoordinateSystem };
1968
2384
  const bl = this.projectPosition([bounds[0], bounds[1], 0], opts);
1969
2385
  const tr = this.projectPosition([bounds[2], bounds[3], 0], opts);
1970
- uniforms.mask_bounds = [bl[0], bl[1], tr[0], tr[1]];
2386
+ maskProps.bounds = [bl[0], bl[1], tr[0], tr[1]];
1971
2387
  } else {
1972
2388
  if (maskId) {
1973
2389
  import_core21.log.warn(`Could not find a mask layer with id: ${maskId}`)();
1974
2390
  }
1975
- uniforms.mask_enabled = false;
2391
+ maskProps.enabled = false;
1976
2392
  }
2393
+ this.setShaderModuleProps({ mask: maskProps });
1977
2394
  }
1978
2395
  };
1979
2396
  MaskExtension.defaultProps = defaultProps7;
@@ -1990,78 +2407,103 @@ var import_core25 = require("@deck.gl/core");
1990
2407
  var import_core22 = require("@deck.gl/core");
1991
2408
  var TERRAIN_MODE = {
1992
2409
  NONE: 0,
2410
+ /** A terrain layer rendering encoded ground elevation into the height map */
1993
2411
  WRITE_HEIGHT_MAP: 1,
2412
+ /** An offset layer reading encoded ground elevation from the height map */
1994
2413
  USE_HEIGHT_MAP: 2,
2414
+ /** A terrain layer rendering to screen, using the cover fbo overlaid with its own texture */
1995
2415
  USE_COVER: 3,
2416
+ /** A terrain layer rendering to screen, using the cover fbo as texture */
1996
2417
  USE_COVER_ONLY: 4,
2418
+ /** Draped layer is rendered into a texture, and never to screen */
1997
2419
  SKIP: 5
1998
2420
  };
1999
2421
  var TERRAIN_MODE_CONSTANTS = Object.keys(TERRAIN_MODE).map((key) => `const float TERRAIN_MODE_${key} = ${TERRAIN_MODE[key]}.0;`).join("\n");
2422
+ var uniformBlock5 = (
2423
+ // eslint-disable-next-line prefer-template
2424
+ TERRAIN_MODE_CONSTANTS + /* glsl */
2425
+ `
2426
+ uniform terrainUniforms {
2427
+ float mode;
2428
+ vec4 bounds;
2429
+ } terrain;
2430
+
2431
+ uniform sampler2D terrain_map;
2432
+ `
2433
+ );
2000
2434
  var terrainModule = {
2001
2435
  name: "terrain",
2002
2436
  dependencies: [import_core22.project],
2437
+ // eslint-disable-next-line prefer-template
2438
+ vs: uniformBlock5 + /* glsl */
2439
+ "out vec3 commonPos;",
2440
+ // eslint-disable-next-line prefer-template
2441
+ fs: uniformBlock5 + /* glsl */
2442
+ "in vec3 commonPos;",
2003
2443
  inject: {
2004
- "vs:#decl": `
2005
- uniform float terrain_mode;
2006
- uniform sampler2D terrain_map;
2007
- uniform vec4 terrain_bounds;
2008
- out vec3 commonPos;
2009
- ` + TERRAIN_MODE_CONSTANTS,
2010
- "vs:#main-start": `
2011
- if (terrain_mode == TERRAIN_MODE_SKIP) {
2012
- gl_Position = vec4(0.0);
2013
- return;
2444
+ "vs:#main-start": (
2445
+ /* glsl */
2446
+ `
2447
+ if (terrain.mode == TERRAIN_MODE_SKIP) {
2448
+ gl_Position = vec4(0.0);
2449
+ return;
2014
2450
  }
2015
- `,
2016
- "vs:DECKGL_FILTER_GL_POSITION": `
2451
+ `
2452
+ ),
2453
+ "vs:DECKGL_FILTER_GL_POSITION": (
2454
+ /* glsl */
2455
+ `
2017
2456
  commonPos = geometry.position.xyz;
2018
- if (terrain_mode == TERRAIN_MODE_WRITE_HEIGHT_MAP) {
2019
- vec2 texCoords = (commonPos.xy - terrain_bounds.xy) / terrain_bounds.zw;
2020
- position = vec4(texCoords * 2.0 - 1.0, 0.0, 1.0);
2021
- commonPos.z += project_uCommonOrigin.z;
2022
- }
2023
- if (terrain_mode == TERRAIN_MODE_USE_HEIGHT_MAP) {
2024
- vec3 anchor = geometry.worldPosition;
2025
- anchor.z = 0.0;
2026
- vec3 anchorCommon = project_position(anchor);
2027
- vec2 texCoords = (anchorCommon.xy - terrain_bounds.xy) / terrain_bounds.zw;
2028
- if (texCoords.x >= 0.0 && texCoords.y >= 0.0 && texCoords.x <= 1.0 && texCoords.y <= 1.0) {
2029
- float terrainZ = texture(terrain_map, texCoords).r;
2030
- geometry.position.z += terrainZ;
2031
- position = project_common_position_to_clipspace(geometry.position);
2032
- }
2033
- }
2034
- `,
2035
- "fs:#decl": `
2036
- uniform float terrain_mode;
2037
- uniform sampler2D terrain_map;
2038
- uniform vec4 terrain_bounds;
2039
- in vec3 commonPos;
2040
- ` + TERRAIN_MODE_CONSTANTS,
2041
- "fs:#main-start": `
2042
- if (terrain_mode == TERRAIN_MODE_WRITE_HEIGHT_MAP) {
2043
- fragColor = vec4(commonPos.z, 0.0, 0.0, 1.0);
2044
- return;
2045
- }
2046
- `,
2047
- "fs:DECKGL_FILTER_COLOR": `
2048
- if ((terrain_mode == TERRAIN_MODE_USE_COVER) || (terrain_mode == TERRAIN_MODE_USE_COVER_ONLY)) {
2049
- vec2 texCoords = (commonPos.xy - terrain_bounds.xy) / terrain_bounds.zw;
2050
- vec4 pixel = texture(terrain_map, texCoords);
2051
- if (terrain_mode == TERRAIN_MODE_USE_COVER_ONLY) {
2052
- color = pixel;
2053
- } else {
2054
- color = pixel + color * (1.0 - pixel.a);
2055
- }
2056
- return;
2457
+ if (terrain.mode == TERRAIN_MODE_WRITE_HEIGHT_MAP) {
2458
+ vec2 texCoords = (commonPos.xy - terrain.bounds.xy) / terrain.bounds.zw;
2459
+ position = vec4(texCoords * 2.0 - 1.0, 0.0, 1.0);
2460
+ commonPos.z += project.commonOrigin.z;
2461
+ }
2462
+ if (terrain.mode == TERRAIN_MODE_USE_HEIGHT_MAP) {
2463
+ vec3 anchor = geometry.worldPosition;
2464
+ anchor.z = 0.0;
2465
+ vec3 anchorCommon = project_position(anchor);
2466
+ vec2 texCoords = (anchorCommon.xy - terrain.bounds.xy) / terrain.bounds.zw;
2467
+ if (texCoords.x >= 0.0 && texCoords.y >= 0.0 && texCoords.x <= 1.0 && texCoords.y <= 1.0) {
2468
+ float terrainZ = texture(terrain_map, texCoords).r;
2469
+ geometry.position.z += terrainZ;
2470
+ position = project_common_position_to_clipspace(geometry.position);
2471
+ }
2472
+ }
2473
+ `
2474
+ ),
2475
+ "fs:#main-start": (
2476
+ /* glsl */
2477
+ `
2478
+ if (terrain.mode == TERRAIN_MODE_WRITE_HEIGHT_MAP) {
2479
+ fragColor = vec4(commonPos.z, 0.0, 0.0, 1.0);
2480
+ return;
2481
+ }
2482
+ `
2483
+ ),
2484
+ "fs:DECKGL_FILTER_COLOR": (
2485
+ /* glsl */
2486
+ `
2487
+ if ((terrain.mode == TERRAIN_MODE_USE_COVER) || (terrain.mode == TERRAIN_MODE_USE_COVER_ONLY)) {
2488
+ vec2 texCoords = (commonPos.xy - terrain.bounds.xy) / terrain.bounds.zw;
2489
+ vec4 pixel = texture(terrain_map, texCoords);
2490
+ if (terrain.mode == TERRAIN_MODE_USE_COVER_ONLY) {
2491
+ color = pixel;
2492
+ } else {
2493
+ // pixel is premultiplied
2494
+ color = pixel + color * (1.0 - pixel.a);
2495
+ }
2496
+ return;
2057
2497
  }
2058
- `
2498
+ `
2499
+ )
2059
2500
  },
2060
- getUniforms: (opts = {}, uniforms) => {
2061
- var _a;
2501
+ // eslint-disable-next-line complexity
2502
+ getUniforms: (opts = {}) => {
2062
2503
  if ("dummyHeightMap" in opts) {
2063
2504
  const { drawToTerrainHeightMap, heightMap, heightMapBounds, dummyHeightMap, terrainCover, useTerrainHeightMap, terrainSkipRender } = opts;
2064
- const { project_uCommonOrigin } = uniforms;
2505
+ const projectUniforms = import_core22.project.getUniforms(opts.project);
2506
+ const { commonOrigin } = projectUniforms;
2065
2507
  let mode = terrainSkipRender ? TERRAIN_MODE.SKIP : TERRAIN_MODE.NONE;
2066
2508
  let sampler = dummyHeightMap;
2067
2509
  let bounds = null;
@@ -2073,10 +2515,9 @@ return;
2073
2515
  sampler = heightMap;
2074
2516
  bounds = heightMapBounds;
2075
2517
  } else if (terrainCover) {
2076
- const isPicking = (_a = opts.picking) == null ? void 0 : _a.isActive;
2077
- const fbo = isPicking ? terrainCover.getPickingFramebuffer() : terrainCover.getRenderFramebuffer();
2518
+ const fbo = opts.isPicking ? terrainCover.getPickingFramebuffer() : terrainCover.getRenderFramebuffer();
2078
2519
  sampler = fbo == null ? void 0 : fbo.colorAttachments[0].texture;
2079
- if (isPicking) {
2520
+ if (opts.isPicking) {
2080
2521
  mode = TERRAIN_MODE.SKIP;
2081
2522
  }
2082
2523
  if (sampler) {
@@ -2087,22 +2528,27 @@ return;
2087
2528
  }
2088
2529
  }
2089
2530
  return {
2090
- terrain_mode: mode,
2531
+ mode,
2091
2532
  terrain_map: sampler,
2092
- terrain_bounds: bounds ? [
2093
- bounds[0] - project_uCommonOrigin[0],
2094
- bounds[1] - project_uCommonOrigin[1],
2533
+ // Convert bounds to the common space, as [minX, minY, width, height]
2534
+ bounds: bounds ? [
2535
+ bounds[0] - commonOrigin[0],
2536
+ bounds[1] - commonOrigin[1],
2095
2537
  bounds[2] - bounds[0],
2096
2538
  bounds[3] - bounds[1]
2097
2539
  ] : [0, 0, 0, 0]
2098
2540
  };
2099
2541
  }
2100
- return null;
2542
+ return {};
2543
+ },
2544
+ uniformTypes: {
2545
+ mode: "f32",
2546
+ bounds: "vec4<f32>"
2101
2547
  }
2102
2548
  };
2103
2549
 
2104
2550
  // dist/terrain/utils.js
2105
- var import_constants2 = require("@luma.gl/constants");
2551
+ var import_constants = require("@luma.gl/constants");
2106
2552
  function createRenderTarget(device, opts) {
2107
2553
  return device.createFramebuffer({
2108
2554
  id: opts.id,
@@ -2141,6 +2587,7 @@ var TerrainCover = class {
2141
2587
  get id() {
2142
2588
  return this.targetLayer.id;
2143
2589
  }
2590
+ /** returns true if the target layer is still in use (i.e. not finalized) */
2144
2591
  get isActive() {
2145
2592
  return Boolean(this.targetLayer.getCurrentLayer());
2146
2593
  }
@@ -2160,6 +2607,7 @@ var TerrainCover = class {
2160
2607
  }
2161
2608
  return layersChanged || sizeChanged;
2162
2609
  }
2610
+ /** Compare layers with the last version. Only rerender if necessary. */
2163
2611
  _updateLayers(layers) {
2164
2612
  let needsRedraw = false;
2165
2613
  layers = this.tile ? getIntersectingLayers(this.tile, layers) : layers;
@@ -2179,6 +2627,7 @@ var TerrainCover = class {
2179
2627
  }
2180
2628
  return needsRedraw;
2181
2629
  }
2630
+ /** Compare viewport and terrain bounds with the last version. Only rerender if necesary. */
2182
2631
  _updateViewport(viewport) {
2183
2632
  var _a;
2184
2633
  const targetLayer = this.targetLayer;
@@ -2352,6 +2801,13 @@ var TerrainPass = class extends import_core23._LayersPass {
2352
2801
  ...layer.props.operation.includes("terrain") && TERRAIN_BLENDING
2353
2802
  };
2354
2803
  }
2804
+ getShaderModuleProps(layer, effects, otherShaderModuleProps) {
2805
+ return {
2806
+ terrain: {
2807
+ project: otherShaderModuleProps.project
2808
+ }
2809
+ };
2810
+ }
2355
2811
  };
2356
2812
 
2357
2813
  // dist/terrain/terrain-picking-pass.js
@@ -2395,6 +2851,8 @@ var TerrainPickingPass = class extends import_core24._PickLayersPass {
2395
2851
  layers,
2396
2852
  effects: [],
2397
2853
  viewports: [viewport],
2854
+ // Disable the default culling because TileLayer would cull sublayers based on the screen viewport,
2855
+ // not the viewport of the terrain cover. Culling is already done by `terrainCover.filterLayers`
2398
2856
  cullRect: void 0,
2399
2857
  deviceRect: viewport,
2400
2858
  pickZ: false
@@ -2410,6 +2868,13 @@ var TerrainPickingPass = class extends import_core24._PickLayersPass {
2410
2868
  }
2411
2869
  return { ...parameters2, depthTest: false };
2412
2870
  }
2871
+ getShaderModuleProps(layer, effects, otherShaderModuleProps) {
2872
+ return {
2873
+ terrain: {
2874
+ project: otherShaderModuleProps.project
2875
+ }
2876
+ };
2877
+ }
2413
2878
  };
2414
2879
 
2415
2880
  // dist/terrain/height-map-builder.js
@@ -2427,6 +2892,9 @@ var HeightMapBuilder = class {
2427
2892
  this.lastViewport = null;
2428
2893
  this.device = device;
2429
2894
  }
2895
+ /** Returns the height map framebuffer for read/write access.
2896
+ * Returns null when the texture is invalid.
2897
+ */
2430
2898
  getRenderFramebuffer() {
2431
2899
  if (!this.renderViewport) {
2432
2900
  return null;
@@ -2436,8 +2904,17 @@ var HeightMapBuilder = class {
2436
2904
  }
2437
2905
  return this.fbo;
2438
2906
  }
2907
+ /** Called every render cycle to check if the framebuffer needs update */
2439
2908
  shouldUpdate({ layers, viewport }) {
2440
- const layersChanged = layers.length !== this.layers.length || layers.some((layer, i) => layer !== this.layers[i] || layer.props.transitions || layer.getBounds() !== this.layersBounds[i]);
2909
+ const layersChanged = layers.length !== this.layers.length || layers.some((layer, i) => (
2910
+ // Layer instance is updated
2911
+ // Layer props might have changed
2912
+ // Undetermined props could have an effect on the output geometry of a terrain source,
2913
+ // for example getElevation+updateTriggers, elevationScale, modelMatrix
2914
+ layer !== this.layers[i] || // Some prop is in transition
2915
+ layer.props.transitions || // Layer's geometry bounds have changed
2916
+ layer.getBounds() !== this.layersBounds[i]
2917
+ ));
2441
2918
  if (layersChanged) {
2442
2919
  this.layers = layers;
2443
2920
  this.layersBounds = layers.map((layer) => layer.getBounds());
@@ -2458,6 +2935,10 @@ var HeightMapBuilder = class {
2458
2935
  const pixelWidth = (bounds[2] - bounds[0]) * scale;
2459
2936
  const pixelHeight = (bounds[3] - bounds[1]) * scale;
2460
2937
  this.renderViewport = pixelWidth > 0 || pixelHeight > 0 ? makeViewport({
2938
+ // It's not important whether the geometry is visible in this viewport, because
2939
+ // vertices will not use the standard project_to_clipspace in the DRAW_TO_HEIGHT_MAP shader
2940
+ // However the viewport must have the same center and zoom as the screen viewport
2941
+ // So that projection uniforms used for calculating z are the same
2461
2942
  bounds: [
2462
2943
  viewport.center[0] - 1,
2463
2944
  viewport.center[1] - 1,
@@ -2530,16 +3011,20 @@ var TerrainEffect = class {
2530
3011
  const drapeLayers = layers.filter((l) => l.state.terrainDrawMode === "drape");
2531
3012
  this._updateTerrainCovers(terrainLayers, drapeLayers, viewport, opts);
2532
3013
  }
2533
- getModuleParameters(layer) {
3014
+ getShaderModuleProps(layer, otherShaderModuleProps) {
2534
3015
  var _a, _b, _c;
2535
3016
  const { terrainDrawMode } = layer.state;
2536
3017
  return {
2537
- heightMap: ((_b = (_a = this.heightMap) == null ? void 0 : _a.getRenderFramebuffer()) == null ? void 0 : _b.colorAttachments[0].texture) || null,
2538
- heightMapBounds: (_c = this.heightMap) == null ? void 0 : _c.bounds,
2539
- dummyHeightMap: this.dummyHeightMap,
2540
- terrainCover: this.isDrapingEnabled ? this.terrainCovers.get(layer.id) : null,
2541
- useTerrainHeightMap: terrainDrawMode === "offset",
2542
- terrainSkipRender: terrainDrawMode === "drape" || !layer.props.operation.includes("draw")
3018
+ terrain: {
3019
+ project: otherShaderModuleProps.project,
3020
+ isPicking: this.isPicking,
3021
+ heightMap: ((_b = (_a = this.heightMap) == null ? void 0 : _a.getRenderFramebuffer()) == null ? void 0 : _b.colorAttachments[0].texture) || null,
3022
+ heightMapBounds: (_c = this.heightMap) == null ? void 0 : _c.bounds,
3023
+ dummyHeightMap: this.dummyHeightMap,
3024
+ terrainCover: this.isDrapingEnabled ? this.terrainCovers.get(layer.id) : null,
3025
+ useTerrainHeightMap: terrainDrawMode === "offset",
3026
+ terrainSkipRender: terrainDrawMode === "drape" || !layer.props.operation.includes("draw")
3027
+ }
2543
3028
  };
2544
3029
  }
2545
3030
  cleanup({ deck }) {
@@ -2568,11 +3053,15 @@ var TerrainEffect = class {
2568
3053
  this.terrainPass.renderHeightMap(this.heightMap, {
2569
3054
  ...opts,
2570
3055
  layers: terrainLayers,
2571
- moduleParameters: {
2572
- heightMapBounds: this.heightMap.bounds,
2573
- dummyHeightMap: this.dummyHeightMap,
2574
- devicePixelRatio: 1,
2575
- drawToTerrainHeightMap: true
3056
+ shaderModuleProps: {
3057
+ terrain: {
3058
+ heightMapBounds: this.heightMap.bounds,
3059
+ dummyHeightMap: this.dummyHeightMap,
3060
+ drawToTerrainHeightMap: true
3061
+ },
3062
+ project: {
3063
+ devicePixelRatio: 1
3064
+ }
2576
3065
  }
2577
3066
  });
2578
3067
  }
@@ -2611,10 +3100,14 @@ var TerrainEffect = class {
2611
3100
  renderPass.renderTerrainCover(terrainCover, {
2612
3101
  ...opts,
2613
3102
  layers: drapeLayers,
2614
- moduleParameters: {
2615
- dummyHeightMap: this.dummyHeightMap,
2616
- terrainSkipRender: false,
2617
- devicePixelRatio: 1
3103
+ shaderModuleProps: {
3104
+ terrain: {
3105
+ dummyHeightMap: this.dummyHeightMap,
3106
+ terrainSkipRender: false
3107
+ },
3108
+ project: {
3109
+ devicePixelRatio: 1
3110
+ }
2618
3111
  }
2619
3112
  });
2620
3113
  if (!this.isPicking) {
@@ -2655,7 +3148,8 @@ var TerrainExtension = class extends import_core26.LayerExtension {
2655
3148
  updateState(params) {
2656
3149
  var _a;
2657
3150
  const { props, oldProps } = params;
2658
- if (this.state.terrainDrawMode && props.terrainDrawMode === oldProps.terrainDrawMode && props.extruded === oldProps.extruded) {
3151
+ if (this.state.terrainDrawMode && props.terrainDrawMode === oldProps.terrainDrawMode && // @ts-ignore `extruded` may not exist in props
3152
+ props.extruded === oldProps.extruded) {
2659
3153
  return;
2660
3154
  }
2661
3155
  let { terrainDrawMode } = props;