@deck.gl-community/infovis-layers 9.3.7 → 9.4.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/dist/index.cjs +1840 -1420
  2. package/dist/index.cjs.map +4 -4
  3. package/dist/layers/block-layer/block-layer-uniforms.d.ts +4 -3
  4. package/dist/layers/block-layer/block-layer-uniforms.d.ts.map +1 -1
  5. package/dist/layers/block-layer/block-layer-uniforms.js +4 -3
  6. package/dist/layers/block-layer/block-layer-uniforms.js.map +1 -1
  7. package/dist/layers/block-layer/block-layer-vertex.glsl.d.ts +1 -1
  8. package/dist/layers/block-layer/block-layer-vertex.glsl.js +4 -4
  9. package/dist/layers/block-layer/block-layer.d.ts +2 -0
  10. package/dist/layers/block-layer/block-layer.d.ts.map +1 -1
  11. package/dist/layers/block-layer/block-layer.js +23 -2
  12. package/dist/layers/block-layer/block-layer.js.map +1 -1
  13. package/dist/layers/block-layer/block-layer.wgsl.d.ts +4 -0
  14. package/dist/layers/block-layer/block-layer.wgsl.d.ts.map +1 -0
  15. package/dist/layers/block-layer/block-layer.wgsl.js +134 -0
  16. package/dist/layers/block-layer/block-layer.wgsl.js.map +1 -0
  17. package/dist/layers/fast-text-layer/fast-text-layer.d.ts +47 -0
  18. package/dist/layers/fast-text-layer/fast-text-layer.d.ts.map +1 -1
  19. package/dist/layers/fast-text-layer/fast-text-layer.js +5 -1
  20. package/dist/layers/fast-text-layer/fast-text-layer.js.map +1 -1
  21. package/dist/layers/fast-text-layer/fast-text-layer.wgsl.d.ts +4 -0
  22. package/dist/layers/fast-text-layer/fast-text-layer.wgsl.d.ts.map +1 -0
  23. package/dist/layers/fast-text-layer/fast-text-layer.wgsl.js +247 -0
  24. package/dist/layers/fast-text-layer/fast-text-layer.wgsl.js.map +1 -0
  25. package/dist/layers/time-delta-layer.d.ts.map +1 -1
  26. package/dist/layers/time-delta-layer.js +34 -17
  27. package/dist/layers/time-delta-layer.js.map +1 -1
  28. package/package.json +12 -12
  29. package/src/layers/block-layer/block-layer-uniforms.ts +4 -3
  30. package/src/layers/block-layer/block-layer-vertex.glsl.ts +4 -4
  31. package/src/layers/block-layer/block-layer.ts +24 -2
  32. package/src/layers/block-layer/block-layer.wgsl.ts +134 -0
  33. package/src/layers/fast-text-layer/fast-text-layer.ts +5 -1
  34. package/src/layers/fast-text-layer/fast-text-layer.wgsl.ts +247 -0
  35. package/src/layers/time-delta-layer.ts +34 -17
@@ -0,0 +1,247 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ /** WebGPU shaders for packed glyphs, following luma.gl's text-rendering conventions. */
6
+ export default /* wgsl */ `
7
+ struct FastTextUniforms {
8
+ fontAtlasSize: vec2<f32>,
9
+ fontSize: f32,
10
+ size: f32,
11
+ sizeScale: f32,
12
+ sizeMinPixels: f32,
13
+ sizeMaxPixels: f32,
14
+ pixelOffset: vec2<f32>,
15
+ billboard: f32,
16
+ sizeUnits: i32,
17
+ alphaCutoff: f32,
18
+ sdfEnabled: f32,
19
+ sdfBuffer: f32,
20
+ sdfGamma: f32,
21
+ contentCutoffPixels: vec2<f32>,
22
+ contentAlign: vec2<i32>,
23
+ flipY: f32,
24
+ };
25
+
26
+ @group(0) @binding(auto) var<uniform> fastText: FastTextUniforms;
27
+ @group(0) @binding(auto) var fontAtlasTexture: texture_2d<f32>;
28
+ @group(0) @binding(auto) var fontAtlasTextureSampler: sampler;
29
+
30
+ struct FastTextAttributes {
31
+ @location(0) positions: vec2<f32>,
32
+ @location(1) instancePositions: vec2<f32>,
33
+ @location(2) instanceGlyphOffsets: vec2<i32>,
34
+ @location(3) instanceGlyphFrames: vec4<u32>,
35
+ @location(4) instanceClipRects: vec4<i32>,
36
+ @location(5) instanceColors: vec4<f32>,
37
+ };
38
+
39
+ struct FastTextVaryings {
40
+ @builtin(position) position: vec4<f32>,
41
+ @location(0) color: vec4<f32>,
42
+ @location(1) textureCoords: vec2<f32>,
43
+ @location(2) uv: vec2<f32>,
44
+ };
45
+
46
+ struct FastTextClipResult {
47
+ position: vec4<f32>,
48
+ pixelOffset: vec2<f32>,
49
+ };
50
+
51
+ fn fast_text_alignment_pixel_offset(
52
+ anchor: f32,
53
+ extent: f32,
54
+ clipStart: f32,
55
+ clipEnd: f32,
56
+ mode: i32
57
+ ) -> f32 {
58
+ if (clipEnd < clipStart) {
59
+ return 0.0;
60
+ }
61
+ if (mode == 1) {
62
+ return max(-(anchor + clipStart), 0.0);
63
+ }
64
+ if (mode == 2) {
65
+ let visibleMin = max(0.0, anchor + clipStart);
66
+ let visibleMax = min(extent, anchor + clipEnd);
67
+ return select(0.0, (visibleMin + visibleMax) * 0.5 - anchor, visibleMin < visibleMax);
68
+ }
69
+ if (mode == 3) {
70
+ return min(extent - (anchor + clipEnd), 0.0);
71
+ }
72
+ return 0.0;
73
+ }
74
+
75
+ fn fast_text_clip_glyph_vertex(
76
+ initialPixelOffset: vec2<f32>,
77
+ anchorPositionScreen: vec2<f32>,
78
+ clipRect: vec4<i32>,
79
+ initialPosition: vec4<f32>
80
+ ) -> FastTextClipResult {
81
+ var result: FastTextClipResult;
82
+ result.position = initialPosition;
83
+ result.pixelOffset = initialPixelOffset;
84
+
85
+ let clipRectFloat = vec4<f32>(clipRect);
86
+ var clipXY = project_size_vec2(clipRectFloat.xy) * project.scale;
87
+ let clipWH = project_size_vec2(clipRectFloat.zw) * project.scale;
88
+
89
+ if (fastText.flipY > 0.5) {
90
+ clipXY.y = -clipXY.y - clipWH.y;
91
+ }
92
+
93
+ if (fastText.contentAlign.x > 0 || fastText.contentAlign.y > 0) {
94
+ let viewportPixels = project.viewportSize / project.devicePixelRatio;
95
+ let scrollPixels = vec2<f32>(
96
+ fast_text_alignment_pixel_offset(
97
+ anchorPositionScreen.x,
98
+ viewportPixels.x,
99
+ clipXY.x,
100
+ clipXY.x + clipWH.x,
101
+ fastText.contentAlign.x
102
+ ),
103
+ -fast_text_alignment_pixel_offset(
104
+ anchorPositionScreen.y,
105
+ viewportPixels.y,
106
+ -clipXY.y - clipWH.y,
107
+ -clipXY.y,
108
+ fastText.contentAlign.y
109
+ )
110
+ );
111
+ result.pixelOffset += scrollPixels;
112
+ result.position = vec4<f32>(
113
+ result.position.xy + project_pixel_size_to_clipspace(scrollPixels),
114
+ result.position.zw
115
+ );
116
+ }
117
+
118
+ if (clipRectFloat.z >= 0.0) {
119
+ if (result.pixelOffset.x < clipXY.x || result.pixelOffset.x > clipXY.x + clipWH.x) {
120
+ result.position = vec4<f32>(0.0);
121
+ } else if (fastText.contentCutoffPixels.x > 0.0) {
122
+ let viewportWidth = project.viewportSize.x / project.devicePixelRatio;
123
+ let left = max(anchorPositionScreen.x + clipXY.x, 0.0);
124
+ let right = min(anchorPositionScreen.x + clipXY.x + clipWH.x, viewportWidth);
125
+ if (right - left < fastText.contentCutoffPixels.x) {
126
+ result.position = vec4<f32>(0.0);
127
+ }
128
+ }
129
+ }
130
+
131
+ if (clipRectFloat.w >= 0.0) {
132
+ if (result.pixelOffset.y < clipXY.y || result.pixelOffset.y > clipXY.y + clipWH.y) {
133
+ result.position = vec4<f32>(0.0);
134
+ } else if (fastText.contentCutoffPixels.y > 0.0) {
135
+ let viewportHeight = project.viewportSize.y / project.devicePixelRatio;
136
+ let top = max(anchorPositionScreen.y - clipXY.y - clipWH.y, 0.0);
137
+ let bottom = min(anchorPositionScreen.y - clipXY.y, viewportHeight);
138
+ if (bottom - top < fastText.contentCutoffPixels.y) {
139
+ result.position = vec4<f32>(0.0);
140
+ }
141
+ }
142
+ }
143
+
144
+ return result;
145
+ }
146
+
147
+ @vertex
148
+ fn vertexMain(attributes: FastTextAttributes) -> FastTextVaryings {
149
+ let worldPosition = vec3<f32>(attributes.instancePositions, 0.0);
150
+ geometry.worldPosition = worldPosition;
151
+ geometry.uv = attributes.positions;
152
+
153
+ let glyphFrame = vec4<f32>(attributes.instanceGlyphFrames);
154
+ let glyphSize = glyphFrame.zw;
155
+ let sizePixels = clamp(
156
+ project_unit_size_to_pixel(fastText.size * fastText.sizeScale, fastText.sizeUnits),
157
+ fastText.sizeMinPixels,
158
+ fastText.sizeMaxPixels
159
+ );
160
+ let instanceScale = select(sizePixels / fastText.fontSize, 0.0, fastText.fontSize == 0.0);
161
+ var pixelOffset = vec2<f32>(attributes.instanceGlyphOffsets) + attributes.positions * glyphSize;
162
+ pixelOffset = pixelOffset * instanceScale + fastText.pixelOffset;
163
+ pixelOffset.y = -pixelOffset.y;
164
+
165
+ var clipPosition: vec4<f32>;
166
+ var anchorPositionClip: vec4<f32>;
167
+
168
+ if (fastText.billboard > 0.5) {
169
+ let projected = project_position_to_clipspace_and_commonspace(
170
+ worldPosition,
171
+ vec3<f32>(0.0),
172
+ vec3<f32>(0.0)
173
+ );
174
+ geometry.position = projected.commonPosition;
175
+ anchorPositionClip = projected.clipPosition;
176
+ clipPosition = vec4<f32>(
177
+ projected.clipPosition.xy + project_pixel_size_to_clipspace(pixelOffset),
178
+ projected.clipPosition.zw
179
+ );
180
+ } else {
181
+ var offsetCommon = vec3<f32>(project_pixel_size_vec2(pixelOffset), 0.0);
182
+ if (fastText.flipY > 0.5) {
183
+ offsetCommon.y = -offsetCommon.y;
184
+ }
185
+ let projected = project_position_to_clipspace_and_commonspace(
186
+ worldPosition,
187
+ vec3<f32>(0.0),
188
+ offsetCommon
189
+ );
190
+ geometry.position = projected.commonPosition;
191
+ anchorPositionClip = project_position_to_clipspace(
192
+ worldPosition,
193
+ vec3<f32>(0.0),
194
+ vec3<f32>(0.0)
195
+ );
196
+ clipPosition = projected.clipPosition;
197
+ }
198
+
199
+ let anchorPositionNdc = anchorPositionClip.xy / anchorPositionClip.w;
200
+ let anchorPositionScreen = vec2<f32>(
201
+ anchorPositionNdc.x + 1.0,
202
+ 1.0 - anchorPositionNdc.y
203
+ ) * 0.5 * project.viewportSize / project.devicePixelRatio;
204
+ let clipped = fast_text_clip_glyph_vertex(
205
+ pixelOffset,
206
+ anchorPositionScreen,
207
+ attributes.instanceClipRects,
208
+ clipPosition
209
+ );
210
+
211
+ var varyings: FastTextVaryings;
212
+ varyings.position = clipped.position;
213
+ varyings.color = attributes.instanceColors;
214
+ varyings.textureCoords =
215
+ (glyphFrame.xy + attributes.positions * glyphSize) / fastText.fontAtlasSize;
216
+ varyings.uv = attributes.positions;
217
+ return varyings;
218
+ }
219
+
220
+ @fragment
221
+ fn fragmentMain(varyings: FastTextVaryings) -> @location(0) vec4<f32> {
222
+ geometry.uv = varyings.uv;
223
+
224
+ var alpha = textureSample(
225
+ fontAtlasTexture,
226
+ fontAtlasTextureSampler,
227
+ varyings.textureCoords
228
+ ).a;
229
+
230
+ if (fastText.sdfEnabled > 0.5) {
231
+ alpha = smoothstep(
232
+ fastText.sdfBuffer - fastText.sdfGamma,
233
+ fastText.sdfBuffer + fastText.sdfGamma,
234
+ alpha
235
+ );
236
+ }
237
+
238
+ let outputAlpha = alpha * varyings.color.a;
239
+ if (outputAlpha < fastText.alphaCutoff) {
240
+ discard;
241
+ }
242
+
243
+ return deckgl_premultiplied_alpha(
244
+ vec4<f32>(varyings.color.rgb, outputAlpha * layer.opacity)
245
+ );
246
+ }
247
+ `;
@@ -8,6 +8,7 @@ import {LineLayer, TextLayer, type TextLayerProps} from '@deck.gl/layers';
8
8
  // import {PathStyleExtension} from '@deck.gl/extensions';
9
9
 
10
10
  import {formatTimeMs} from '../utils/format-utils';
11
+ import {FastTextLayer} from './fast-text-layer/fast-text-layer';
11
12
 
12
13
  /** Properties supported by {@link TimeDeltaLayer}. */
13
14
  export type TimeDeltaLayerProps = LayerProps & _TimeDeltaLayerProps;
@@ -92,6 +93,7 @@ export class TimeDeltaLayer extends CompositeLayer<Required<_TimeDeltaLayerProps
92
93
  const timeDeltaPosition = [(startTimeMs + endTimeMs) / 2, y - 10];
93
94
  const timeDeltaMs = Math.abs(endTimeMs - startTimeMs);
94
95
  const timeDeltaLabel = formatTimeMs(timeDeltaMs, {space: false});
96
+ const labelData = [{position: timeDeltaPosition, text: timeDeltaLabel}];
95
97
 
96
98
  const timeLines = [
97
99
  {
@@ -133,23 +135,38 @@ export class TimeDeltaLayer extends CompositeLayer<Required<_TimeDeltaLayerProps
133
135
  }),
134
136
 
135
137
  // Label
136
- new TextLayer({
137
- id: 'header-time-delta-label',
138
- data: [{position: timeDeltaPosition, text: timeDeltaLabel}],
139
- getPosition: d => d.position,
140
- getText: d => d.text,
141
- characterSet: '-0123456789.dhmsµ',
142
- getSize: fontSize,
143
- fontFamily,
144
- fontSettings,
145
- fontWeight,
146
- getColor: color,
147
- getTextAnchor: 'middle',
148
- getAlignmentBaseline: 'center',
149
- background: true,
150
- getBackgroundColor: [255 - color[0], 255 - color[1], 255 - color[2], 255],
151
- backgroundPadding: [4, 2] // Horizontal and vertical padding
152
- })
138
+ this.context?.device?.type === 'webgpu'
139
+ ? new FastTextLayer({
140
+ id: 'header-time-delta-label',
141
+ data: labelData,
142
+ getPosition: d => d.position,
143
+ getText: d => d.text,
144
+ characterSet: '-0123456789.dhmsµ',
145
+ size: fontSize,
146
+ fontFamily,
147
+ fontSettings,
148
+ fontWeight,
149
+ getColor: color,
150
+ textAnchor: 'middle',
151
+ alignmentBaseline: 'center'
152
+ })
153
+ : new TextLayer({
154
+ id: 'header-time-delta-label',
155
+ data: labelData,
156
+ getPosition: d => d.position,
157
+ getText: d => d.text,
158
+ characterSet: '-0123456789.dhmsµ',
159
+ getSize: fontSize,
160
+ fontFamily,
161
+ fontSettings,
162
+ fontWeight,
163
+ getColor: color,
164
+ getTextAnchor: 'middle',
165
+ getAlignmentBaseline: 'center',
166
+ background: true,
167
+ getBackgroundColor: [255 - color[0], 255 - color[1], 255 - color[2], 255],
168
+ backgroundPadding: [4, 2]
169
+ })
153
170
  ];
154
171
  }
155
172
  }