@deck.gl/extensions 9.0.40 → 9.1.0-beta.3

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 (160) 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 +16 -19
  4. package/dist/brushing/brushing-extension.js.map +1 -0
  5. package/dist/brushing/shader-module.d.ts +8 -2
  6. package/dist/brushing/shader-module.d.ts.map +1 -1
  7. package/dist/brushing/shader-module.js +75 -50
  8. package/dist/brushing/shader-module.js.map +1 -0
  9. package/dist/clip/clip-extension.d.ts +5 -2
  10. package/dist/clip/clip-extension.d.ts.map +1 -1
  11. package/dist/clip/clip-extension.js +37 -42
  12. package/dist/clip/clip-extension.js.map +1 -0
  13. package/dist/collision-filter/collision-filter-effect.d.ts +4 -4
  14. package/dist/collision-filter/collision-filter-effect.d.ts.map +1 -1
  15. package/dist/collision-filter/collision-filter-effect.js +28 -13
  16. package/dist/collision-filter/collision-filter-effect.js.map +1 -0
  17. package/dist/collision-filter/collision-filter-extension.d.ts +1 -1
  18. package/dist/collision-filter/collision-filter-extension.d.ts.map +1 -1
  19. package/dist/collision-filter/collision-filter-extension.js +6 -6
  20. package/dist/collision-filter/collision-filter-extension.js.map +1 -0
  21. package/dist/collision-filter/collision-filter-pass.d.ts +9 -5
  22. package/dist/collision-filter/collision-filter-pass.d.ts.map +1 -1
  23. package/dist/collision-filter/collision-filter-pass.js +15 -4
  24. package/dist/collision-filter/collision-filter-pass.js.map +1 -0
  25. package/dist/collision-filter/shader-module.d.ts +3 -2
  26. package/dist/collision-filter/shader-module.d.ts.map +1 -1
  27. package/dist/collision-filter/shader-module.js +75 -52
  28. package/dist/collision-filter/shader-module.js.map +1 -0
  29. package/dist/data-filter/aggregator.d.ts +4 -10
  30. package/dist/data-filter/aggregator.d.ts.map +1 -1
  31. package/dist/data-filter/aggregator.js +15 -8
  32. package/dist/data-filter/aggregator.js.map +1 -0
  33. package/dist/data-filter/data-filter-extension.d.ts.map +1 -1
  34. package/dist/data-filter/data-filter-extension.js +49 -39
  35. package/dist/data-filter/data-filter-extension.js.map +1 -0
  36. package/dist/data-filter/shader-module.d.ts +12 -5
  37. package/dist/data-filter/shader-module.d.ts.map +1 -1
  38. package/dist/data-filter/shader-module.js +190 -131
  39. package/dist/data-filter/shader-module.js.map +1 -0
  40. package/dist/dist.dev.js +2720 -2037
  41. package/dist/fill-style/fill-style-extension.d.ts.map +1 -1
  42. package/dist/fill-style/fill-style-extension.js +12 -4
  43. package/dist/fill-style/fill-style-extension.js.map +1 -0
  44. package/dist/fill-style/shader-module.d.ts +64 -6
  45. package/dist/fill-style/shader-module.d.ts.map +1 -1
  46. package/dist/fill-style/shader-module.js +74 -51
  47. package/dist/fill-style/shader-module.js.map +1 -0
  48. package/dist/fp64/fp64-extension.d.ts +1 -0
  49. package/dist/fp64/fp64-extension.d.ts.map +1 -1
  50. package/dist/fp64/fp64-extension.js +8 -19
  51. package/dist/fp64/fp64-extension.js.map +1 -0
  52. package/dist/fp64/project64.d.ts +2 -2
  53. package/dist/fp64/project64.d.ts.map +1 -1
  54. package/dist/fp64/project64.glsl.d.ts +1 -1
  55. package/dist/fp64/project64.glsl.d.ts.map +1 -1
  56. package/dist/fp64/project64.glsl.js +19 -21
  57. package/dist/fp64/project64.glsl.js.map +1 -0
  58. package/dist/fp64/project64.js +25 -24
  59. package/dist/fp64/project64.js.map +1 -0
  60. package/dist/index.cjs +1034 -528
  61. package/dist/index.cjs.map +4 -4
  62. package/dist/index.d.ts +1 -0
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +4 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/mask/mask-effect.d.ts +5 -3
  67. package/dist/mask/mask-effect.d.ts.map +1 -1
  68. package/dist/mask/mask-effect.js +13 -5
  69. package/dist/mask/mask-effect.js.map +1 -0
  70. package/dist/mask/mask-extension.d.ts +1 -1
  71. package/dist/mask/mask-extension.d.ts.map +1 -1
  72. package/dist/mask/mask-extension.js +14 -8
  73. package/dist/mask/mask-extension.js.map +1 -0
  74. package/dist/mask/mask-pass.d.ts +2 -43
  75. package/dist/mask/mask-pass.d.ts.map +1 -1
  76. package/dist/mask/mask-pass.js +5 -1
  77. package/dist/mask/mask-pass.js.map +1 -0
  78. package/dist/mask/shader-module.d.ts +60 -3
  79. package/dist/mask/shader-module.d.ts.map +1 -1
  80. package/dist/mask/shader-module.js +74 -46
  81. package/dist/mask/shader-module.js.map +1 -0
  82. package/dist/path-style/path-style-extension.d.ts.map +1 -1
  83. package/dist/path-style/path-style-extension.js +21 -24
  84. package/dist/path-style/path-style-extension.js.map +1 -0
  85. package/dist/path-style/shaders.glsl.d.ts.map +1 -1
  86. package/dist/path-style/shaders.glsl.js +12 -7
  87. package/dist/path-style/shaders.glsl.js.map +1 -0
  88. package/dist/terrain/height-map-builder.d.ts.map +1 -1
  89. package/dist/terrain/height-map-builder.js +4 -0
  90. package/dist/terrain/height-map-builder.js.map +1 -0
  91. package/dist/terrain/shader-module.d.ts +60 -6
  92. package/dist/terrain/shader-module.d.ts.map +1 -1
  93. package/dist/terrain/shader-module.js +70 -61
  94. package/dist/terrain/shader-module.js.map +1 -0
  95. package/dist/terrain/terrain-cover.d.ts.map +1 -1
  96. package/dist/terrain/terrain-cover.js +4 -0
  97. package/dist/terrain/terrain-cover.js.map +1 -0
  98. package/dist/terrain/terrain-effect.d.ts +4 -2
  99. package/dist/terrain/terrain-effect.d.ts.map +1 -1
  100. package/dist/terrain/terrain-effect.js +32 -18
  101. package/dist/terrain/terrain-effect.js.map +1 -0
  102. package/dist/terrain/terrain-extension.d.ts.map +1 -1
  103. package/dist/terrain/terrain-extension.js +4 -0
  104. package/dist/terrain/terrain-extension.js.map +1 -0
  105. package/dist/terrain/terrain-pass.d.ts +6 -41
  106. package/dist/terrain/terrain-pass.d.ts.map +1 -1
  107. package/dist/terrain/terrain-pass.js +12 -1
  108. package/dist/terrain/terrain-pass.js.map +1 -0
  109. package/dist/terrain/terrain-picking-pass.d.ts +7 -1
  110. package/dist/terrain/terrain-picking-pass.d.ts.map +1 -1
  111. package/dist/terrain/terrain-picking-pass.js +12 -1
  112. package/dist/terrain/terrain-picking-pass.js.map +1 -0
  113. package/dist/terrain/utils.d.ts.map +1 -1
  114. package/dist/terrain/utils.js +4 -0
  115. package/dist/terrain/utils.js.map +1 -0
  116. package/dist/utils/debug.d.ts +2 -2
  117. package/dist/utils/debug.d.ts.map +1 -1
  118. package/dist/utils/debug.js +4 -1
  119. package/dist/utils/debug.js.map +1 -0
  120. package/dist/utils/projection-utils.d.ts.map +1 -1
  121. package/dist/utils/projection-utils.js +4 -0
  122. package/dist/utils/projection-utils.js.map +1 -0
  123. package/dist.min.js +1102 -817
  124. package/package.json +8 -8
  125. package/src/brushing/brushing-extension.ts +17 -20
  126. package/src/brushing/shader-module.ts +58 -47
  127. package/src/clip/clip-extension.ts +38 -40
  128. package/src/collision-filter/collision-filter-effect.ts +31 -20
  129. package/src/collision-filter/collision-filter-extension.ts +6 -7
  130. package/src/collision-filter/collision-filter-pass.ts +17 -6
  131. package/src/collision-filter/shader-module.ts +40 -22
  132. package/src/data-filter/aggregator.ts +23 -11
  133. package/src/data-filter/data-filter-extension.ts +76 -49
  134. package/src/data-filter/shader-module.ts +150 -90
  135. package/src/fill-style/fill-style-extension.ts +13 -5
  136. package/src/fill-style/shader-module.ts +84 -52
  137. package/src/fp64/fp64-extension.ts +8 -19
  138. package/src/fp64/project64.glsl.ts +18 -21
  139. package/src/fp64/project64.ts +27 -28
  140. package/src/index.ts +5 -0
  141. package/src/mask/mask-effect.ts +17 -7
  142. package/src/mask/mask-extension.ts +16 -9
  143. package/src/mask/mask-pass.ts +17 -3
  144. package/src/mask/shader-module.ts +63 -27
  145. package/src/path-style/path-style-extension.ts +27 -28
  146. package/src/path-style/shaders.glsl.ts +13 -7
  147. package/src/terrain/height-map-builder.ts +4 -0
  148. package/src/terrain/shader-module.ts +62 -44
  149. package/src/terrain/terrain-cover.ts +4 -0
  150. package/src/terrain/terrain-effect.ts +36 -19
  151. package/src/terrain/terrain-extension.ts +4 -0
  152. package/src/terrain/terrain-pass.ts +19 -3
  153. package/src/terrain/terrain-picking-pass.ts +15 -2
  154. package/src/terrain/utils.ts +4 -0
  155. package/src/utils/debug.ts +4 -0
  156. package/src/utils/projection-utils.ts +4 -0
  157. package/dist/utils/syntax-tags.d.ts +0 -6
  158. package/dist/utils/syntax-tags.d.ts.map +0 -1
  159. package/dist/utils/syntax-tags.js +0 -5
  160. 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;
181
228
  #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;
229
+ DATAFILTER_TYPE min;
230
+ DATAFILTER_TYPE softMin;
231
+ DATAFILTER_TYPE softMax;
232
+ DATAFILTER_TYPE max;
187
233
  #ifdef DATAFILTER_DOUBLE
188
- in DATAFILTER_TYPE filterValues64Low;
189
- uniform DATAFILTER_TYPE filter_min64High;
190
- uniform DATAFILTER_TYPE filter_max64High;
234
+ DATAFILTER_TYPE min64High;
235
+ DATAFILTER_TYPE max64High;
191
236
  #endif
192
237
  #endif
193
238
  #ifdef DATACATEGORY_TYPE
194
- in DATACATEGORY_TYPE filterCategoryValues;
239
+ highp uvec4 categoryBitMask;
195
240
  #endif
241
+ } dataFilter;
242
+ `
243
+ );
244
+ var vertex2 = (
245
+ /* glsl */
246
+ `
247
+ #ifdef DATAFILTER_TYPE
248
+ in DATAFILTER_TYPE filterValues;
249
+ #ifdef DATAFILTER_DOUBLE
250
+ in DATAFILTER_TYPE filterValues64Low;
251
+ #endif
252
+ #endif
253
+
254
+ #ifdef DATACATEGORY_TYPE
255
+ in DATACATEGORY_TYPE filterCategoryValues;
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
+ uint dataFilter_masks = dataFilter.categoryBitMask[category / 32u];
301
+ #elif DATACATEGORY_CHANNELS == 2 // Two 64-bit masks
302
+ uvec2 dataFilter_masks = uvec2(
303
+ dataFilter.categoryBitMask[category.x / 32u],
304
+ dataFilter.categoryBitMask[category.y / 32u + 2u]
305
+ );
306
+ #elif DATACATEGORY_CHANNELS == 3 // Three 32-bit masks
307
+ uvec3 dataFilter_masks = dataFilter.categoryBitMask.xyz;
308
+ #else // Four 32-bit masks
309
+ uvec4 dataFilter_masks = dataFilter.categoryBitMask;
310
+ #endif
311
+
312
+ // Shift mask and extract relevant bits
313
+ DATACATEGORY_TYPE dataFilter_bits = DATACATEGORY_TYPE(dataFilter_masks) >> (category & 31u);
314
+ dataFilter_bits &= 1u;
315
+
316
+ #if DATACATEGORY_CHANNELS == 1
317
+ if(dataFilter_bits == 0u) dataFilter_value = 0.0;
318
+ #else
319
+ if(any(equal(dataFilter_bits, DATACATEGORY_TYPE(0u)))) 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
@@ -473,6 +599,12 @@ var defaultOptions = {
473
599
  fp64: false,
474
600
  countItems: false
475
601
  };
602
+ var CATEGORY_TYPE_FROM_SIZE = {
603
+ 1: "uint",
604
+ 2: "uvec2",
605
+ 3: "uvec3",
606
+ 4: "uvec4"
607
+ };
476
608
  var DATA_TYPE_FROM_SIZE = {
477
609
  1: "float",
478
610
  2: "vec2",
@@ -487,14 +619,16 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
487
619
  const { categorySize, filterSize, fp64: fp642 } = extension.opts;
488
620
  const defines = {};
489
621
  if (categorySize) {
490
- defines.DATACATEGORY_TYPE = DATA_TYPE_FROM_SIZE[categorySize];
622
+ defines.DATACATEGORY_TYPE = CATEGORY_TYPE_FROM_SIZE[categorySize];
491
623
  defines.DATACATEGORY_CHANNELS = categorySize;
492
624
  }
493
625
  if (filterSize) {
494
626
  defines.DATAFILTER_TYPE = DATA_TYPE_FROM_SIZE[filterSize];
495
627
  defines.DATAFILTER_DOUBLE = Boolean(fp642);
496
628
  }
497
- return { modules: [fp642 ? shaderModule64 : shaderModule], defines };
629
+ const module2 = fp642 ? dataFilter64 : dataFilter;
630
+ module2.uniformTypes = module2.uniformTypesFromOptions(extension.opts);
631
+ return { modules: [module2], defines };
498
632
  }
499
633
  initializeState(context, extension) {
500
634
  const attributeManager = this.getAttributeManager();
@@ -516,6 +650,7 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
516
650
  size: categorySize,
517
651
  stepMode: "dynamic",
518
652
  accessor: "getFilterCategory",
653
+ type: "uint32",
519
654
  transform: categorySize === 1 ? (d) => extension._getCategoryKey.call(this, d, 0) : (d) => d.map((x, i) => extension._getCategoryKey.call(this, x, i))
520
655
  }
521
656
  });
@@ -525,7 +660,7 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
525
660
  if (attributeManager && extension.opts.countItems) {
526
661
  const useFloatTarget = supportsFloatTarget(device);
527
662
  attributeManager.add({
528
- filterIndices: {
663
+ filterVertexIndices: {
529
664
  size: useFloatTarget ? 1 : 2,
530
665
  vertexOffset: 1,
531
666
  type: "unorm8",
@@ -544,7 +679,7 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
544
679
  }
545
680
  });
546
681
  const filterFBO = getFramebuffer(device, useFloatTarget);
547
- const filterModel = getModel(device, extension.getShaders.call(this, extension), useFloatTarget);
682
+ const filterModel = getModel(device, attributeManager.getBufferLayouts({ isInstanced: false }), extension.getShaders.call(this, extension), useFloatTarget);
548
683
  this.setState({ filterFBO, filterModel });
549
684
  }
550
685
  }
@@ -553,7 +688,10 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
553
688
  const attributeManager = this.getAttributeManager();
554
689
  const { categorySize } = extension.opts;
555
690
  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;
691
+ const filterNeedsUpdate = (
692
+ // attributeManager must be defined for filterModel to be set
693
+ ((_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
694
+ );
557
695
  if (filterNeedsUpdate) {
558
696
  this.setState({ filterNeedsUpdate });
559
697
  }
@@ -576,29 +714,46 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
576
714
  const filterFBO = this.state.filterFBO;
577
715
  const filterModel = this.state.filterModel;
578
716
  const filterNeedsUpdate = this.state.filterNeedsUpdate;
579
- const { onFilteredItemsChange } = this.props;
580
717
  if (!this.state.categoryBitMask) {
581
718
  extension._updateCategoryBitMask.call(this, params, extension);
582
719
  }
583
- params.uniforms.filter_categoryBitMask = this.state.categoryBitMask;
720
+ const { onFilteredItemsChange, extensions, filterEnabled, filterRange, filterSoftRange, filterTransformSize, filterTransformColor, filterCategories } = this.props;
721
+ const dataFilterProps = {
722
+ extensions,
723
+ filterEnabled,
724
+ filterRange,
725
+ filterSoftRange,
726
+ filterTransformSize,
727
+ filterTransformColor,
728
+ filterCategories
729
+ };
730
+ if (this.state.categoryBitMask) {
731
+ dataFilterProps.categoryBitMask = this.state.categoryBitMask;
732
+ }
733
+ this.setShaderModuleProps({ dataFilter: dataFilterProps });
584
734
  if (filterNeedsUpdate && onFilteredItemsChange && filterModel) {
585
- const { attributes: { filterValues, filterCategoryValues, filterIndices } } = this.getAttributeManager();
735
+ const attributeManager = this.getAttributeManager();
736
+ const { attributes: { filterValues, filterCategoryValues, filterVertexIndices } } = attributeManager;
586
737
  filterModel.setVertexCount(this.getNumInstances());
587
- this.context.device.clearWebGL({ framebuffer: filterFBO, color: [0, 0, 0, 0] });
588
- filterModel.updateModuleSettings(params.moduleParameters);
589
- filterModel.setAttributes({
738
+ const attributes = {
590
739
  ...filterValues == null ? void 0 : filterValues.getValue(),
591
740
  ...filterCategoryValues == null ? void 0 : filterCategoryValues.getValue(),
592
- ...filterIndices == null ? void 0 : filterIndices.getValue()
741
+ ...filterVertexIndices == null ? void 0 : filterVertexIndices.getValue()
742
+ };
743
+ filterModel.setAttributes(attributes);
744
+ filterModel.shaderInputs.setProps({
745
+ dataFilter: dataFilterProps
593
746
  });
594
- filterModel.setUniforms(params.uniforms);
595
- filterModel.device.withParametersWebGL({
747
+ const viewport = [0, 0, filterFBO.width, filterFBO.height];
748
+ const renderPass = filterModel.device.beginRenderPass({
749
+ id: "data-filter-aggregation",
596
750
  framebuffer: filterFBO,
597
- ...parameters,
598
- viewport: [0, 0, filterFBO.width, filterFBO.height]
599
- }, () => {
600
- filterModel.draw(this.context.renderPass);
751
+ parameters: { viewport },
752
+ clearColor: [0, 0, 0, 0]
601
753
  });
754
+ filterModel.setParameters(parameters);
755
+ filterModel.draw(renderPass);
756
+ renderPass.end();
602
757
  const color = filterModel.device.readPixelsToArrayWebGL(filterFBO);
603
758
  let count = 0;
604
759
  for (let i = 0; i < color.length; i++) {
@@ -614,6 +769,11 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
614
769
  filterFBO == null ? void 0 : filterFBO.destroy();
615
770
  filterModel == null ? void 0 : filterModel.destroy();
616
771
  }
772
+ /**
773
+ * Updates the bitmask used on the GPU to perform the filter based on the
774
+ * `filterCategories` prop. The mapping between categories and bit in the bitmask
775
+ * is performed by `_getCategoryKey()`
776
+ */
617
777
  _updateCategoryBitMask(params, extension) {
618
778
  const { categorySize } = extension.opts;
619
779
  if (!categorySize)
@@ -636,6 +796,10 @@ var DataFilterExtension = class extends import_core3.LayerExtension {
636
796
  }
637
797
  this.state.categoryBitMask = categoryBitMask;
638
798
  }
799
+ /**
800
+ * Returns an index of bit in the bitmask for a given category. If the category has
801
+ * not yet been assigned a bit, a new one is assigned.
802
+ */
639
803
  _getCategoryKey(category, channel) {
640
804
  const categoryMap = this.state.categoryMap[channel];
641
805
  if (!(category in categoryMap)) {
@@ -657,7 +821,11 @@ var import_core4 = require("@deck.gl/core");
657
821
 
658
822
  // dist/fp64/project64.glsl.js
659
823
  var project64_glsl_default = `const vec2 WORLD_SCALE_FP64 = vec2(81.4873275756836, 0.0000032873668232014097);
660
- uniform vec2 project_uViewProjectionMatrixFP64[16];
824
+ uniform project64Uniforms {
825
+ vec2 scale;
826
+ mat4 viewProjectionMatrix;
827
+ mat4 viewProjectionMatrix64Low;
828
+ } project64;
661
829
  void mercatorProject_fp64(vec4 lnglat_fp64, out vec2 out_val[2]) {
662
830
  #if defined(NVIDIA_FP64_WORKAROUND)
663
831
  out_val[0] = sum_fp64(radians_fp64(lnglat_fp64.xy), PI_FP64 * ONE);
@@ -683,7 +851,16 @@ project_position_fp64(position64xy, out_val);
683
851
  }
684
852
  vec4 project_common_position_to_clipspace_fp64(vec2 vertex_pos_modelspace[4]) {
685
853
  vec2 vertex_pos_clipspace[4];
686
- mat4_vec4_mul_fp64(project_uViewProjectionMatrixFP64, vertex_pos_modelspace,
854
+ vec2 viewProjectionMatrixFP64[16];
855
+ for (int i = 0; i < 4; i++) {
856
+ for (int j = 0; j < 4; j++) {
857
+ viewProjectionMatrixFP64[4 * i + j] = vec2(
858
+ project64.viewProjectionMatrix[j][i],
859
+ project64.viewProjectionMatrix64Low[j][i]
860
+ );
861
+ }
862
+ }
863
+ mat4_vec4_mul_fp64(viewProjectionMatrixFP64, vertex_pos_modelspace,
687
864
  vertex_pos_clipspace);
688
865
  return vec4(
689
866
  vertex_pos_clipspace[0].x,
@@ -724,7 +901,13 @@ var project64_default = {
724
901
  name: "project64",
725
902
  dependencies: [import_core4.project, import_shadertools.fp64],
726
903
  vs: project64_glsl_default,
727
- getUniforms: getUniforms2
904
+ getUniforms: getUniforms2,
905
+ uniformTypes: {
906
+ scale: "vec2<f32>",
907
+ // Cannot pass as vec2[16], so instead split into 2 mat4x4
908
+ viewProjectionMatrix: "mat4x4<f32>",
909
+ viewProjectionMatrix64Low: "mat4x4<f32>"
910
+ }
728
911
  };
729
912
  var getMemoizedUniforms = (0, import_core4._memoize)(calculateUniforms);
730
913
  function getUniforms2(opts) {
@@ -736,11 +919,20 @@ function getUniforms2(opts) {
736
919
  }
737
920
  function calculateUniforms({ viewProjectionMatrix, scale }) {
738
921
  const glViewProjectionMatrixFP64 = fp64ifyMatrix4(viewProjectionMatrix);
739
- const scaleFP64 = fp64ify(scale);
922
+ const viewProjectionMatrix64High = new Float32Array(16);
923
+ const viewProjectionMatrix64Low = new Float32Array(16);
924
+ for (let i = 0; i < 4; i++) {
925
+ for (let j = 0; j < 4; j++) {
926
+ const from = 4 * i + j;
927
+ const to = 4 * j + i;
928
+ viewProjectionMatrix64High[to] = glViewProjectionMatrixFP64[2 * from];
929
+ viewProjectionMatrix64Low[to] = glViewProjectionMatrixFP64[2 * from + 1];
930
+ }
931
+ }
740
932
  return {
741
- project_uViewProjectionMatrixFP64: glViewProjectionMatrixFP64,
742
- project64_uViewProjectionMatrix: glViewProjectionMatrixFP64,
743
- project64_uScale: scaleFP64
933
+ scale: fp64ify(scale),
934
+ viewProjectionMatrix: [...viewProjectionMatrix64High],
935
+ viewProjectionMatrix64Low: [...viewProjectionMatrix64Low]
744
936
  };
745
937
  }
746
938
 
@@ -755,6 +947,10 @@ var Fp64Extension = class extends import_core5.LayerExtension {
755
947
  modules: [project64_default]
756
948
  };
757
949
  }
950
+ draw(params, extension) {
951
+ const { viewport } = params.context;
952
+ this.setShaderModuleProps({ project64: { viewport } });
953
+ }
758
954
  };
759
955
  Fp64Extension.extensionName = "Fp64Extension";
760
956
  var fp64_extension_default = Fp64Extension;
@@ -777,19 +973,28 @@ vDashArray = instanceDashArrays;
777
973
  vDashOffset = instanceDashOffsets / width.x;
778
974
  `,
779
975
  "fs:#decl": `
780
- uniform float dashAlignMode;
781
- uniform float capType;
782
- uniform bool dashGapPickable;
976
+ uniform pathStyleUniforms {
977
+ float dashAlignMode;
978
+ bool dashGapPickable;
979
+ } pathStyle;
783
980
  in vec2 vDashArray;
784
981
  in float vDashOffset;
785
982
  `,
983
+ // if given position is in the gap part of the dashed line
984
+ // dashArray.x: solid stroke length, relative to width
985
+ // dashArray.y: gap length, relative to width
986
+ // alignMode:
987
+ // 0 - no adjustment
988
+ // o---- ---- ---- ---- o---- -o---- ---- o
989
+ // 1 - stretch to fit, draw half dash at each end for nicer joints
990
+ // o-- ---- ---- ---- --o-- --o-- ---- --o
786
991
  "fs:#main-start": `
787
992
  float solidLength = vDashArray.x;
788
993
  float gapLength = vDashArray.y;
789
994
  float unitLength = solidLength + gapLength;
790
995
  float offset;
791
996
  if (unitLength > 0.0) {
792
- if (dashAlignMode == 0.0) {
997
+ if (pathStyle.dashAlignMode == 0.0) {
793
998
  offset = vDashOffset;
794
999
  } else {
795
1000
  unitLength = vPathLength / round(vPathLength / unitLength);
@@ -797,8 +1002,8 @@ offset = solidLength / 2.0;
797
1002
  }
798
1003
  float unitOffset = mod(vPathPosition.y + offset, unitLength);
799
1004
  if (gapLength > 0.0 && unitOffset > solidLength) {
800
- if (capType <= 0.5) {
801
- if (!(dashGapPickable && bool(picking.isActive))) {
1005
+ if (path.capType <= 0.5) {
1006
+ if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
802
1007
  discard;
803
1008
  }
804
1009
  } else {
@@ -807,7 +1012,7 @@ min(unitOffset - solidLength, unitLength - unitOffset),
807
1012
  vPathPosition.x
808
1013
  ));
809
1014
  if (distToEnd > 1.0) {
810
- if (!(dashGapPickable && bool(picking.isActive))) {
1015
+ if (!(pathStyle.dashGapPickable && bool(picking.isActive))) {
811
1016
  discard;
812
1017
  }
813
1018
  }
@@ -868,7 +1073,18 @@ var PathStyleExtension = class extends import_core6.LayerExtension {
868
1073
  if (extension.opts.offset) {
869
1074
  result = (0, import_core6._mergeShaders)(result, offsetShaders);
870
1075
  }
871
- return result;
1076
+ const { inject: inject6 } = result;
1077
+ const pathStyle = {
1078
+ name: "pathStyle",
1079
+ inject: inject6,
1080
+ uniformTypes: {
1081
+ dashAlignMode: "f32",
1082
+ dashGapPickable: "i32"
1083
+ }
1084
+ };
1085
+ return {
1086
+ modules: [pathStyle]
1087
+ };
872
1088
  }
873
1089
  initializeState(context, extension) {
874
1090
  const attributeManager = this.getAttributeManager();
@@ -898,16 +1114,16 @@ var PathStyleExtension = class extends import_core6.LayerExtension {
898
1114
  }
899
1115
  }
900
1116
  updateState(params, extension) {
901
- var _a;
902
1117
  if (!extension.isEnabled(this)) {
903
1118
  return;
904
1119
  }
905
- const uniforms = {};
906
1120
  if (extension.opts.dash) {
907
- uniforms.dashAlignMode = this.props.dashJustified ? 1 : 0;
908
- uniforms.dashGapPickable = Boolean(this.props.dashGapPickable);
1121
+ const pathStyleProps = {
1122
+ dashAlignMode: this.props.dashJustified ? 1 : 0,
1123
+ dashGapPickable: Boolean(this.props.dashGapPickable)
1124
+ };
1125
+ this.setShaderModuleProps({ pathStyle: pathStyleProps });
909
1126
  }
910
- (_a = this.state.model) == null ? void 0 : _a.setUniforms(uniforms);
911
1127
  }
912
1128
  getDashOffsets(path) {
913
1129
  const result = [0];
@@ -937,86 +1153,124 @@ var import_core9 = require("@deck.gl/core");
937
1153
 
938
1154
  // dist/fill-style/shader-module.js
939
1155
  var import_core8 = require("@deck.gl/core");
940
- var patternVs = `
1156
+ var uniformBlock3 = (
1157
+ /* glsl */
1158
+ `uniform fillUniforms {
1159
+ vec2 patternTextureSize;
1160
+ bool patternEnabled;
1161
+ bool patternMask;
1162
+ vec2 uvCoordinateOrigin;
1163
+ vec2 uvCoordinateOrigin64Low;
1164
+ } fill;
1165
+ `
1166
+ );
1167
+ var patternVs = (
1168
+ /* glsl */
1169
+ `
941
1170
  in vec4 fillPatternFrames;
942
1171
  in float fillPatternScales;
943
1172
  in vec2 fillPatternOffsets;
944
- uniform bool fill_patternEnabled;
945
- uniform vec2 fill_patternTextureSize;
1173
+
946
1174
  out vec2 fill_uv;
947
1175
  out vec4 fill_patternBounds;
948
1176
  out vec4 fill_patternPlacement;
1177
+ `
1178
+ );
1179
+ var vs3 = `
1180
+ ${uniformBlock3}
1181
+ ${patternVs}
949
1182
  `;
950
- var patternFs = `
951
- uniform bool fill_patternEnabled;
952
- uniform bool fill_patternMask;
1183
+ var patternFs = (
1184
+ /* glsl */
1185
+ `
953
1186
  uniform sampler2D fill_patternTexture;
954
- uniform vec2 fill_uvCoordinateOrigin;
955
- uniform vec2 fill_uvCoordinateOrigin64Low;
1187
+
956
1188
  in vec4 fill_patternBounds;
957
1189
  in vec4 fill_patternPlacement;
958
1190
  in vec2 fill_uv;
1191
+
959
1192
  const float FILL_UV_SCALE = 512.0 / 40000000.0;
1193
+ `
1194
+ );
1195
+ var fs3 = `
1196
+ ${uniformBlock3}
1197
+ ${patternFs}
960
1198
  `;
961
1199
  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
- `
1200
+ "vs:DECKGL_FILTER_GL_POSITION": (
1201
+ /* glsl */
1202
+ `
1203
+ fill_uv = geometry.position.xy;
1204
+ `
1205
+ ),
1206
+ "vs:DECKGL_FILTER_COLOR": (
1207
+ /* glsl */
1208
+ `
1209
+ if (fill.patternEnabled) {
1210
+ fill_patternBounds = fillPatternFrames / vec4(fill.patternTextureSize, fill.patternTextureSize);
1211
+ fill_patternPlacement.xy = fillPatternOffsets;
1212
+ fill_patternPlacement.zw = fillPatternScales * fillPatternFrames.zw;
1213
+ }
1214
+ `
1215
+ ),
1216
+ "fs:DECKGL_FILTER_COLOR": (
1217
+ /* glsl */
1218
+ `
1219
+ if (fill.patternEnabled) {
1220
+ vec2 scale = FILL_UV_SCALE * fill_patternPlacement.zw;
1221
+ vec2 patternUV = mod(mod(fill.uvCoordinateOrigin, scale) + fill.uvCoordinateOrigin64Low + fill_uv, scale) / scale;
1222
+ patternUV = mod(fill_patternPlacement.xy + patternUV, 1.0);
1223
+
1224
+ vec2 texCoords = fill_patternBounds.xy + fill_patternBounds.zw * patternUV;
1225
+
1226
+ vec4 patternColor = texture(fill_patternTexture, texCoords);
1227
+ color.a *= patternColor.a;
1228
+ if (!fill.patternMask) {
1229
+ color.rgb = patternColor.rgb;
1230
+ }
1231
+ }
1232
+ `
1233
+ )
985
1234
  };
986
- function getPatternUniforms(opts, uniforms) {
1235
+ function getPatternUniforms(opts) {
987
1236
  if (!opts) {
988
1237
  return {};
989
1238
  }
1239
+ const uniforms = {};
990
1240
  if ("fillPatternTexture" in opts) {
991
1241
  const { fillPatternTexture } = opts;
992
- return {
993
- fill_patternTexture: fillPatternTexture,
994
- fill_patternTextureSize: [fillPatternTexture.width, fillPatternTexture.height]
995
- };
1242
+ uniforms.fill_patternTexture = fillPatternTexture;
1243
+ uniforms.patternTextureSize = [fillPatternTexture.width, fillPatternTexture.height];
996
1244
  }
997
- if ("viewport" in opts) {
1245
+ if ("project" in opts) {
998
1246
  const { fillPatternMask = true, fillPatternEnabled = true } = opts;
999
- const { project_uCommonOrigin: coordinateOriginCommon } = uniforms;
1247
+ const projectUniforms = import_core8.project.getUniforms(opts.project);
1248
+ const { commonOrigin: coordinateOriginCommon } = projectUniforms;
1000
1249
  const coordinateOriginCommon64Low = [
1001
1250
  (0, import_core8.fp64LowPart)(coordinateOriginCommon[0]),
1002
1251
  (0, import_core8.fp64LowPart)(coordinateOriginCommon[1])
1003
1252
  ];
1004
- return {
1005
- fill_uvCoordinateOrigin: coordinateOriginCommon.slice(0, 2),
1006
- fill_uvCoordinateOrigin64Low: coordinateOriginCommon64Low,
1007
- fill_patternMask: fillPatternMask,
1008
- fill_patternEnabled: fillPatternEnabled
1009
- };
1253
+ uniforms.uvCoordinateOrigin = coordinateOriginCommon.slice(0, 2);
1254
+ uniforms.uvCoordinateOrigin64Low = coordinateOriginCommon64Low;
1255
+ uniforms.patternMask = fillPatternMask;
1256
+ uniforms.patternEnabled = fillPatternEnabled;
1010
1257
  }
1011
- return {};
1258
+ return uniforms;
1012
1259
  }
1013
1260
  var patternShaders = {
1014
- name: "fill-pattern",
1015
- vs: patternVs,
1016
- fs: patternFs,
1261
+ name: "fill",
1262
+ vs: vs3,
1263
+ fs: fs3,
1017
1264
  inject: inject3,
1018
1265
  dependencies: [import_core8.project],
1019
- getUniforms: getPatternUniforms
1266
+ getUniforms: getPatternUniforms,
1267
+ uniformTypes: {
1268
+ patternTextureSize: "vec2<f32>",
1269
+ patternEnabled: "i32",
1270
+ patternMask: "i32",
1271
+ uvCoordinateOrigin: "vec2<f32>",
1272
+ uvCoordinateOrigin64Low: "vec2<f32>"
1273
+ }
1020
1274
  };
1021
1275
 
1022
1276
  // dist/fill-style/fill-style-extension.js
@@ -1095,10 +1349,14 @@ var FillStyleExtension = class extends import_core9.LayerExtension {
1095
1349
  if (!extension.isEnabled(this)) {
1096
1350
  return;
1097
1351
  }
1098
- const { fillPatternAtlas } = this.props;
1099
- this.setModuleParameters({
1352
+ const { fillPatternAtlas, fillPatternEnabled, fillPatternMask } = this.props;
1353
+ const fillProps = {
1354
+ project: params.shaderModuleProps.project,
1355
+ fillPatternEnabled,
1356
+ fillPatternMask,
1100
1357
  fillPatternTexture: fillPatternAtlas || this.state.emptyTexture
1101
- });
1358
+ };
1359
+ this.setShaderModuleProps({ fill: fillProps });
1102
1360
  }
1103
1361
  finalizeState() {
1104
1362
  const emptyTexture = this.state.emptyTexture;
@@ -1120,47 +1378,83 @@ var defaultProps5 = {
1120
1378
  clipBounds: [0, 0, 1, 1],
1121
1379
  clipByInstance: void 0
1122
1380
  };
1123
- var shaderFunction = `
1124
- uniform vec4 clip_bounds;
1381
+ var shaderFunction = (
1382
+ /* glsl */
1383
+ `
1384
+ uniform clipUniforms {
1385
+ vec4 bounds;
1386
+ } clip;
1387
+
1125
1388
  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];
1389
+ return position.x >= clip.bounds[0] && position.y >= clip.bounds[1] && position.x < clip.bounds[2] && position.y < clip.bounds[3];
1127
1390
  }
1128
- `;
1391
+ `
1392
+ );
1129
1393
  var shaderModuleVs = {
1130
- name: "clip-vs",
1131
- vs: shaderFunction
1394
+ name: "clip",
1395
+ vs: shaderFunction,
1396
+ uniformTypes: {
1397
+ bounds: "vec4<f32>"
1398
+ }
1132
1399
  };
1133
1400
  var injectionVs = {
1134
- "vs:#decl": `
1401
+ "vs:#decl": (
1402
+ /* glsl */
1403
+ `
1135
1404
  out float clip_isVisible;
1136
- `,
1137
- "vs:DECKGL_FILTER_GL_POSITION": `
1138
- clip_isVisible = float(clip_isInBounds(geometry.worldPosition.xy));
1139
- `,
1140
- "fs:#decl": `
1405
+ `
1406
+ ),
1407
+ "vs:DECKGL_FILTER_GL_POSITION": (
1408
+ /* glsl */
1409
+ `
1410
+ clip_isVisible = float(clip_isInBounds(geometry.worldPosition.xy));
1411
+ `
1412
+ ),
1413
+ "fs:#decl": (
1414
+ /* glsl */
1415
+ `
1141
1416
  in float clip_isVisible;
1142
- `,
1143
- "fs:DECKGL_FILTER_COLOR": `
1144
- if (clip_isVisible < 0.5) discard;
1145
1417
  `
1418
+ ),
1419
+ "fs:DECKGL_FILTER_COLOR": (
1420
+ /* glsl */
1421
+ `
1422
+ if (clip_isVisible < 0.5) discard;
1423
+ `
1424
+ )
1146
1425
  };
1147
1426
  var shaderModuleFs = {
1148
- name: "clip-fs",
1149
- fs: shaderFunction
1427
+ name: "clip",
1428
+ fs: shaderFunction,
1429
+ uniformTypes: {
1430
+ bounds: "vec4<f32>"
1431
+ }
1150
1432
  };
1151
1433
  var injectionFs = {
1152
- "vs:#decl": `
1434
+ "vs:#decl": (
1435
+ /* glsl */
1436
+ `
1153
1437
  out vec2 clip_commonPosition;
1154
- `,
1155
- "vs:DECKGL_FILTER_GL_POSITION": `
1156
- clip_commonPosition = geometry.position.xy;
1157
- `,
1158
- "fs:#decl": `
1438
+ `
1439
+ ),
1440
+ "vs:DECKGL_FILTER_GL_POSITION": (
1441
+ /* glsl */
1442
+ `
1443
+ clip_commonPosition = geometry.position.xy;
1444
+ `
1445
+ ),
1446
+ "fs:#decl": (
1447
+ /* glsl */
1448
+ `
1159
1449
  in vec2 clip_commonPosition;
1160
- `,
1161
- "fs:DECKGL_FILTER_COLOR": `
1162
- if (!clip_isInBounds(clip_commonPosition)) discard;
1163
1450
  `
1451
+ ),
1452
+ "fs:DECKGL_FILTER_COLOR": (
1453
+ /* glsl */
1454
+ `
1455
+ if (!clip_isInBounds(clip_commonPosition)) discard;
1456
+ `
1457
+ )
1164
1458
  };
1165
1459
  var ClipExtension = class extends import_core10.LayerExtension {
1166
1460
  getShaders() {
@@ -1177,20 +1471,23 @@ var ClipExtension = class extends import_core10.LayerExtension {
1177
1471
  inject: injectionFs
1178
1472
  };
1179
1473
  }
1180
- draw({ uniforms }) {
1474
+ /* eslint-disable camelcase */
1475
+ draw() {
1181
1476
  const { clipBounds } = this.props;
1477
+ const clipProps = {};
1182
1478
  if (this.state.clipByInstance) {
1183
- uniforms.clip_bounds = clipBounds;
1479
+ clipProps.bounds = clipBounds;
1184
1480
  } else {
1185
1481
  const corner0 = this.projectPosition([clipBounds[0], clipBounds[1], 0]);
1186
1482
  const corner1 = this.projectPosition([clipBounds[2], clipBounds[3], 0]);
1187
- uniforms.clip_bounds = [
1483
+ clipProps.bounds = [
1188
1484
  Math.min(corner0[0], corner1[0]),
1189
1485
  Math.min(corner0[1], corner1[1]),
1190
1486
  Math.max(corner0[0], corner1[0]),
1191
1487
  Math.max(corner0[1], corner1[1])
1192
1488
  ];
1193
1489
  }
1490
+ this.setShaderModuleProps({ clip: clipProps });
1194
1491
  }
1195
1492
  };
1196
1493
  ClipExtension.defaultProps = defaultProps5;
@@ -1202,80 +1499,112 @@ var import_core15 = require("@deck.gl/core");
1202
1499
 
1203
1500
  // dist/collision-filter/shader-module.js
1204
1501
  var import_core11 = require("@deck.gl/core");
1205
- var vs3 = `
1502
+ var vs4 = (
1503
+ /* glsl */
1504
+ `
1206
1505
  in float collisionPriorities;
1506
+
1207
1507
  uniform sampler2D collision_texture;
1208
- uniform bool collision_sort;
1209
- uniform bool collision_enabled;
1508
+
1509
+ uniform collisionUniforms {
1510
+ bool sort;
1511
+ bool enabled;
1512
+ } collision;
1513
+
1210
1514
  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;
1515
+ vec4 collision_clipspace = project_common_position_to_clipspace(position);
1516
+ return (1.0 + collision_clipspace.xy / collision_clipspace.w) / 2.0;
1213
1517
  }
1518
+
1214
1519
  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);
1520
+ vec4 collision_pickingColor = texture(collision_texture, tex);
1521
+ float delta = dot(abs(collision_pickingColor.rgb - pickingColor), vec3(1.0));
1522
+ float e = 0.001;
1523
+ return step(delta, e);
1219
1524
  }
1525
+
1220
1526
  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);
1527
+ if (!collision.enabled) {
1528
+ return 1.0;
1529
+ }
1530
+
1531
+ // Visibility test, sample area of 5x5 pixels in order to fade in/out.
1532
+ // Due to the locality, the lookups will be cached
1533
+ // This reduces the flicker present when objects are shown/hidden
1534
+ const int N = 2;
1535
+ float accumulator = 0.0;
1536
+ vec2 step = vec2(1.0 / project.viewportSize);
1537
+
1538
+ const float floatN = float(N);
1539
+ vec2 delta = -floatN * step;
1540
+ for(int i = -N; i <= N; i++) {
1541
+ delta.x = -step.x * floatN;
1542
+ for(int j = -N; j <= N; j++) {
1543
+ accumulator += collision_match(texCoords + delta, pickingColor);
1544
+ delta.x += step.x;
1545
+ }
1546
+ delta.y += step.y;
1547
+ }
1548
+
1549
+ float W = 2.0 * floatN + 1.0;
1550
+ return pow(accumulator / (W * W), 2.2);
1239
1551
  }
1240
- `;
1552
+ `
1553
+ );
1241
1554
  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;
1555
+ "vs:#decl": (
1556
+ /* glsl */
1557
+ `
1558
+ float collision_fade = 1.0;
1261
1559
  `
1560
+ ),
1561
+ "vs:DECKGL_FILTER_GL_POSITION": (
1562
+ /* glsl */
1563
+ `
1564
+ if (collision.sort) {
1565
+ float collisionPriority = collisionPriorities;
1566
+ position.z = -0.001 * collisionPriority * position.w; // Support range -1000 -> 1000
1567
+ }
1568
+
1569
+ if (collision.enabled) {
1570
+ vec4 collision_common_position = project_position(vec4(geometry.worldPosition, 1.0));
1571
+ vec2 collision_texCoords = collision_getCoords(collision_common_position);
1572
+ collision_fade = collision_isVisible(collision_texCoords, geometry.pickingColor / 255.0);
1573
+ if (collision_fade < 0.0001) {
1574
+ // Position outside clip space bounds to discard
1575
+ position = vec4(0.0, 0.0, 2.0, 1.0);
1576
+ }
1577
+ }
1578
+ `
1579
+ ),
1580
+ "vs:DECKGL_FILTER_COLOR": (
1581
+ /* glsl */
1582
+ `
1583
+ color.a *= collision_fade;
1584
+ `
1585
+ )
1262
1586
  };
1263
- var getCollisionUniforms = (opts, uniforms) => {
1587
+ var getCollisionUniforms = (opts) => {
1264
1588
  if (!opts || !("dummyCollisionMap" in opts)) {
1265
1589
  return {};
1266
1590
  }
1267
- const { collisionFBO, drawToCollisionMap, dummyCollisionMap } = opts;
1591
+ const { enabled, collisionFBO, drawToCollisionMap, dummyCollisionMap } = opts;
1268
1592
  return {
1269
- collision_sort: Boolean(drawToCollisionMap),
1593
+ enabled: enabled && !drawToCollisionMap,
1594
+ sort: Boolean(drawToCollisionMap),
1270
1595
  collision_texture: !drawToCollisionMap && collisionFBO ? collisionFBO.colorAttachments[0] : dummyCollisionMap
1271
1596
  };
1272
1597
  };
1273
1598
  var shader_module_default2 = {
1274
1599
  name: "collision",
1275
1600
  dependencies: [import_core11.project],
1276
- vs: vs3,
1601
+ vs: vs4,
1277
1602
  inject: inject4,
1278
- getUniforms: getCollisionUniforms
1603
+ getUniforms: getCollisionUniforms,
1604
+ uniformTypes: {
1605
+ sort: "i32",
1606
+ enabled: "i32"
1607
+ }
1279
1608
  };
1280
1609
 
1281
1610
  // dist/collision-filter/collision-filter-effect.js
@@ -1292,16 +1621,23 @@ var CollisionFilterPass = class extends import_core12._LayersPass {
1292
1621
  this.render({ ...options, clearColor, scissorRect, target, pass: "collision" });
1293
1622
  }
1294
1623
  getLayerParameters(layer, layerIndex, viewport) {
1295
- return { ...layer.props.parameters, blend: false, depthRange: [0, 1], depthTest: true };
1624
+ return {
1625
+ ...layer.props.parameters,
1626
+ blend: false,
1627
+ depthWriteEnabled: true,
1628
+ depthCompare: "less-equal"
1629
+ };
1296
1630
  }
1297
- getModuleParameters() {
1631
+ getShaderModuleProps() {
1298
1632
  return {
1299
- drawToCollisionMap: true,
1633
+ collision: {
1634
+ drawToCollisionMap: true
1635
+ },
1300
1636
  picking: {
1301
1637
  isActive: 1,
1302
1638
  isAttribute: false
1303
1639
  },
1304
- lightSources: {}
1640
+ lighting: { enabled: false }
1305
1641
  };
1306
1642
  }
1307
1643
  };
@@ -1330,6 +1666,7 @@ var CollisionFilterEffect = class {
1330
1666
  return;
1331
1667
  }
1332
1668
  const collisionLayers = layers.filter(
1669
+ // @ts-ignore
1333
1670
  ({ props: { visible, collisionEnabled } }) => visible && collisionEnabled
1334
1671
  );
1335
1672
  if (collisionLayers.length === 0) {
@@ -1365,7 +1702,12 @@ var CollisionFilterEffect = class {
1365
1702
  if (!oldRenderInfo) {
1366
1703
  return;
1367
1704
  }
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);
1705
+ const needsRender = viewportChanged || // If render info is new
1706
+ renderInfo === oldRenderInfo || // If sublayers have changed
1707
+ !(0, import_core14._deepEqual)(oldRenderInfo.layers, renderInfo.layers, 1) || // If a sublayer's bounds have been updated
1708
+ renderInfo.layerBounds.some((b, i) => !(0, import_core13.equals)(b, oldRenderInfo.layerBounds[i])) || // If a sublayer's isLoaded state has been updated
1709
+ renderInfo.allLayersLoaded !== oldRenderInfo.allLayersLoaded || // Some prop is in transition
1710
+ renderInfo.layers.some((layer) => layer.props.transitions);
1369
1711
  this.channels[collisionGroup] = renderInfo;
1370
1712
  if (needsRender) {
1371
1713
  this.lastViewport = viewport;
@@ -1379,17 +1721,28 @@ var CollisionFilterEffect = class {
1379
1721
  viewports: viewport ? [viewport] : [],
1380
1722
  onViewportActive,
1381
1723
  views,
1382
- moduleParameters: {
1383
- dummyCollisionMap: this.dummyCollisionMap,
1384
- devicePixelRatio: collisionFBO.device.canvasContext.getDevicePixelRatio() / DOWNSCALE
1724
+ shaderModuleProps: {
1725
+ collision: {
1726
+ enabled: true,
1727
+ // To avoid feedback loop forming between Framebuffer and active Texture.
1728
+ dummyCollisionMap: this.dummyCollisionMap
1729
+ },
1730
+ project: {
1731
+ // @ts-expect-error TODO - assuming WebGL context
1732
+ devicePixelRatio: collisionFBO.device.canvasContext.getDevicePixelRatio() / DOWNSCALE
1733
+ }
1385
1734
  }
1386
1735
  });
1387
1736
  }
1388
1737
  }
1738
+ /**
1739
+ * Group layers by collisionGroup
1740
+ * Returns a map from collisionGroup to render info
1741
+ */
1389
1742
  _groupByCollisionGroup(device, collisionLayers) {
1390
1743
  const channelMap = {};
1391
1744
  for (const layer of collisionLayers) {
1392
- const { collisionGroup } = layer.props;
1745
+ const collisionGroup = layer.props.collisionGroup;
1393
1746
  let channelInfo = channelMap[collisionGroup];
1394
1747
  if (!channelInfo) {
1395
1748
  channelInfo = { collisionGroup, layers: [], layerBounds: [], allLayersLoaded: true };
@@ -1416,10 +1769,18 @@ var CollisionFilterEffect = class {
1416
1769
  }
1417
1770
  return channelMap;
1418
1771
  }
1419
- getModuleParameters(layer) {
1420
- const { collisionGroup } = layer.props;
1772
+ getShaderModuleProps(layer) {
1773
+ const { collisionGroup, collisionEnabled } = layer.props;
1421
1774
  const { collisionFBOs, dummyCollisionMap } = this;
1422
- return { collisionFBO: collisionFBOs[collisionGroup], dummyCollisionMap };
1775
+ const collisionFBO = collisionFBOs[collisionGroup];
1776
+ const enabled = collisionEnabled && Boolean(collisionFBO);
1777
+ return {
1778
+ collision: {
1779
+ enabled,
1780
+ collisionFBO,
1781
+ dummyCollisionMap
1782
+ }
1783
+ };
1423
1784
  }
1424
1785
  cleanup() {
1425
1786
  if (this.dummyCollisionMap) {
@@ -1450,9 +1811,7 @@ var CollisionFilterEffect = class {
1450
1811
  format: "depth16unorm",
1451
1812
  width,
1452
1813
  height,
1453
- mipmaps: false,
1454
- dataFormat: 6402,
1455
- type: 5125
1814
+ mipmaps: false
1456
1815
  });
1457
1816
  this.collisionFBOs[collisionGroup] = device.createFramebuffer({
1458
1817
  id: `collision-${collisionGroup}`,
@@ -1483,12 +1842,10 @@ var CollisionFilterExtension = class extends import_core15.LayerExtension {
1483
1842
  getShaders() {
1484
1843
  return { modules: [shader_module_default2] };
1485
1844
  }
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) {
1845
+ /* eslint-disable camelcase */
1846
+ draw({ shaderModuleProps }) {
1847
+ var _a;
1848
+ if ((_a = shaderModuleProps.collision) == null ? void 0 : _a.drawToCollisionMap) {
1492
1849
  this.props = this.clone(this.props.collisionTestProps).props;
1493
1850
  }
1494
1851
  }
@@ -1520,63 +1877,101 @@ var import_core21 = require("@deck.gl/core");
1520
1877
 
1521
1878
  // dist/mask/shader-module.js
1522
1879
  var import_core16 = require("@deck.gl/core");
1523
- var vs4 = `
1524
- uniform vec4 mask_bounds;
1525
- uniform bool mask_maskByInstance;
1880
+ var uniformBlock4 = (
1881
+ /* glsl */
1882
+ `uniform maskUniforms {
1883
+ vec4 bounds;
1884
+ highp int channel;
1885
+ bool enabled;
1886
+ bool inverted;
1887
+ bool maskByInstance;
1888
+ } mask;
1889
+ `
1890
+ );
1891
+ var vertex3 = (
1892
+ /* glsl */
1893
+ `
1526
1894
  vec2 mask_getCoords(vec4 position) {
1527
- return (position.xy - mask_bounds.xy) / (mask_bounds.zw - mask_bounds.xy);
1895
+ return (position.xy - mask.bounds.xy) / (mask.bounds.zw - mask.bounds.xy);
1528
1896
  }
1897
+ `
1898
+ );
1899
+ var vs5 = `
1900
+ ${uniformBlock4}
1901
+ ${vertex3}
1529
1902
  `;
1530
- var fs3 = `
1903
+ var fragment3 = (
1904
+ /* glsl */
1905
+ `
1531
1906
  uniform sampler2D mask_texture;
1532
- uniform int mask_channel;
1533
- uniform bool mask_enabled;
1534
- uniform bool mask_inverted;
1907
+
1535
1908
  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
- }
1909
+ if (!mask.enabled) {
1910
+ return true;
1911
+ }
1912
+ vec4 maskColor = texture(mask_texture, texCoords);
1913
+ float maskValue = 1.0;
1914
+ if (mask.channel == 0) {
1915
+ maskValue = maskColor.r;
1916
+ } else if (mask.channel == 1) {
1917
+ maskValue = maskColor.g;
1918
+ } else if (mask.channel == 2) {
1919
+ maskValue = maskColor.b;
1920
+ } else if (mask.channel == 3) {
1921
+ maskValue = maskColor.a;
1922
+ }
1923
+
1924
+ if (mask.inverted) {
1925
+ return maskValue >= 0.5;
1926
+ } else {
1927
+ return maskValue < 0.5;
1928
+ }
1555
1929
  }
1930
+ `
1931
+ );
1932
+ var fs4 = `
1933
+ ${uniformBlock4}
1934
+ ${fragment3}
1556
1935
  `;
1557
1936
  var inject5 = {
1558
- "vs:#decl": `
1937
+ "vs:#decl": (
1938
+ /* glsl */
1939
+ `
1559
1940
  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": `
1941
+ `
1942
+ ),
1943
+ "vs:#main-end": (
1944
+ /* glsl */
1945
+ `
1946
+ vec4 mask_common_position;
1947
+ if (mask.maskByInstance) {
1948
+ mask_common_position = project_position(vec4(geometry.worldPosition, 1.0));
1949
+ } else {
1950
+ mask_common_position = geometry.position;
1951
+ }
1952
+ mask_texCoords = mask_getCoords(mask_common_position);
1953
+ `
1954
+ ),
1955
+ "fs:#decl": (
1956
+ /* glsl */
1957
+ `
1571
1958
  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
1959
  `
1960
+ ),
1961
+ "fs:#main-start": (
1962
+ /* glsl */
1963
+ `
1964
+ if (mask.enabled) {
1965
+ bool mask = mask_isInBounds(mask_texCoords);
1966
+
1967
+ // Debug: show extent of render target
1968
+ // fragColor = vec4(mask_texCoords, 0.0, 1.0);
1969
+ // fragColor = texture(mask_texture, mask_texCoords);
1970
+
1971
+ if (!mask) discard;
1972
+ }
1973
+ `
1974
+ )
1580
1975
  };
1581
1976
  var getMaskUniforms = (opts) => {
1582
1977
  if (opts && "maskMap" in opts) {
@@ -1584,15 +1979,22 @@ var getMaskUniforms = (opts) => {
1584
1979
  mask_texture: opts.maskMap
1585
1980
  };
1586
1981
  }
1587
- return {};
1982
+ return opts || {};
1588
1983
  };
1589
1984
  var shader_module_default3 = {
1590
1985
  name: "mask",
1591
1986
  dependencies: [import_core16.project],
1592
- vs: vs4,
1593
- fs: fs3,
1987
+ vs: vs5,
1988
+ fs: fs4,
1594
1989
  inject: inject5,
1595
- getUniforms: getMaskUniforms
1990
+ getUniforms: getMaskUniforms,
1991
+ uniformTypes: {
1992
+ bounds: "vec4<f32>",
1993
+ channel: "i32",
1994
+ enabled: "i32",
1995
+ inverted: "i32",
1996
+ maskByInstance: "i32"
1997
+ }
1596
1998
  };
1597
1999
 
1598
2000
  // dist/mask/mask-effect.js
@@ -1640,7 +2042,7 @@ var MaskPass = class extends import_core17._LayersPass {
1640
2042
  return {
1641
2043
  ...layer.props.parameters,
1642
2044
  blend: true,
1643
- depthTest: false,
2045
+ depthCompare: "always",
1644
2046
  ...MASK_BLENDING
1645
2047
  };
1646
2048
  }
@@ -1821,13 +2223,26 @@ var MaskEffect = class {
1821
2223
  }
1822
2224
  return { didRender };
1823
2225
  }
2226
+ /* eslint-disable-next-line complexity */
1824
2227
  _renderChannel(channelInfo, { layerFilter, onViewportActive, views, viewport, viewportChanged }) {
1825
2228
  let didRender = false;
1826
2229
  const oldChannelInfo = this.channels[channelInfo.index];
1827
2230
  if (!oldChannelInfo) {
1828
2231
  return didRender;
1829
2232
  }
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]);
2233
+ const maskChanged = (
2234
+ // If a channel is new
2235
+ channelInfo === oldChannelInfo || // If sublayers have changed
2236
+ channelInfo.layers.length !== oldChannelInfo.layers.length || channelInfo.layers.some((layer, i) => (
2237
+ // Layer instance is updated
2238
+ // Layer props might have changed
2239
+ // Undetermined props could have an effect on the output geometry of a mask layer,
2240
+ // for example getRadius+updateTriggers, radiusScale, modelMatrix
2241
+ layer !== oldChannelInfo.layers[i] || // Some prop is in transition
2242
+ layer.props.transitions
2243
+ )) || // If a sublayer's positions have been updated, the cached bounds will change shallowly
2244
+ channelInfo.layerBounds.some((b, i) => b !== oldChannelInfo.layerBounds[i])
2245
+ );
1831
2246
  channelInfo.bounds = oldChannelInfo.bounds;
1832
2247
  channelInfo.maskBounds = oldChannelInfo.maskBounds;
1833
2248
  this.channels[channelInfo.index] = channelInfo;
@@ -1853,8 +2268,10 @@ var MaskEffect = class {
1853
2268
  viewports: maskViewport ? [maskViewport] : [],
1854
2269
  onViewportActive,
1855
2270
  views,
1856
- moduleParameters: {
1857
- devicePixelRatio: 1
2271
+ shaderModuleProps: {
2272
+ project: {
2273
+ devicePixelRatio: 1
2274
+ }
1858
2275
  }
1859
2276
  });
1860
2277
  didRender = true;
@@ -1868,6 +2285,13 @@ var MaskEffect = class {
1868
2285
  };
1869
2286
  return didRender;
1870
2287
  }
2288
+ /**
2289
+ * Find a channel to render each mask into
2290
+ * If a maskId already exists, diff and update the existing channel
2291
+ * Otherwise replace a removed mask
2292
+ * Otherwise create a new channel
2293
+ * Returns a map from mask layer id to channel info
2294
+ */
1871
2295
  _sortMaskChannels(maskLayers) {
1872
2296
  const channelMap = {};
1873
2297
  let channelCount = 0;
@@ -1907,10 +2331,12 @@ var MaskEffect = class {
1907
2331
  }
1908
2332
  return channelMap;
1909
2333
  }
1910
- getModuleParameters() {
2334
+ getShaderModuleProps() {
1911
2335
  return {
1912
- maskMap: this.masks ? this.maskMap : this.dummyMaskMap,
1913
- maskChannels: this.masks
2336
+ mask: {
2337
+ maskMap: this.masks ? this.maskMap : this.dummyMaskMap,
2338
+ maskChannels: this.masks
2339
+ }
1914
2340
  };
1915
2341
  }
1916
2342
  cleanup() {
@@ -1950,30 +2376,33 @@ var MaskExtension = class extends import_core21.LayerExtension {
1950
2376
  modules: [shader_module_default3]
1951
2377
  };
1952
2378
  }
1953
- draw({ uniforms, context, moduleParameters }) {
1954
- uniforms.mask_maskByInstance = this.state.maskByInstance;
2379
+ /* eslint-disable camelcase */
2380
+ draw({ context, shaderModuleProps }) {
2381
+ const maskProps = {};
2382
+ maskProps.maskByInstance = Boolean(this.state.maskByInstance);
1955
2383
  const { maskId, maskInverted } = this.props;
1956
- const { maskChannels } = moduleParameters;
2384
+ const { maskChannels } = shaderModuleProps.mask || {};
1957
2385
  const { viewport } = context;
1958
2386
  if (maskChannels && maskChannels[maskId]) {
1959
2387
  const { index, bounds, coordinateOrigin: fromCoordinateOrigin } = maskChannels[maskId];
1960
2388
  let { coordinateSystem: fromCoordinateSystem } = maskChannels[maskId];
1961
- uniforms.mask_enabled = true;
1962
- uniforms.mask_channel = index;
1963
- uniforms.mask_inverted = maskInverted;
2389
+ maskProps.enabled = true;
2390
+ maskProps.channel = index;
2391
+ maskProps.inverted = maskInverted;
1964
2392
  if (fromCoordinateSystem === import_core21.COORDINATE_SYSTEM.DEFAULT) {
1965
2393
  fromCoordinateSystem = viewport.isGeospatial ? import_core21.COORDINATE_SYSTEM.LNGLAT : import_core21.COORDINATE_SYSTEM.CARTESIAN;
1966
2394
  }
1967
2395
  const opts = { modelMatrix: null, fromCoordinateOrigin, fromCoordinateSystem };
1968
2396
  const bl = this.projectPosition([bounds[0], bounds[1], 0], opts);
1969
2397
  const tr = this.projectPosition([bounds[2], bounds[3], 0], opts);
1970
- uniforms.mask_bounds = [bl[0], bl[1], tr[0], tr[1]];
2398
+ maskProps.bounds = [bl[0], bl[1], tr[0], tr[1]];
1971
2399
  } else {
1972
2400
  if (maskId) {
1973
2401
  import_core21.log.warn(`Could not find a mask layer with id: ${maskId}`)();
1974
2402
  }
1975
- uniforms.mask_enabled = false;
2403
+ maskProps.enabled = false;
1976
2404
  }
2405
+ this.setShaderModuleProps({ mask: maskProps });
1977
2406
  }
1978
2407
  };
1979
2408
  MaskExtension.defaultProps = defaultProps7;
@@ -1990,78 +2419,103 @@ var import_core25 = require("@deck.gl/core");
1990
2419
  var import_core22 = require("@deck.gl/core");
1991
2420
  var TERRAIN_MODE = {
1992
2421
  NONE: 0,
2422
+ /** A terrain layer rendering encoded ground elevation into the height map */
1993
2423
  WRITE_HEIGHT_MAP: 1,
2424
+ /** An offset layer reading encoded ground elevation from the height map */
1994
2425
  USE_HEIGHT_MAP: 2,
2426
+ /** A terrain layer rendering to screen, using the cover fbo overlaid with its own texture */
1995
2427
  USE_COVER: 3,
2428
+ /** A terrain layer rendering to screen, using the cover fbo as texture */
1996
2429
  USE_COVER_ONLY: 4,
2430
+ /** Draped layer is rendered into a texture, and never to screen */
1997
2431
  SKIP: 5
1998
2432
  };
1999
2433
  var TERRAIN_MODE_CONSTANTS = Object.keys(TERRAIN_MODE).map((key) => `const float TERRAIN_MODE_${key} = ${TERRAIN_MODE[key]}.0;`).join("\n");
2434
+ var uniformBlock5 = (
2435
+ // eslint-disable-next-line prefer-template
2436
+ TERRAIN_MODE_CONSTANTS + /* glsl */
2437
+ `
2438
+ uniform terrainUniforms {
2439
+ float mode;
2440
+ vec4 bounds;
2441
+ } terrain;
2442
+
2443
+ uniform sampler2D terrain_map;
2444
+ `
2445
+ );
2000
2446
  var terrainModule = {
2001
2447
  name: "terrain",
2002
2448
  dependencies: [import_core22.project],
2449
+ // eslint-disable-next-line prefer-template
2450
+ vs: uniformBlock5 + /* glsl */
2451
+ "out vec3 commonPos;",
2452
+ // eslint-disable-next-line prefer-template
2453
+ fs: uniformBlock5 + /* glsl */
2454
+ "in vec3 commonPos;",
2003
2455
  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;
2456
+ "vs:#main-start": (
2457
+ /* glsl */
2458
+ `
2459
+ if (terrain.mode == TERRAIN_MODE_SKIP) {
2460
+ gl_Position = vec4(0.0);
2461
+ return;
2014
2462
  }
2015
- `,
2016
- "vs:DECKGL_FILTER_GL_POSITION": `
2463
+ `
2464
+ ),
2465
+ "vs:DECKGL_FILTER_GL_POSITION": (
2466
+ /* glsl */
2467
+ `
2017
2468
  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;
2469
+ if (terrain.mode == TERRAIN_MODE_WRITE_HEIGHT_MAP) {
2470
+ vec2 texCoords = (commonPos.xy - terrain.bounds.xy) / terrain.bounds.zw;
2471
+ position = vec4(texCoords * 2.0 - 1.0, 0.0, 1.0);
2472
+ commonPos.z += project.commonOrigin.z;
2473
+ }
2474
+ if (terrain.mode == TERRAIN_MODE_USE_HEIGHT_MAP) {
2475
+ vec3 anchor = geometry.worldPosition;
2476
+ anchor.z = 0.0;
2477
+ vec3 anchorCommon = project_position(anchor);
2478
+ vec2 texCoords = (anchorCommon.xy - terrain.bounds.xy) / terrain.bounds.zw;
2479
+ if (texCoords.x >= 0.0 && texCoords.y >= 0.0 && texCoords.x <= 1.0 && texCoords.y <= 1.0) {
2480
+ float terrainZ = texture(terrain_map, texCoords).r;
2481
+ geometry.position.z += terrainZ;
2482
+ position = project_common_position_to_clipspace(geometry.position);
2483
+ }
2484
+ }
2485
+ `
2486
+ ),
2487
+ "fs:#main-start": (
2488
+ /* glsl */
2489
+ `
2490
+ if (terrain.mode == TERRAIN_MODE_WRITE_HEIGHT_MAP) {
2491
+ fragColor = vec4(commonPos.z, 0.0, 0.0, 1.0);
2492
+ return;
2493
+ }
2494
+ `
2495
+ ),
2496
+ "fs:DECKGL_FILTER_COLOR": (
2497
+ /* glsl */
2498
+ `
2499
+ if ((terrain.mode == TERRAIN_MODE_USE_COVER) || (terrain.mode == TERRAIN_MODE_USE_COVER_ONLY)) {
2500
+ vec2 texCoords = (commonPos.xy - terrain.bounds.xy) / terrain.bounds.zw;
2501
+ vec4 pixel = texture(terrain_map, texCoords);
2502
+ if (terrain.mode == TERRAIN_MODE_USE_COVER_ONLY) {
2503
+ color = pixel;
2504
+ } else {
2505
+ // pixel is premultiplied
2506
+ color = pixel + color * (1.0 - pixel.a);
2507
+ }
2508
+ return;
2057
2509
  }
2058
- `
2510
+ `
2511
+ )
2059
2512
  },
2060
- getUniforms: (opts = {}, uniforms) => {
2061
- var _a;
2513
+ // eslint-disable-next-line complexity
2514
+ getUniforms: (opts = {}) => {
2062
2515
  if ("dummyHeightMap" in opts) {
2063
2516
  const { drawToTerrainHeightMap, heightMap, heightMapBounds, dummyHeightMap, terrainCover, useTerrainHeightMap, terrainSkipRender } = opts;
2064
- const { project_uCommonOrigin } = uniforms;
2517
+ const projectUniforms = import_core22.project.getUniforms(opts.project);
2518
+ const { commonOrigin } = projectUniforms;
2065
2519
  let mode = terrainSkipRender ? TERRAIN_MODE.SKIP : TERRAIN_MODE.NONE;
2066
2520
  let sampler = dummyHeightMap;
2067
2521
  let bounds = null;
@@ -2073,10 +2527,9 @@ return;
2073
2527
  sampler = heightMap;
2074
2528
  bounds = heightMapBounds;
2075
2529
  } else if (terrainCover) {
2076
- const isPicking = (_a = opts.picking) == null ? void 0 : _a.isActive;
2077
- const fbo = isPicking ? terrainCover.getPickingFramebuffer() : terrainCover.getRenderFramebuffer();
2530
+ const fbo = opts.isPicking ? terrainCover.getPickingFramebuffer() : terrainCover.getRenderFramebuffer();
2078
2531
  sampler = fbo == null ? void 0 : fbo.colorAttachments[0].texture;
2079
- if (isPicking) {
2532
+ if (opts.isPicking) {
2080
2533
  mode = TERRAIN_MODE.SKIP;
2081
2534
  }
2082
2535
  if (sampler) {
@@ -2087,22 +2540,27 @@ return;
2087
2540
  }
2088
2541
  }
2089
2542
  return {
2090
- terrain_mode: mode,
2543
+ mode,
2091
2544
  terrain_map: sampler,
2092
- terrain_bounds: bounds ? [
2093
- bounds[0] - project_uCommonOrigin[0],
2094
- bounds[1] - project_uCommonOrigin[1],
2545
+ // Convert bounds to the common space, as [minX, minY, width, height]
2546
+ bounds: bounds ? [
2547
+ bounds[0] - commonOrigin[0],
2548
+ bounds[1] - commonOrigin[1],
2095
2549
  bounds[2] - bounds[0],
2096
2550
  bounds[3] - bounds[1]
2097
2551
  ] : [0, 0, 0, 0]
2098
2552
  };
2099
2553
  }
2100
- return null;
2554
+ return {};
2555
+ },
2556
+ uniformTypes: {
2557
+ mode: "f32",
2558
+ bounds: "vec4<f32>"
2101
2559
  }
2102
2560
  };
2103
2561
 
2104
2562
  // dist/terrain/utils.js
2105
- var import_constants2 = require("@luma.gl/constants");
2563
+ var import_constants = require("@luma.gl/constants");
2106
2564
  function createRenderTarget(device, opts) {
2107
2565
  return device.createFramebuffer({
2108
2566
  id: opts.id,
@@ -2141,6 +2599,7 @@ var TerrainCover = class {
2141
2599
  get id() {
2142
2600
  return this.targetLayer.id;
2143
2601
  }
2602
+ /** returns true if the target layer is still in use (i.e. not finalized) */
2144
2603
  get isActive() {
2145
2604
  return Boolean(this.targetLayer.getCurrentLayer());
2146
2605
  }
@@ -2160,6 +2619,7 @@ var TerrainCover = class {
2160
2619
  }
2161
2620
  return layersChanged || sizeChanged;
2162
2621
  }
2622
+ /** Compare layers with the last version. Only rerender if necessary. */
2163
2623
  _updateLayers(layers) {
2164
2624
  let needsRedraw = false;
2165
2625
  layers = this.tile ? getIntersectingLayers(this.tile, layers) : layers;
@@ -2179,6 +2639,7 @@ var TerrainCover = class {
2179
2639
  }
2180
2640
  return needsRedraw;
2181
2641
  }
2642
+ /** Compare viewport and terrain bounds with the last version. Only rerender if necesary. */
2182
2643
  _updateViewport(viewport) {
2183
2644
  var _a;
2184
2645
  const targetLayer = this.targetLayer;
@@ -2348,10 +2809,17 @@ var TerrainPass = class extends import_core23._LayersPass {
2348
2809
  return {
2349
2810
  ...layer.props.parameters,
2350
2811
  blend: true,
2351
- depthTest: false,
2812
+ depthCompare: "always",
2352
2813
  ...layer.props.operation.includes("terrain") && TERRAIN_BLENDING
2353
2814
  };
2354
2815
  }
2816
+ getShaderModuleProps(layer, effects, otherShaderModuleProps) {
2817
+ return {
2818
+ terrain: {
2819
+ project: otherShaderModuleProps.project
2820
+ }
2821
+ };
2822
+ }
2355
2823
  };
2356
2824
 
2357
2825
  // dist/terrain/terrain-picking-pass.js
@@ -2395,6 +2863,8 @@ var TerrainPickingPass = class extends import_core24._PickLayersPass {
2395
2863
  layers,
2396
2864
  effects: [],
2397
2865
  viewports: [viewport],
2866
+ // Disable the default culling because TileLayer would cull sublayers based on the screen viewport,
2867
+ // not the viewport of the terrain cover. Culling is already done by `terrainCover.filterLayers`
2398
2868
  cullRect: void 0,
2399
2869
  deviceRect: viewport,
2400
2870
  pickZ: false
@@ -2408,7 +2878,14 @@ var TerrainPickingPass = class extends import_core24._PickLayersPass {
2408
2878
  parameters2 = super.getLayerParameters(layer, layerIndex, viewport);
2409
2879
  parameters2.blend = true;
2410
2880
  }
2411
- return { ...parameters2, depthTest: false };
2881
+ return { ...parameters2, depthCompare: "always" };
2882
+ }
2883
+ getShaderModuleProps(layer, effects, otherShaderModuleProps) {
2884
+ return {
2885
+ terrain: {
2886
+ project: otherShaderModuleProps.project
2887
+ }
2888
+ };
2412
2889
  }
2413
2890
  };
2414
2891
 
@@ -2427,6 +2904,9 @@ var HeightMapBuilder = class {
2427
2904
  this.lastViewport = null;
2428
2905
  this.device = device;
2429
2906
  }
2907
+ /** Returns the height map framebuffer for read/write access.
2908
+ * Returns null when the texture is invalid.
2909
+ */
2430
2910
  getRenderFramebuffer() {
2431
2911
  if (!this.renderViewport) {
2432
2912
  return null;
@@ -2436,8 +2916,17 @@ var HeightMapBuilder = class {
2436
2916
  }
2437
2917
  return this.fbo;
2438
2918
  }
2919
+ /** Called every render cycle to check if the framebuffer needs update */
2439
2920
  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]);
2921
+ const layersChanged = layers.length !== this.layers.length || layers.some((layer, i) => (
2922
+ // Layer instance is updated
2923
+ // Layer props might have changed
2924
+ // Undetermined props could have an effect on the output geometry of a terrain source,
2925
+ // for example getElevation+updateTriggers, elevationScale, modelMatrix
2926
+ layer !== this.layers[i] || // Some prop is in transition
2927
+ layer.props.transitions || // Layer's geometry bounds have changed
2928
+ layer.getBounds() !== this.layersBounds[i]
2929
+ ));
2441
2930
  if (layersChanged) {
2442
2931
  this.layers = layers;
2443
2932
  this.layersBounds = layers.map((layer) => layer.getBounds());
@@ -2458,6 +2947,10 @@ var HeightMapBuilder = class {
2458
2947
  const pixelWidth = (bounds[2] - bounds[0]) * scale;
2459
2948
  const pixelHeight = (bounds[3] - bounds[1]) * scale;
2460
2949
  this.renderViewport = pixelWidth > 0 || pixelHeight > 0 ? makeViewport({
2950
+ // It's not important whether the geometry is visible in this viewport, because
2951
+ // vertices will not use the standard project_to_clipspace in the DRAW_TO_HEIGHT_MAP shader
2952
+ // However the viewport must have the same center and zoom as the screen viewport
2953
+ // So that projection uniforms used for calculating z are the same
2461
2954
  bounds: [
2462
2955
  viewport.center[0] - 1,
2463
2956
  viewport.center[1] - 1,
@@ -2530,16 +3023,20 @@ var TerrainEffect = class {
2530
3023
  const drapeLayers = layers.filter((l) => l.state.terrainDrawMode === "drape");
2531
3024
  this._updateTerrainCovers(terrainLayers, drapeLayers, viewport, opts);
2532
3025
  }
2533
- getModuleParameters(layer) {
3026
+ getShaderModuleProps(layer, otherShaderModuleProps) {
2534
3027
  var _a, _b, _c;
2535
3028
  const { terrainDrawMode } = layer.state;
2536
3029
  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")
3030
+ terrain: {
3031
+ project: otherShaderModuleProps.project,
3032
+ isPicking: this.isPicking,
3033
+ heightMap: ((_b = (_a = this.heightMap) == null ? void 0 : _a.getRenderFramebuffer()) == null ? void 0 : _b.colorAttachments[0].texture) || null,
3034
+ heightMapBounds: (_c = this.heightMap) == null ? void 0 : _c.bounds,
3035
+ dummyHeightMap: this.dummyHeightMap,
3036
+ terrainCover: this.isDrapingEnabled ? this.terrainCovers.get(layer.id) : null,
3037
+ useTerrainHeightMap: terrainDrawMode === "offset",
3038
+ terrainSkipRender: terrainDrawMode === "drape" || !layer.props.operation.includes("draw")
3039
+ }
2543
3040
  };
2544
3041
  }
2545
3042
  cleanup({ deck }) {
@@ -2568,11 +3065,15 @@ var TerrainEffect = class {
2568
3065
  this.terrainPass.renderHeightMap(this.heightMap, {
2569
3066
  ...opts,
2570
3067
  layers: terrainLayers,
2571
- moduleParameters: {
2572
- heightMapBounds: this.heightMap.bounds,
2573
- dummyHeightMap: this.dummyHeightMap,
2574
- devicePixelRatio: 1,
2575
- drawToTerrainHeightMap: true
3068
+ shaderModuleProps: {
3069
+ terrain: {
3070
+ heightMapBounds: this.heightMap.bounds,
3071
+ dummyHeightMap: this.dummyHeightMap,
3072
+ drawToTerrainHeightMap: true
3073
+ },
3074
+ project: {
3075
+ devicePixelRatio: 1
3076
+ }
2576
3077
  }
2577
3078
  });
2578
3079
  }
@@ -2611,10 +3112,14 @@ var TerrainEffect = class {
2611
3112
  renderPass.renderTerrainCover(terrainCover, {
2612
3113
  ...opts,
2613
3114
  layers: drapeLayers,
2614
- moduleParameters: {
2615
- dummyHeightMap: this.dummyHeightMap,
2616
- terrainSkipRender: false,
2617
- devicePixelRatio: 1
3115
+ shaderModuleProps: {
3116
+ terrain: {
3117
+ dummyHeightMap: this.dummyHeightMap,
3118
+ terrainSkipRender: false
3119
+ },
3120
+ project: {
3121
+ devicePixelRatio: 1
3122
+ }
2618
3123
  }
2619
3124
  });
2620
3125
  if (!this.isPicking) {
@@ -2655,7 +3160,8 @@ var TerrainExtension = class extends import_core26.LayerExtension {
2655
3160
  updateState(params) {
2656
3161
  var _a;
2657
3162
  const { props, oldProps } = params;
2658
- if (this.state.terrainDrawMode && props.terrainDrawMode === oldProps.terrainDrawMode && props.extruded === oldProps.extruded) {
3163
+ if (this.state.terrainDrawMode && props.terrainDrawMode === oldProps.terrainDrawMode && // @ts-ignore `extruded` may not exist in props
3164
+ props.extruded === oldProps.extruded) {
2659
3165
  return;
2660
3166
  }
2661
3167
  let { terrainDrawMode } = props;