@deck.gl/geo-layers 9.4.0-alpha.2 → 9.4.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 (121) hide show
  1. package/dist/dist.dev.js +10452 -10051
  2. package/dist/geo-cell-layer/GeoCellLayer.d.ts.map +1 -1
  3. package/dist/geo-cell-layer/GeoCellLayer.js +2 -1
  4. package/dist/geo-cell-layer/GeoCellLayer.js.map +1 -1
  5. package/dist/index.cjs +21654 -1900
  6. package/dist/index.cjs.map +3 -4
  7. package/dist/mesh-layer/mesh-layer-uniforms.d.ts +1 -0
  8. package/dist/mesh-layer/mesh-layer-uniforms.d.ts.map +1 -1
  9. package/dist/mesh-layer/mesh-layer-uniforms.js +8 -0
  10. package/dist/mesh-layer/mesh-layer-uniforms.js.map +1 -1
  11. package/dist/mesh-layer/mesh-layer.d.ts.map +1 -1
  12. package/dist/mesh-layer/mesh-layer.js +15 -6
  13. package/dist/mesh-layer/mesh-layer.js.map +1 -1
  14. package/dist/mesh-layer/mesh-layer.wgsl.d.ts +3 -0
  15. package/dist/mesh-layer/mesh-layer.wgsl.d.ts.map +1 -0
  16. package/dist/mesh-layer/mesh-layer.wgsl.js +130 -0
  17. package/dist/mesh-layer/mesh-layer.wgsl.js.map +1 -0
  18. package/dist/mesh-layer/mesh-pbr-material.d.ts +252 -0
  19. package/dist/mesh-layer/mesh-pbr-material.d.ts.map +1 -0
  20. package/dist/mesh-layer/mesh-pbr-material.js +27 -0
  21. package/dist/mesh-layer/mesh-pbr-material.js.map +1 -0
  22. package/dist/trips-layer/trips-layer-uniforms.d.ts +1 -0
  23. package/dist/trips-layer/trips-layer-uniforms.d.ts.map +1 -1
  24. package/dist/trips-layer/trips-layer-uniforms.js +14 -3
  25. package/dist/trips-layer/trips-layer-uniforms.js.map +1 -1
  26. package/dist/trips-layer/trips-layer.d.ts +6 -1
  27. package/dist/trips-layer/trips-layer.d.ts.map +1 -1
  28. package/dist/trips-layer/trips-layer.js +57 -24
  29. package/dist/trips-layer/trips-layer.js.map +1 -1
  30. package/dist/trips-layer/trips-layer.wgsl.d.ts +11 -0
  31. package/dist/trips-layer/trips-layer.wgsl.d.ts.map +1 -0
  32. package/dist/trips-layer/trips-layer.wgsl.js +48 -0
  33. package/dist/trips-layer/trips-layer.wgsl.js.map +1 -0
  34. package/dist.min.js +1415 -149
  35. package/dist.webgl-only/a5-layer/a5-layer.js +30 -0
  36. package/dist.webgl-only/a5-layer/a5-layer.js.map +1 -0
  37. package/dist.webgl-only/geo-cell-layer/GeoCellLayer.js +57 -0
  38. package/dist.webgl-only/geo-cell-layer/GeoCellLayer.js.map +1 -0
  39. package/dist.webgl-only/geohash-layer/geohash-layer.js +24 -0
  40. package/dist.webgl-only/geohash-layer/geohash-layer.js.map +1 -0
  41. package/dist.webgl-only/geohash-layer/geohash-utils.js +54 -0
  42. package/dist.webgl-only/geohash-layer/geohash-utils.js.map +1 -0
  43. package/dist.webgl-only/great-circle-layer/great-circle-layer.js +17 -0
  44. package/dist.webgl-only/great-circle-layer/great-circle-layer.js.map +1 -0
  45. package/dist.webgl-only/h3-layers/h3-cluster-layer.js +52 -0
  46. package/dist.webgl-only/h3-layers/h3-cluster-layer.js.map +1 -0
  47. package/dist.webgl-only/h3-layers/h3-hexagon-layer.js +209 -0
  48. package/dist.webgl-only/h3-layers/h3-hexagon-layer.js.map +1 -0
  49. package/dist.webgl-only/h3-layers/h3-utils.js +60 -0
  50. package/dist.webgl-only/h3-layers/h3-utils.js.map +1 -0
  51. package/dist.webgl-only/index.cjs +23004 -0
  52. package/dist.webgl-only/index.cjs.map +6 -0
  53. package/dist.webgl-only/index.js +22 -0
  54. package/dist.webgl-only/index.js.map +1 -0
  55. package/dist.webgl-only/mesh-layer/mesh-layer-fragment.glsl.js +34 -0
  56. package/dist.webgl-only/mesh-layer/mesh-layer-fragment.glsl.js.map +1 -0
  57. package/dist.webgl-only/mesh-layer/mesh-layer-uniforms.js +19 -0
  58. package/dist.webgl-only/mesh-layer/mesh-layer-uniforms.js.map +1 -0
  59. package/dist.webgl-only/mesh-layer/mesh-layer-vertex.glsl.js +64 -0
  60. package/dist.webgl-only/mesh-layer/mesh-layer-vertex.glsl.js.map +1 -0
  61. package/dist.webgl-only/mesh-layer/mesh-layer.js +149 -0
  62. package/dist.webgl-only/mesh-layer/mesh-layer.js.map +1 -0
  63. package/dist.webgl-only/mesh-layer/mesh-layer.wgsl.js +5 -0
  64. package/dist.webgl-only/mesh-layer/mesh-layer.wgsl.js.map +1 -0
  65. package/dist.webgl-only/mesh-layer/mesh-pbr-material.js +27 -0
  66. package/dist.webgl-only/mesh-layer/mesh-pbr-material.js.map +1 -0
  67. package/dist.webgl-only/mvt-layer/coordinate-transform.js +45 -0
  68. package/dist.webgl-only/mvt-layer/coordinate-transform.js.map +1 -0
  69. package/dist.webgl-only/mvt-layer/find-index-binary.js +100 -0
  70. package/dist.webgl-only/mvt-layer/find-index-binary.js.map +1 -0
  71. package/dist.webgl-only/mvt-layer/mvt-layer.js +315 -0
  72. package/dist.webgl-only/mvt-layer/mvt-layer.js.map +1 -0
  73. package/dist.webgl-only/quadkey-layer/quadkey-layer.js +27 -0
  74. package/dist.webgl-only/quadkey-layer/quadkey-layer.js.map +1 -0
  75. package/dist.webgl-only/quadkey-layer/quadkey-utils.js +30 -0
  76. package/dist.webgl-only/quadkey-layer/quadkey-utils.js.map +1 -0
  77. package/dist.webgl-only/s2-layer/s2-geometry.js +127 -0
  78. package/dist.webgl-only/s2-layer/s2-geometry.js.map +1 -0
  79. package/dist.webgl-only/s2-layer/s2-layer.js +24 -0
  80. package/dist.webgl-only/s2-layer/s2-layer.js.map +1 -0
  81. package/dist.webgl-only/s2-layer/s2-utils.js +91 -0
  82. package/dist.webgl-only/s2-layer/s2-utils.js.map +1 -0
  83. package/dist.webgl-only/terrain-layer/terrain-layer.js +260 -0
  84. package/dist.webgl-only/terrain-layer/terrain-layer.js.map +1 -0
  85. package/dist.webgl-only/tile-3d-layer/tile-3d-layer.js +343 -0
  86. package/dist.webgl-only/tile-3d-layer/tile-3d-layer.js.map +1 -0
  87. package/dist.webgl-only/tile-layer/tile-layer.js +233 -0
  88. package/dist.webgl-only/tile-layer/tile-layer.js.map +1 -0
  89. package/dist.webgl-only/tileset-2d/index.js +7 -0
  90. package/dist.webgl-only/tileset-2d/index.js.map +1 -0
  91. package/dist.webgl-only/tileset-2d/memoize.js +45 -0
  92. package/dist.webgl-only/tileset-2d/memoize.js.map +1 -0
  93. package/dist.webgl-only/tileset-2d/tile-2d-header.js +141 -0
  94. package/dist.webgl-only/tileset-2d/tile-2d-header.js.map +1 -0
  95. package/dist.webgl-only/tileset-2d/tile-2d-traversal.js +208 -0
  96. package/dist.webgl-only/tileset-2d/tile-2d-traversal.js.map +1 -0
  97. package/dist.webgl-only/tileset-2d/tileset-2d.js +557 -0
  98. package/dist.webgl-only/tileset-2d/tileset-2d.js.map +1 -0
  99. package/dist.webgl-only/tileset-2d/types.js +5 -0
  100. package/dist.webgl-only/tileset-2d/types.js.map +1 -0
  101. package/dist.webgl-only/tileset-2d/utils.js +246 -0
  102. package/dist.webgl-only/tileset-2d/utils.js.map +1 -0
  103. package/dist.webgl-only/trips-layer/trips-layer-uniforms.js +23 -0
  104. package/dist.webgl-only/trips-layer/trips-layer-uniforms.js.map +1 -0
  105. package/dist.webgl-only/trips-layer/trips-layer.js +97 -0
  106. package/dist.webgl-only/trips-layer/trips-layer.js.map +1 -0
  107. package/dist.webgl-only/trips-layer/trips-layer.wgsl.js +3 -0
  108. package/dist.webgl-only/trips-layer/trips-layer.wgsl.js.map +1 -0
  109. package/dist.webgl-only/wms-layer/utils.js +17 -0
  110. package/dist.webgl-only/wms-layer/utils.js.map +1 -0
  111. package/dist.webgl-only/wms-layer/wms-layer.js +198 -0
  112. package/dist.webgl-only/wms-layer/wms-layer.js.map +1 -0
  113. package/package.json +12 -7
  114. package/src/geo-cell-layer/GeoCellLayer.ts +2 -0
  115. package/src/mesh-layer/mesh-layer-uniforms.ts +9 -0
  116. package/src/mesh-layer/mesh-layer.ts +15 -6
  117. package/src/mesh-layer/mesh-layer.wgsl.ts +130 -0
  118. package/src/mesh-layer/mesh-pbr-material.ts +39 -0
  119. package/src/trips-layer/trips-layer-uniforms.ts +15 -3
  120. package/src/trips-layer/trips-layer.ts +84 -38
  121. package/src/trips-layer/trips-layer.wgsl.ts +63 -0
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "deck.gl layers supporting geospatial use cases and GIS formats",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
- "version": "9.4.0-alpha.2",
6
+ "version": "9.4.0-beta.3",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -27,12 +27,17 @@
27
27
  "exports": {
28
28
  ".": {
29
29
  "types": "./dist/index.d.ts",
30
+ "visgl:webgl-only": {
31
+ "import": "./dist.webgl-only/index.js",
32
+ "require": "./dist.webgl-only/index.cjs"
33
+ },
30
34
  "import": "./dist/index.js",
31
35
  "require": "./dist/index.cjs"
32
36
  }
33
37
  },
34
38
  "files": [
35
39
  "dist",
40
+ "dist.webgl-only",
36
41
  "src",
37
42
  "dist.min.js"
38
43
  ],
@@ -50,13 +55,13 @@
50
55
  "@loaders.gl/terrain": "^4.4.3",
51
56
  "@loaders.gl/tiles": "^4.4.3",
52
57
  "@loaders.gl/wms": "^4.4.3",
53
- "@luma.gl/gltf": "^9.4.0-alpha.1",
54
- "@luma.gl/shadertools": "^9.4.0-alpha.1",
58
+ "@luma.gl/gltf": "^9.4.0-beta.4",
59
+ "@luma.gl/shadertools": "^9.4.0-beta.4",
55
60
  "@math.gl/core": "^4.1.0",
56
61
  "@math.gl/culling": "^4.1.0",
57
62
  "@math.gl/web-mercator": "^4.1.0",
58
63
  "@types/geojson": "^7946.0.8",
59
- "a5-js": "^0.7.2",
64
+ "a5-js": "^0.10.0",
60
65
  "h3-js": "^4.4.0",
61
66
  "long": "^3.2.0"
62
67
  },
@@ -66,8 +71,8 @@
66
71
  "@deck.gl/layers": "~9.3.0-beta.2",
67
72
  "@deck.gl/mesh-layers": "~9.3.0-beta.2",
68
73
  "@loaders.gl/core": "^4.4.3",
69
- "@luma.gl/core": "~9.4.0-alpha.1",
70
- "@luma.gl/engine": "~9.4.0-alpha.1"
74
+ "@luma.gl/core": "~9.4.0-beta.4",
75
+ "@luma.gl/engine": "~9.4.0-beta.4"
71
76
  },
72
- "gitHead": "546e2e8284b00949ab26e744ffd05b9aa017c802"
77
+ "gitHead": "7f1e9e63019e6525b3f804cbadcf390ed9d40b65"
73
78
  }
@@ -35,6 +35,7 @@ export default class GeoCellLayer<DataT = any, ExtraProps extends {} = {}> exten
35
35
  lineWidthScale,
36
36
  lineWidthMinPixels,
37
37
  lineWidthMaxPixels,
38
+ lineAntialiasing,
38
39
  lineJointRounded,
39
40
  lineMiterLimit,
40
41
  lineDashJustified,
@@ -63,6 +64,7 @@ export default class GeoCellLayer<DataT = any, ExtraProps extends {} = {}> exten
63
64
  lineWidthScale,
64
65
  lineWidthMinPixels,
65
66
  lineWidthMaxPixels,
67
+ lineAntialiasing,
66
68
  lineJointRounded,
67
69
  lineMiterLimit,
68
70
  lineDashJustified,
@@ -10,6 +10,14 @@ layout(std140) uniform meshUniforms {
10
10
  } mesh;
11
11
  `;
12
12
 
13
+ const source = /* wgsl */ `\
14
+ struct MeshUniforms {
15
+ pickFeatureIds: f32,
16
+ };
17
+
18
+ @group(0) @binding(auto) var<uniform> mesh: MeshUniforms;
19
+ `;
20
+
13
21
  export type MeshProps = {
14
22
  pickFeatureIds: boolean;
15
23
  };
@@ -18,6 +26,7 @@ export const meshUniforms = {
18
26
  name: 'mesh',
19
27
  vs: uniformBlock,
20
28
  fs: uniformBlock,
29
+ source,
21
30
  uniformTypes: {
22
31
  pickFeatureIds: 'f32'
23
32
  }
@@ -4,15 +4,16 @@
4
4
 
5
5
  import type {NumericArray} from '@math.gl/core';
6
6
  import {parsePBRMaterial, ParsedPBRMaterial} from '@luma.gl/gltf';
7
- import {pbrMaterial} from '@luma.gl/shadertools';
8
7
  import {Model} from '@luma.gl/engine';
9
8
  import type {MeshAttribute, MeshAttributes} from '@loaders.gl/schema';
10
9
  import type {UpdateParameters, DefaultProps, LayerContext} from '@deck.gl/core';
11
10
  import {SimpleMeshLayer, SimpleMeshLayerProps} from '@deck.gl/mesh-layers';
12
11
 
13
12
  import {MeshProps, meshUniforms} from './mesh-layer-uniforms';
13
+ import {meshPbrMaterial} from './mesh-pbr-material';
14
14
  import vs from './mesh-layer-vertex.glsl';
15
15
  import fs from './mesh-layer-fragment.glsl';
16
+ import source from './mesh-layer.wgsl';
16
17
 
17
18
  export type Mesh = {
18
19
  attributes: MeshAttributes;
@@ -62,9 +63,13 @@ export default class MeshLayer<DataT = any, ExtraProps extends {} = {}> extends
62
63
 
63
64
  getShaders() {
64
65
  const shaders = super.getShaders();
65
- const modules = shaders.modules;
66
- modules.push(pbrMaterial, meshUniforms);
67
- return {...shaders, vs, fs};
66
+ return {
67
+ ...shaders,
68
+ vs,
69
+ fs,
70
+ source,
71
+ modules: [...shaders.modules, meshPbrMaterial, meshUniforms]
72
+ };
68
73
  }
69
74
 
70
75
  initializeState() {
@@ -131,7 +136,8 @@ export default class MeshLayer<DataT = any, ExtraProps extends {} = {}> extends
131
136
  defines: {
132
137
  ...shaders.defines,
133
138
  ...parsedPBRMaterial?.defines,
134
- HAS_UV_REGIONS: mesh.attributes.uvRegions ? 1 : 0
139
+ HAS_UV_REGIONS: mesh.attributes.uvRegions ? 1 : 0,
140
+ HAS_FEATURE_IDS: this.props.featureIds ? 1 : 0
135
141
  },
136
142
  parameters: parsedPBRMaterial?.parameters,
137
143
  isInstanced: true
@@ -150,8 +156,11 @@ export default class MeshLayer<DataT = any, ExtraProps extends {} = {}> extends
150
156
 
151
157
  const {pbr_baseColorSampler} = parsedPBRMaterial.bindings;
152
158
  const {emptyTexture} = this.state;
159
+ const meshTexture = pbr_baseColorSampler || emptyTexture;
153
160
  const simpleMeshProps = {
154
- sampler: pbr_baseColorSampler || emptyTexture,
161
+ ...(this.context.device.type === 'webgpu'
162
+ ? {simpleMeshTexture: meshTexture}
163
+ : {sampler: meshTexture}),
155
164
  hasTexture: Boolean(pbr_baseColorSampler)
156
165
  };
157
166
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -0,0 +1,130 @@
1
+ // deck.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ export default /* wgsl */ `\
6
+ struct VertexInputs {
7
+ @location(0) positions: vec3<f32>,
8
+ #ifdef HAS_NORMALS
9
+ @location(1) normals: vec3<f32>,
10
+ #endif
11
+ @location(2) colors: vec4<f32>,
12
+ #ifdef HAS_UV
13
+ @location(3) texCoords: vec2<f32>,
14
+ #endif
15
+ #ifdef HAS_UV_REGIONS
16
+ @location(4) uvRegions: vec4<f32>,
17
+ #endif
18
+ #ifdef HAS_FEATURE_IDS
19
+ @location(5) rowIndexes: u32,
20
+ #endif
21
+ @location(6) instanceColors: vec4<f32>,
22
+ @location(7) instanceModelMatrixCol0: vec3<f32>,
23
+ @location(8) instanceModelMatrixCol1: vec3<f32>,
24
+ @location(9) instanceModelMatrixCol2: vec3<f32>,
25
+ };
26
+
27
+ struct FragmentInputs {
28
+ @builtin(position) position: vec4<f32>,
29
+ @location(0) color: vec4<f32>,
30
+ @location(1) texCoord: vec2<f32>,
31
+ @location(2) pbrPosition: vec3<f32>,
32
+ @location(3) pbrNormal: vec3<f32>,
33
+ @location(4) pickingColor: vec3<f32>,
34
+ };
35
+
36
+ fn applyUVRegion(uv: vec2<f32>, uvRegion: vec4<f32>) -> vec2<f32> {
37
+ #ifdef HAS_UV_REGIONS
38
+ // https://github.com/Esri/i3s-spec/blob/master/docs/1.7/geometryUVRegion.cmn.md
39
+ return fract(uv) * (uvRegion.zw - uvRegion.xy) + uvRegion.xy;
40
+ #else
41
+ return uv;
42
+ #endif
43
+ }
44
+
45
+ @vertex
46
+ fn vertexMain(
47
+ inputs: VertexInputs,
48
+ @builtin(instance_index) instanceIndex: u32
49
+ ) -> FragmentInputs {
50
+ var outputs: FragmentInputs;
51
+ var texCoord = vec2<f32>(0.0);
52
+ var normal = vec3<f32>(0.0, 0.0, 1.0);
53
+ var uvRegion = vec4<f32>(0.0);
54
+
55
+ #ifdef HAS_UV
56
+ texCoord = inputs.texCoords;
57
+ #endif
58
+ #ifdef HAS_NORMALS
59
+ normal = inputs.normals;
60
+ #endif
61
+ #ifdef HAS_UV_REGIONS
62
+ uvRegion = inputs.uvRegions;
63
+ #endif
64
+
65
+ texCoord = applyUVRegion(texCoord, uvRegion);
66
+ geometry.uv = texCoord;
67
+ #ifdef HAS_FEATURE_IDS
68
+ geometry.pickingColor = picking_getPickingColorFromIndex(inputs.rowIndexes);
69
+ #else
70
+ geometry.pickingColor = picking_getPickingColorFromIndex(instanceIndex);
71
+ #endif
72
+
73
+ let instanceModelMatrix = mat3x3<f32>(
74
+ inputs.instanceModelMatrixCol0,
75
+ inputs.instanceModelMatrixCol1,
76
+ inputs.instanceModelMatrixCol2
77
+ );
78
+ let commonPosition = vec4<f32>(project_position_vec3_f32(inputs.positions), 1.0);
79
+
80
+ geometry.position = commonPosition;
81
+ geometry.normal = project_normal(instanceModelMatrix * normal);
82
+
83
+ outputs.position = project_common_position_to_clipspace(commonPosition);
84
+ outputs.color = vec4<f32>(
85
+ inputs.colors.rgb * inputs.instanceColors.rgb,
86
+ inputs.instanceColors.a
87
+ );
88
+ outputs.texCoord = texCoord;
89
+ outputs.pbrPosition = commonPosition.xyz;
90
+ outputs.pbrNormal = geometry.normal;
91
+ outputs.pickingColor = geometry.pickingColor;
92
+ return outputs;
93
+ }
94
+
95
+ @fragment
96
+ fn fragmentMain(inputs: FragmentInputs) -> @location(0) vec4<f32> {
97
+ fragmentGeometry.uv = inputs.texCoord;
98
+
99
+ if (picking.isActive > 0.5) {
100
+ if (!picking_isColorValid(inputs.pickingColor)) {
101
+ discard;
102
+ }
103
+ return vec4<f32>(inputs.pickingColor, 1.0);
104
+ }
105
+
106
+ fragmentInputs.pbr_vPosition = inputs.pbrPosition;
107
+ fragmentInputs.pbr_vUV0 = inputs.texCoord;
108
+ fragmentInputs.pbr_vUV1 = vec2<f32>(0.0);
109
+ fragmentInputs.pbr_vNormal = inputs.pbrNormal;
110
+
111
+ var color = inputs.color * pbr_filterColor(vec4<f32>(0.0));
112
+ color.a *= layer.opacity;
113
+
114
+ if (picking.isHighlightActive > 0.5) {
115
+ let highlightedObjectColor = picking_normalizeColor(picking.highlightedObjectColor);
116
+ if (picking_isColorZero(abs(inputs.pickingColor - highlightedObjectColor))) {
117
+ let highlightAlpha = picking.highlightColor.a;
118
+ let blendedAlpha = highlightAlpha + color.a * (1.0 - highlightAlpha);
119
+ if (blendedAlpha > 0.0) {
120
+ color = vec4<f32>(
121
+ mix(color.rgb, picking.highlightColor.rgb, highlightAlpha / blendedAlpha),
122
+ blendedAlpha
123
+ );
124
+ }
125
+ }
126
+ }
127
+
128
+ return deckgl_premultiplied_alpha(color);
129
+ }
130
+ `;
@@ -0,0 +1,39 @@
1
+ // deck.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {pbrMaterial} from '@luma.gl/shadertools';
6
+
7
+ import type {
8
+ PBRMaterialBindings,
9
+ PBRMaterialProps,
10
+ PBRMaterialUniforms,
11
+ ShaderModule
12
+ } from '@luma.gl/shadertools';
13
+
14
+ // The stock PBR module still uses the pre-indexed UV field name in one helper and owns a
15
+ // separate camera uniform. Align it with the current PBR input struct and deck.gl's project
16
+ // module until these compatibility fixes can be made in luma.gl itself.
17
+ const source = (pbrMaterial.source as string)
18
+ .replace(
19
+ /fn pbr_setPositionNormalTangentUV\([\s\S]*?\n}\n/,
20
+ `fn pbr_setPositionNormalTangentUV(position: vec4f, normal: vec4f, tangent: vec4f, uv: vec2f)
21
+ {
22
+ fragmentInputs.pbr_vPosition = position.xyz;
23
+ fragmentInputs.pbr_vNormal = normal.xyz;
24
+ fragmentInputs.pbr_vTBN = mat3x3f(
25
+ vec3f(1.0, 0.0, 0.0),
26
+ vec3f(0.0, 1.0, 0.0),
27
+ vec3f(0.0, 0.0, 1.0)
28
+ );
29
+ fragmentInputs.pbr_vUV0 = uv;
30
+ fragmentInputs.pbr_vUV1 = uv;
31
+ }
32
+ `
33
+ )
34
+ .replace(/pbrProjection\.camera/g, 'project.cameraPosition');
35
+
36
+ export const meshPbrMaterial = {
37
+ ...pbrMaterial,
38
+ source
39
+ } as const satisfies ShaderModule<PBRMaterialProps, PBRMaterialUniforms, PBRMaterialBindings>;
@@ -4,7 +4,18 @@
4
4
 
5
5
  import type {ShaderModule} from '@luma.gl/shadertools';
6
6
 
7
- const uniformBlock = `\
7
+ const uniformBlockWGSL = /* wgsl */ `\
8
+ struct TripsUniforms {
9
+ fadeTrail: f32,
10
+ trailLength: f32,
11
+ currentTime: f32,
12
+ };
13
+
14
+ @group(0) @binding(auto)
15
+ var<uniform> trips: TripsUniforms;
16
+ `;
17
+
18
+ const uniformBlockGLSL = `\
8
19
  layout(std140) uniform tripsUniforms {
9
20
  bool fadeTrail;
10
21
  float trailLength;
@@ -20,8 +31,9 @@ export type TripsProps = {
20
31
 
21
32
  export const tripsUniforms = {
22
33
  name: 'trips',
23
- vs: uniformBlock,
24
- fs: uniformBlock,
34
+ source: uniformBlockWGSL,
35
+ vs: uniformBlockGLSL,
36
+ fs: uniformBlockGLSL,
25
37
  uniformTypes: {
26
38
  fadeTrail: 'f32',
27
39
  trailLength: 'f32',
@@ -3,10 +3,12 @@
3
3
  // Copyright (c) vis.gl contributors
4
4
 
5
5
  import type {NumericArray} from '@math.gl/core';
6
- import {AccessorFunction, DefaultProps} from '@deck.gl/core';
6
+ import {createIterable} from '@deck.gl/core';
7
+ import type {AccessorFunction, Attribute, DefaultProps} from '@deck.gl/core';
7
8
  import {PathLayer, PathLayerProps} from '@deck.gl/layers';
8
9
 
9
10
  import {tripsUniforms, TripsProps} from './trips-layer-uniforms';
11
+ import {packTripTimestamps, tripsShaderInjectionsWGSL} from './trips-layer.wgsl';
10
12
 
11
13
  const defaultProps: DefaultProps<TripsLayerProps> = {
12
14
  fadeTrail: true,
@@ -15,6 +17,31 @@ const defaultProps: DefaultProps<TripsLayerProps> = {
15
17
  getTimestamps: {type: 'accessor', value: (d: any) => d.timestamps}
16
18
  };
17
19
 
20
+ const tripsShaderInjectionsGLSL = {
21
+ 'vs:#decl': `\
22
+ in float instanceTimestamps;
23
+ in float instanceNextTimestamps;
24
+ out float vTime;
25
+ `,
26
+ // Timestamp of the vertex
27
+ 'vs:#main-end': `\
28
+ vTime = instanceTimestamps + (instanceNextTimestamps - instanceTimestamps) * vPathPosition.y / vPathLength;
29
+ `,
30
+ 'fs:#decl': `\
31
+ in float vTime;
32
+ `,
33
+ // Drop segments only after PathLayer evaluates analytic-coverage derivatives, then
34
+ // fade the color (currentTime - 100%, end of trail - 0%).
35
+ 'fs:DECKGL_FILTER_COLOR': `\
36
+ if(vTime > trips.currentTime || (trips.fadeTrail && (vTime < trips.currentTime - trips.trailLength))) {
37
+ discard;
38
+ }
39
+ if(trips.fadeTrail) {
40
+ color.a *= 1.0 - (trips.currentTime - vTime) / trips.trailLength;
41
+ }
42
+ `
43
+ } as const;
44
+
18
45
  /** All properties supported by TripsLayer. */
19
46
  export type TripsLayerProps<DataT = unknown> = _TripsLayerProps<DataT> & PathLayerProps<DataT>;
20
47
 
@@ -51,32 +78,8 @@ export default class TripsLayer<DataT = any, ExtraProps extends {} = {}> extends
51
78
 
52
79
  getShaders() {
53
80
  const shaders = super.getShaders();
54
- shaders.inject = {
55
- 'vs:#decl': `\
56
- in float instanceTimestamps;
57
- in float instanceNextTimestamps;
58
- out float vTime;
59
- `,
60
- // Timestamp of the vertex
61
- 'vs:#main-end': `\
62
- vTime = instanceTimestamps + (instanceNextTimestamps - instanceTimestamps) * vPathPosition.y / vPathLength;
63
- `,
64
- 'fs:#decl': `\
65
- in float vTime;
66
- `,
67
- // Drop the segments outside of the time window
68
- 'fs:#main-start': `\
69
- if(vTime > trips.currentTime || (trips.fadeTrail && (vTime < trips.currentTime - trips.trailLength))) {
70
- discard;
71
- }
72
- `,
73
- // Fade the color (currentTime - 100%, end of trail - 0%)
74
- 'fs:DECKGL_FILTER_COLOR': `\
75
- if(trips.fadeTrail) {
76
- color.a *= 1.0 - (trips.currentTime - vTime) / trips.trailLength;
77
- }
78
- `
79
- };
81
+ shaders.inject =
82
+ this.context.device.type === 'webgpu' ? tripsShaderInjectionsWGSL : tripsShaderInjectionsGLSL;
80
83
  shaders.modules = [...shaders.modules, tripsUniforms];
81
84
  return shaders;
82
85
  }
@@ -86,21 +89,64 @@ if(trips.fadeTrail) {
86
89
 
87
90
  const attributeManager = this.getAttributeManager();
88
91
  attributeManager!.addInstanced({
89
- timestamps: {
90
- size: 1,
91
- accessor: 'getTimestamps',
92
- shaderAttributes: {
93
- instanceTimestamps: {
94
- vertexOffset: 0
95
- },
96
- instanceNextTimestamps: {
97
- vertexOffset: 1
92
+ ...(this.context.device.type === 'webgpu'
93
+ ? {
94
+ instanceTimestamps: {
95
+ size: 2,
96
+ accessor: 'getTimestamps',
97
+ // eslint-disable-next-line @typescript-eslint/unbound-method
98
+ update: this.calculateWebGPUTimestamps,
99
+ bufferGroup: 'path-instance-data'
100
+ }
98
101
  }
99
- }
100
- }
102
+ : {
103
+ timestamps: {
104
+ size: 1,
105
+ accessor: 'getTimestamps',
106
+ shaderAttributes: {
107
+ instanceTimestamps: {
108
+ vertexOffset: 0
109
+ },
110
+ instanceNextTimestamps: {
111
+ vertexOffset: 1
112
+ }
113
+ }
114
+ }
115
+ })
101
116
  });
102
117
  }
103
118
 
119
+ /** Materialize timestamps in the same per-path instance layout as the path tessellator. */
120
+ protected calculateWebGPUTimestamps(
121
+ attribute: Attribute,
122
+ {data, props}: {data: TripsLayerProps<DataT>['data']; props: TripsLayerProps<DataT>}
123
+ ): void {
124
+ const {pathTesselator} = this.state;
125
+ const {instanceCount, vertexStarts} = pathTesselator;
126
+ const packedTimestamps = new Float32Array(instanceCount * 2);
127
+ const {iterable, objectInfo} = createIterable(data);
128
+
129
+ for (const object of iterable) {
130
+ objectInfo.index++;
131
+
132
+ const vertexStart = vertexStarts[objectInfo.index];
133
+ const vertexEnd = vertexStarts[objectInfo.index + 1] ?? instanceCount;
134
+
135
+ if (vertexEnd <= vertexStart) {
136
+ continue;
137
+ }
138
+
139
+ const timestamps = props.getTimestamps?.(object, objectInfo) ?? [];
140
+ packedTimestamps.set(
141
+ packTripTimestamps(timestamps, vertexEnd - vertexStart, props._pathType === 'loop'),
142
+ vertexStart * 2
143
+ );
144
+ }
145
+
146
+ attribute.startIndices = vertexStarts;
147
+ attribute.value = packedTimestamps;
148
+ }
149
+
104
150
  draw(params) {
105
151
  const {fadeTrail, trailLength, currentTime} = this.props;
106
152
  const tripsProps: TripsProps = {fadeTrail, trailLength, currentTime};
@@ -0,0 +1,63 @@
1
+ // deck.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import type {NumericArray} from '@math.gl/core';
6
+
7
+ /** Pack timestamps in the same padded instance order used by PathTesselator. */
8
+ export function packTripTimestamps(
9
+ timestamps: NumericArray,
10
+ instanceCount: number = timestamps.length,
11
+ isLoop: boolean = false
12
+ ): Float32Array {
13
+ const packedTimestamps = new Float32Array(instanceCount * 2);
14
+
15
+ if (timestamps.length === 0) {
16
+ return packedTimestamps;
17
+ }
18
+
19
+ const isClosed = instanceCount > timestamps.length;
20
+ const cycleLength = isLoop ? timestamps.length : Math.max(timestamps.length - 1, 1);
21
+
22
+ for (let index = 0; index < instanceCount; index++) {
23
+ const timestampIndex = isClosed ? index % cycleLength : Math.min(index, timestamps.length - 1);
24
+ const nextTimestampIndex = isClosed
25
+ ? (timestampIndex + 1) % cycleLength
26
+ : Math.min(timestampIndex + 1, timestamps.length - 1);
27
+
28
+ packedTimestamps[index * 2] = timestamps[timestampIndex];
29
+ packedTimestamps[index * 2 + 1] = timestamps[nextTimestampIndex];
30
+ }
31
+
32
+ return packedTimestamps;
33
+ }
34
+
35
+ /** Extend PathLayer's WGSL without duplicating its path geometry or changing its GLSL hooks. */
36
+ export const tripsShaderInjectionsWGSL = {
37
+ ' @location(12) rowIndexes: u32,': /* wgsl */ `
38
+ @location(13) instanceTimestamps: vec2<f32>,`,
39
+
40
+ ' @location(5) vJointType: f32,': /* wgsl */ `
41
+ @location(6) vTime: f32,`,
42
+
43
+ ' attributes.instanceColors.a * layer.opacity\n );': /* wgsl */ `
44
+
45
+ varyings.vTime = mix(
46
+ attributes.instanceTimestamps.x,
47
+ attributes.instanceTimestamps.y,
48
+ varyings.vPathPosition.y / varyings.vPathLength
49
+ );
50
+
51
+ if (trips.fadeTrail > 0.5) {
52
+ varyings.vColor.a *=
53
+ 1.0 - (trips.currentTime - varyings.vTime) / trips.trailLength;
54
+ }`,
55
+
56
+ ' // DECKGL_FILTER_COLOR': /* wgsl */ `
57
+ if (
58
+ varyings.vTime > trips.currentTime ||
59
+ (trips.fadeTrail > 0.5 && varyings.vTime < trips.currentTime - trips.trailLength)
60
+ ) {
61
+ discard;
62
+ }`
63
+ } as const;