@deck.gl-community/layers 9.2.8 → 9.3.1-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -25,13 +25,13 @@ var __publicField = (obj, key, value) => {
25
25
  var dist_exports = {};
26
26
  __export(dist_exports, {
27
27
  PathMarkerLayer: () => PathMarkerLayer,
28
- PathOutlineLayer: () => PathOutlineLayer
28
+ PathOutlineLayer: () => PathOutlineLayer,
29
+ SkyboxLayer: () => SkyboxLayer
29
30
  });
30
31
  module.exports = __toCommonJS(dist_exports);
31
32
 
32
33
  // dist/path-outline-layer/path-outline-layer.js
33
34
  var import_layers = require("@deck.gl/layers");
34
- var import_constants = require("@luma.gl/constants");
35
35
 
36
36
  // dist/path-outline-layer/outline.js
37
37
  var INITIAL_STATE = {
@@ -81,8 +81,6 @@ in float outline_vzLevel;
81
81
  // in vec2 outline_vUV;
82
82
  in vec4 outline_vPosition;
83
83
 
84
- out vec4 fragColor;
85
-
86
84
  const float OUTLINE_Z_LEVEL_ERROR = 0.01;
87
85
 
88
86
  // Return a darker color in shadowmap
@@ -95,12 +93,12 @@ vec4 outline_filterDarkenColor(vec4 color) {
95
93
  if (outline_uEnabled) {
96
94
  float maxZLevel;
97
95
  if (outline_vPosition.q > 0.0) {
98
- maxZLevel = texture2DProj(outline_uShadowmap, outline_vPosition).r * 255.;
96
+ maxZLevel = textureProj(outline_uShadowmap, outline_vPosition).r * 255.;
99
97
  } else {
100
98
  discard;
101
99
  }
102
100
  if (maxZLevel < outline_vzLevel + OUTLINE_Z_LEVEL_ERROR) {
103
- vec4(color.rgb * 0.5, color.a);
101
+ return vec4(color.rgb * 0.5, color.a);
104
102
  } else {
105
103
  discard;
106
104
  }
@@ -175,25 +173,54 @@ var PathOutlineLayer = class extends import_layers.PathLayer {
175
173
  // @ts-expect-error PathLayer is missing LayerContext arg
176
174
  initializeState(context) {
177
175
  super.initializeState();
176
+ const attributeManager = this.getAttributeManager();
177
+ if (!attributeManager) {
178
+ throw new Error("PathOutlineLayer requires an attribute manager during initialization.");
179
+ }
178
180
  const outlineFramebuffer = context.device.createFramebuffer({
179
- colorAttachments: ["rgba8unorm"]
181
+ colorAttachments: [
182
+ context.device.createTexture({
183
+ format: "rgba8unorm",
184
+ width: 1,
185
+ height: 1,
186
+ mipLevels: 1
187
+ })
188
+ ]
180
189
  });
181
- this.setState({
182
- outlineFramebuffer
183
- });
184
- this.state.attributeManager.addInstanced({
190
+ attributeManager.addInstanced({
185
191
  instanceZLevel: {
186
192
  size: 1,
187
- type: 5121,
193
+ type: "uint8",
188
194
  accessor: "getZLevel"
189
195
  }
190
196
  });
197
+ this.setState({
198
+ outlineFramebuffer,
199
+ model: this._getModel()
200
+ });
191
201
  }
192
- // Override draw to add render module
193
- draw({ moduleParameters = {}, parameters, uniforms, context }) {
202
+ finalizeState(context) {
194
203
  var _a;
204
+ (_a = this.state.outlineFramebuffer) == null ? void 0 : _a.destroy();
205
+ super.finalizeState(context);
206
+ }
207
+ // Override draw to add render module
208
+ draw() {
209
+ const model = this.state.model;
210
+ const outlineFramebuffer = this.state.outlineFramebuffer;
211
+ if (!model || !outlineFramebuffer) {
212
+ return;
213
+ }
214
+ const viewport = this.context.viewport;
215
+ const viewportWidth = Math.max(1, Math.ceil(viewport.width));
216
+ const viewportHeight = Math.max(1, Math.ceil(viewport.height));
217
+ outlineFramebuffer.resize({ width: viewportWidth, height: viewportHeight });
218
+ const shadowmapTexture = getFramebufferTexture(outlineFramebuffer);
219
+ if (!shadowmapTexture) {
220
+ return;
221
+ }
195
222
  const { jointRounded, capRounded, billboard, miterLimit, widthUnits, widthScale, widthMinPixels, widthMaxPixels } = this.props;
196
- uniforms = Object.assign({}, uniforms, {
223
+ const basePathProps = {
197
224
  jointType: Number(jointRounded),
198
225
  capType: Number(capRounded),
199
226
  billboard,
@@ -202,49 +229,55 @@ var PathOutlineLayer = class extends import_layers.PathLayer {
202
229
  miterLimit,
203
230
  widthMinPixels,
204
231
  widthMaxPixels
232
+ };
233
+ this.setShaderModuleProps({
234
+ outline: {
235
+ outlineEnabled: true,
236
+ outlineRenderShadowmap: true,
237
+ outlineShadowmap: shadowmapTexture
238
+ }
205
239
  });
206
- const { outlineFramebuffer } = this.state;
207
- if (context == null ? void 0 : context.viewport) {
208
- const viewportWidth = Math.max(1, Math.ceil(context.viewport.width));
209
- const viewportHeight = Math.max(1, Math.ceil(context.viewport.height));
210
- outlineFramebuffer.resize({ width: viewportWidth, height: viewportHeight });
211
- } else {
212
- outlineFramebuffer.resize();
213
- }
214
- const shadowmapTexture = (_a = outlineFramebuffer.colorAttachments[0]) == null ? void 0 : _a.texture;
215
- if (!shadowmapTexture) {
216
- return;
217
- }
218
- this.state.model.updateModuleSettings({
219
- outlineEnabled: true,
220
- outlineRenderShadowmap: true,
221
- outlineShadowmap: shadowmapTexture
222
- });
223
- this.state.model.draw({
224
- uniforms: Object.assign({}, uniforms, {
240
+ model.shaderInputs.setProps({
241
+ path: {
242
+ ...basePathProps,
225
243
  jointType: 0,
226
- widthScale: this.props.widthScale * 1.3
227
- }),
228
- parameters: OUTLINE_SHADOWMAP_PARAMETERS,
229
- framebuffer: outlineFramebuffer
244
+ widthScale: widthScale * 1.3
245
+ }
230
246
  });
231
- this.state.model.updateModuleSettings({
232
- outlineEnabled: true,
233
- outlineRenderShadowmap: false,
234
- outlineShadowmap: shadowmapTexture
247
+ model.setParameters(OUTLINE_SHADOWMAP_PARAMETERS);
248
+ const shadowRenderPass = this.context.device.beginRenderPass({
249
+ id: `${this.props.id}-outline-shadowmap`,
250
+ framebuffer: outlineFramebuffer,
251
+ parameters: { viewport: [0, 0, viewportWidth, viewportHeight] },
252
+ clearColor: [0, 0, 0, 0],
253
+ clearDepth: 1,
254
+ clearStencil: 0
235
255
  });
236
- this.state.model.draw({
237
- uniforms: Object.assign({}, uniforms, {
238
- jointType: Number(jointRounded),
239
- capType: Number(capRounded),
240
- widthScale: this.props.widthScale
241
- }),
242
- parameters: OUTLINE_RENDER_PARAMETERS
256
+ model.draw(shadowRenderPass);
257
+ shadowRenderPass.end();
258
+ this.setShaderModuleProps({
259
+ outline: {
260
+ outlineEnabled: true,
261
+ outlineRenderShadowmap: false,
262
+ outlineShadowmap: shadowmapTexture
263
+ }
243
264
  });
265
+ model.shaderInputs.setProps({
266
+ path: basePathProps
267
+ });
268
+ model.setParameters(OUTLINE_RENDER_PARAMETERS);
269
+ model.draw(this.context.renderPass);
244
270
  }
245
271
  };
246
272
  __publicField(PathOutlineLayer, "layerName", "PathOutlineLayer");
247
273
  __publicField(PathOutlineLayer, "defaultProps", defaultProps);
274
+ function getFramebufferTexture(framebuffer) {
275
+ const colorAttachment = framebuffer.colorAttachments[0];
276
+ if (!colorAttachment) {
277
+ return null;
278
+ }
279
+ return "texture" in colorAttachment ? colorAttachment.texture : colorAttachment;
280
+ }
248
281
 
249
282
  // dist/path-marker-layer/path-marker-layer.js
250
283
  var import_core3 = require("@deck.gl/core");
@@ -526,4 +559,306 @@ var PathMarkerLayer = class extends import_core3.CompositeLayer {
526
559
  };
527
560
  __publicField(PathMarkerLayer, "layerName", "PathMarkerLayer");
528
561
  __publicField(PathMarkerLayer, "defaultProps", defaultProps2);
562
+
563
+ // dist/skybox-layer/skybox-layer.js
564
+ var import_core4 = require("@loaders.gl/core");
565
+ var import_textures = require("@loaders.gl/textures");
566
+ var import_core5 = require("@deck.gl/core");
567
+ var import_core6 = require("@math.gl/core");
568
+ var import_engine2 = require("@luma.gl/engine");
569
+
570
+ // dist/skybox-layer/cubemap-utils.js
571
+ var CUBE_FACES = ["+X", "-X", "+Y", "-Y", "+Z", "-Z"];
572
+ function createCubemapLoadOptions(cubemap, loadOptions) {
573
+ var _a;
574
+ if (!loadOptions) {
575
+ return void 0;
576
+ }
577
+ if (typeof cubemap === "string" || ((_a = loadOptions.core) == null ? void 0 : _a.baseUrl) || !loadOptions.baseUrl) {
578
+ return loadOptions;
579
+ }
580
+ return {
581
+ ...loadOptions,
582
+ core: {
583
+ ...loadOptions.core,
584
+ baseUrl: loadOptions.baseUrl
585
+ }
586
+ };
587
+ }
588
+ function convertLoadedCubemapToTextureData(texture) {
589
+ if (texture.type !== "cube" || !Array.isArray(texture.data) || texture.data.length !== 6) {
590
+ throw new Error("SkyboxLayer expected a cubemap texture with six faces.");
591
+ }
592
+ return Object.fromEntries(CUBE_FACES.map((face, index) => [face, normalizeTextureSlice(texture.data[index], face)]));
593
+ }
594
+ function normalizeTextureSlice(faceData, face) {
595
+ if (Array.isArray(faceData)) {
596
+ if (faceData.length === 0) {
597
+ throw new Error(`SkyboxLayer received an empty mip chain for face ${face}.`);
598
+ }
599
+ return faceData.map((level, mipLevel) => normalizeTextureLevel(level, face, mipLevel));
600
+ }
601
+ return normalizeTextureLevel(faceData, face, 0);
602
+ }
603
+ function normalizeTextureLevel(faceData, face, mipLevel) {
604
+ if (typeof ImageBitmap !== "undefined" && faceData instanceof ImageBitmap) {
605
+ return faceData;
606
+ }
607
+ const level = faceData;
608
+ if (level == null ? void 0 : level.imageBitmap) {
609
+ return level.imageBitmap;
610
+ }
611
+ if (level && ArrayBuffer.isView(level.data) && level.width && level.height) {
612
+ return {
613
+ data: level.data,
614
+ width: level.width,
615
+ height: level.height,
616
+ format: typeof level.textureFormat === "string" ? level.textureFormat : typeof level.format === "string" ? level.format : "rgba8unorm"
617
+ };
618
+ }
619
+ throw new Error(`SkyboxLayer could not normalize cubemap face ${face} mip ${mipLevel}.`);
620
+ }
621
+
622
+ // dist/skybox-layer/skybox-layer.js
623
+ var app = {
624
+ name: "app",
625
+ uniformTypes: {
626
+ modelMatrix: "mat4x4<f32>",
627
+ viewMatrix: "mat4x4<f32>",
628
+ projectionMatrix: "mat4x4<f32>"
629
+ }
630
+ };
631
+ var SKYBOX_PARAMETERS = {
632
+ cullMode: "front",
633
+ depthWriteEnabled: false,
634
+ depthCompare: "less-equal"
635
+ };
636
+ var SKYBOX_SCALE = new import_core6.Matrix4().scale([2, 2, 2]);
637
+ var defaultProps3 = {
638
+ cubemap: null,
639
+ loadOptions: null,
640
+ orientation: "default"
641
+ };
642
+ var SkyboxLayer = class extends import_core5.Layer {
643
+ state = void 0;
644
+ /** Initializes the cube model and starts loading the cubemap texture. */
645
+ initializeState() {
646
+ const attributeManager = this.getAttributeManager();
647
+ attributeManager == null ? void 0 : attributeManager.remove(["instancePickingColors"]);
648
+ const shaderInputs = new import_engine2.ShaderInputs(createShaderInputModules(this.context.defaultShaderModules), {
649
+ disableWarnings: true
650
+ });
651
+ const model = this._getModel(shaderInputs);
652
+ this.setState({
653
+ cubemapTexture: null,
654
+ loadCount: 0,
655
+ model,
656
+ shaderInputs
657
+ });
658
+ this._loadCubemap().catch(() => {
659
+ });
660
+ }
661
+ /** Reloads the cubemap when its source manifest or load options change. */
662
+ updateState({ props, oldProps }) {
663
+ if (props.cubemap !== oldProps.cubemap || props.loadOptions !== oldProps.loadOptions) {
664
+ this._loadCubemap().catch(() => {
665
+ });
666
+ }
667
+ }
668
+ /** Releases GPU resources owned by the layer. */
669
+ finalizeState() {
670
+ var _a, _b;
671
+ (_a = this.state.cubemapTexture) == null ? void 0 : _a.destroy();
672
+ (_b = this.state.model) == null ? void 0 : _b.destroy();
673
+ }
674
+ /** Draws the skybox cube for the current viewport. */
675
+ draw() {
676
+ const { model, cubemapTexture, shaderInputs } = this.state;
677
+ if (!model || !cubemapTexture || !shaderInputs) {
678
+ return;
679
+ }
680
+ const viewport = this.context.viewport;
681
+ shaderInputs.setProps({
682
+ app: {
683
+ modelMatrix: getSkyboxModelMatrix(this.props.orientation),
684
+ viewMatrix: getSkyboxViewMatrix(viewport),
685
+ projectionMatrix: viewport.projectionMatrix
686
+ }
687
+ });
688
+ model.draw(this.context.renderPass);
689
+ }
690
+ /** Creates the luma.gl model used to render the skybox cube. */
691
+ _getModel(shaderInputs) {
692
+ var _a;
693
+ return new import_engine2.Model(this.context.device, {
694
+ ...this.getShaders(),
695
+ id: this.props.id,
696
+ bufferLayout: ((_a = this.getAttributeManager()) == null ? void 0 : _a.getBufferLayouts()) || [],
697
+ geometry: new import_engine2.CubeGeometry({ indices: true }),
698
+ shaderInputs,
699
+ isInstanced: false,
700
+ parameters: SKYBOX_PARAMETERS
701
+ });
702
+ }
703
+ /** Returns the WGSL/GLSL shader pair used by the layer. */
704
+ getShaders() {
705
+ return {
706
+ source: SKYBOX_WGSL,
707
+ vs: SKYBOX_VS,
708
+ fs: SKYBOX_FS
709
+ };
710
+ }
711
+ /** Starts an asynchronous cubemap load for the current props. */
712
+ async _loadCubemap() {
713
+ const { cubemap, loadOptions } = this.props;
714
+ const nextLoadCount = this.state.loadCount + 1;
715
+ this.setState({ loadCount: nextLoadCount });
716
+ if (!cubemap) {
717
+ this._setCubemapTexture(null);
718
+ return;
719
+ }
720
+ try {
721
+ const loadedTexture = await loadCubemapSource(cubemap, loadOptions);
722
+ if (this.state.loadCount !== nextLoadCount || !this.state.model) {
723
+ return;
724
+ }
725
+ const cubemapData = convertLoadedCubemapToTextureData(loadedTexture);
726
+ this._setCubemapTexture(createCubemapTexture(this.context.device, cubemapData));
727
+ } catch (error) {
728
+ if (this.state.loadCount === nextLoadCount) {
729
+ this.raiseError(error, "SkyboxLayer failed to load cubemap");
730
+ }
731
+ }
732
+ }
733
+ /** Swaps the active GPU cubemap texture and updates model bindings. */
734
+ _setCubemapTexture(texture) {
735
+ const { cubemapTexture, model } = this.state;
736
+ if (cubemapTexture === texture) {
737
+ return;
738
+ }
739
+ cubemapTexture == null ? void 0 : cubemapTexture.destroy();
740
+ this.setState({ cubemapTexture: texture });
741
+ if (texture && model) {
742
+ model.setBindings({ cubeTexture: texture });
743
+ }
744
+ this.setNeedsRedraw();
745
+ }
746
+ };
747
+ __publicField(SkyboxLayer, "defaultProps", defaultProps3);
748
+ __publicField(SkyboxLayer, "layerName", "SkyboxLayer");
749
+ async function loadCubemapSource(cubemap, loadOptions) {
750
+ const normalizedLoadOptions = createCubemapLoadOptions(cubemap, loadOptions);
751
+ if (typeof cubemap === "string") {
752
+ return await (0, import_core4.load)(cubemap, import_textures.TextureCubeLoader, normalizedLoadOptions);
753
+ }
754
+ return await import_textures.TextureCubeLoader.parseText(JSON.stringify(cubemap), normalizedLoadOptions);
755
+ }
756
+ function createCubemapTexture(device, data) {
757
+ return new import_engine2.DynamicTexture(device, {
758
+ dimension: "cube",
759
+ data,
760
+ mipmaps: true,
761
+ sampler: {
762
+ addressModeU: "clamp-to-edge",
763
+ addressModeV: "clamp-to-edge",
764
+ addressModeW: "clamp-to-edge",
765
+ magFilter: "linear",
766
+ minFilter: "linear",
767
+ mipmapFilter: "linear"
768
+ }
769
+ });
770
+ }
771
+ function getSkyboxViewMatrix(viewport) {
772
+ const viewMatrix = new import_core6.Matrix4(viewport.viewMatrixUncentered || viewport.viewMatrix);
773
+ viewMatrix[12] = 0;
774
+ viewMatrix[13] = 0;
775
+ viewMatrix[14] = 0;
776
+ return viewMatrix;
777
+ }
778
+ function getSkyboxModelMatrix(orientation = "default") {
779
+ if (orientation === "y-up") {
780
+ return new import_core6.Matrix4().rotateX(Math.PI / 2).scale([2, 2, 2]);
781
+ }
782
+ return new import_core6.Matrix4(SKYBOX_SCALE);
783
+ }
784
+ function createShaderInputModules(defaultShaderModules) {
785
+ return Object.fromEntries([app, ...defaultShaderModules].map((module2) => [module2.name, module2]));
786
+ }
787
+ var SKYBOX_WGSL = (
788
+ /* wgsl */
789
+ `
790
+ struct appUniforms {
791
+ modelMatrix: mat4x4<f32>,
792
+ viewMatrix: mat4x4<f32>,
793
+ projectionMatrix: mat4x4<f32>,
794
+ };
795
+
796
+ @group(0) @binding(auto) var<uniform> app : appUniforms;
797
+ @group(0) @binding(auto) var cubeTexture : texture_cube<f32>;
798
+ @group(0) @binding(auto) var cubeTextureSampler : sampler;
799
+
800
+ struct VertexInputs {
801
+ @location(0) positions : vec3<f32>,
802
+ };
803
+
804
+ struct VertexOutputs {
805
+ @builtin(position) position : vec4<f32>,
806
+ @location(0) direction : vec3<f32>,
807
+ };
808
+
809
+ @vertex
810
+ fn vertexMain(inputs: VertexInputs) -> VertexOutputs {
811
+ var outputs : VertexOutputs;
812
+ let clipPosition =
813
+ app.projectionMatrix *
814
+ app.viewMatrix *
815
+ app.modelMatrix *
816
+ vec4<f32>(inputs.positions, 1.0);
817
+ outputs.position = vec4<f32>(clipPosition.x, clipPosition.y, clipPosition.w, clipPosition.w);
818
+ outputs.direction = inputs.positions;
819
+ return outputs;
820
+ }
821
+
822
+ @fragment
823
+ fn fragmentMain(inputs: VertexOutputs) -> @location(0) vec4<f32> {
824
+ return textureSample(cubeTexture, cubeTextureSampler, normalize(inputs.direction));
825
+ }
826
+ `
827
+ );
828
+ var SKYBOX_VS = (
829
+ /* glsl */
830
+ `#version 300 es
831
+ in vec3 positions;
832
+
833
+ uniform appUniforms {
834
+ mat4 modelMatrix;
835
+ mat4 viewMatrix;
836
+ mat4 projectionMatrix;
837
+ } app;
838
+
839
+ out vec3 vDirection;
840
+
841
+ void main(void) {
842
+ vec4 clipPosition =
843
+ app.projectionMatrix * app.viewMatrix * app.modelMatrix * vec4(positions, 1.0);
844
+ gl_Position = clipPosition.xyww;
845
+ vDirection = positions;
846
+ }
847
+ `
848
+ );
849
+ var SKYBOX_FS = (
850
+ /* glsl */
851
+ `#version 300 es
852
+ precision highp float;
853
+
854
+ uniform samplerCube cubeTexture;
855
+
856
+ in vec3 vDirection;
857
+ out vec4 fragColor;
858
+
859
+ void main(void) {
860
+ fragColor = texture(cubeTexture, normalize(vDirection));
861
+ }
862
+ `
863
+ );
529
864
  //# sourceMappingURL=index.cjs.map