@deck.gl-community/layers 9.2.5 → 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.
@@ -0,0 +1,58 @@
1
+ import { type TextureCubeLoaderOptions, type TextureCubeManifest } from '@loaders.gl/textures';
2
+ import { Layer } from '@deck.gl/core';
3
+ import type { DefaultProps, LayerProps, UpdateParameters } from '@deck.gl/core';
4
+ import { DynamicTexture, Model, ShaderInputs } from '@luma.gl/engine';
5
+ type _SkyboxLayerProps = {
6
+ /** Cubemap manifest URL or manifest object to load and render. */
7
+ cubemap: string | TextureCubeManifest | null;
8
+ /** Optional loaders.gl texture-cube load options. */
9
+ loadOptions?: TextureCubeLoaderOptions | null;
10
+ /**
11
+ * Declares how the cubemap faces are oriented relative to deck.gl's Z-up
12
+ * world. Use `y-up` for cubemaps authored for Y-up scenes, such as the
13
+ * Tycho star map faces from the luma.gl globe showcase.
14
+ */
15
+ orientation?: 'default' | 'y-up';
16
+ };
17
+ export type SkyboxLayerProps = _SkyboxLayerProps & LayerProps;
18
+ type SkyboxLayerState = {
19
+ /** Active GPU cubemap texture, if one has been loaded successfully. */
20
+ cubemapTexture: DynamicTexture | null;
21
+ /** Monotonic load token used to discard stale async cubemap loads. */
22
+ loadCount: number;
23
+ /** Backing model that renders the cube geometry. */
24
+ model?: Model;
25
+ /** Shader input manager for the skybox uniforms. */
26
+ shaderInputs?: ShaderInputs<any>;
27
+ };
28
+ /**
29
+ * Renders a camera-centered cubemap background for `MapView`, `GlobeView`,
30
+ * `FirstPersonView`, and other 3D-capable deck.gl views.
31
+ */
32
+ export declare class SkyboxLayer<ExtraProps extends Record<string, unknown> = Record<string, unknown>> extends Layer<Required<_SkyboxLayerProps> & ExtraProps> {
33
+ static defaultProps: DefaultProps<SkyboxLayerProps>;
34
+ static layerName: string;
35
+ state: SkyboxLayerState;
36
+ /** Initializes the cube model and starts loading the cubemap texture. */
37
+ initializeState(): void;
38
+ /** Reloads the cubemap when its source manifest or load options change. */
39
+ updateState({ props, oldProps }: UpdateParameters<this>): void;
40
+ /** Releases GPU resources owned by the layer. */
41
+ finalizeState(): void;
42
+ /** Draws the skybox cube for the current viewport. */
43
+ draw(): void;
44
+ /** Creates the luma.gl model used to render the skybox cube. */
45
+ protected _getModel(shaderInputs: ShaderInputs<any>): Model;
46
+ /** Returns the WGSL/GLSL shader pair used by the layer. */
47
+ getShaders(): {
48
+ source: string;
49
+ vs: string;
50
+ fs: string;
51
+ };
52
+ /** Starts an asynchronous cubemap load for the current props. */
53
+ private _loadCubemap;
54
+ /** Swaps the active GPU cubemap texture and updates model bindings. */
55
+ private _setCubemapTexture;
56
+ }
57
+ export {};
58
+ //# sourceMappingURL=skybox-layer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skybox-layer.d.ts","sourceRoot":"","sources":["../../src/skybox-layer/skybox-layer.ts"],"names":[],"mappings":"AAKA,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAC,KAAK,EAAC,MAAM,eAAe,CAAC;AACpC,OAAO,KAAK,EAAC,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAW,MAAM,eAAe,CAAC;AAGxF,OAAO,EAAe,cAAc,EAAE,KAAK,EAAE,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAqClF,KAAK,iBAAiB,GAAG;IACvB,kEAAkE;IAClE,OAAO,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAAC;IAC7C,qDAAqD;IACrD,WAAW,CAAC,EAAE,wBAAwB,GAAG,IAAI,CAAC;IAC9C;;;;OAIG;IACH,WAAW,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;CAClC,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,GAAG,UAAU,CAAC;AAO9D,KAAK,gBAAgB,GAAG;IACtB,uEAAuE;IACvE,cAAc,EAAE,cAAc,GAAG,IAAI,CAAC;IACtC,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,oDAAoD;IACpD,YAAY,CAAC,EAAE,YAAY,CAAC,GAAG,CAAC,CAAC;CAClC,CAAC;AAEF;;;GAGG;AACH,qBAAa,WAAW,CACtB,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CACpE,SAAQ,KAAK,CAAC,QAAQ,CAAC,iBAAiB,CAAC,GAAG,UAAU,CAAC;IACvD,MAAM,CAAC,YAAY,iCAAgB;IACnC,MAAM,CAAC,SAAS,SAAiB;IAEjC,KAAK,EAAE,gBAAgB,CAAc;IAErC,yEAAyE;IACzE,eAAe,IAAI,IAAI;IAsBvB,2EAA2E;IAC3E,WAAW,CAAC,EAAC,KAAK,EAAE,QAAQ,EAAC,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,IAAI;IAM5D,iDAAiD;IACjD,aAAa,IAAI,IAAI;IAKrB,sDAAsD;IACtD,IAAI,IAAI,IAAI;IAkBZ,gEAAgE;IAChE,SAAS,CAAC,SAAS,CAAC,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,GAAG,KAAK;IAY3D,2DAA2D;IAC3D,UAAU;;;;;IAQV,iEAAiE;YACnD,YAAY;IAyB1B,uEAAuE;IACvE,OAAO,CAAC,kBAAkB;CAe3B"}
@@ -0,0 +1,248 @@
1
+ // deck.gl-community
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+ import { load } from '@loaders.gl/core';
5
+ import { TextureCubeLoader } from '@loaders.gl/textures';
6
+ import { Layer } from '@deck.gl/core';
7
+ import { Matrix4 } from '@math.gl/core';
8
+ import { CubeGeometry, DynamicTexture, Model, ShaderInputs } from '@luma.gl/engine';
9
+ import { convertLoadedCubemapToTextureData, createCubemapLoadOptions } from "./cubemap-utils.js";
10
+ const app = {
11
+ name: 'app',
12
+ uniformTypes: {
13
+ modelMatrix: 'mat4x4<f32>',
14
+ viewMatrix: 'mat4x4<f32>',
15
+ projectionMatrix: 'mat4x4<f32>'
16
+ }
17
+ };
18
+ const SKYBOX_PARAMETERS = {
19
+ cullMode: 'front',
20
+ depthWriteEnabled: false,
21
+ depthCompare: 'less-equal'
22
+ };
23
+ const SKYBOX_SCALE = new Matrix4().scale([2, 2, 2]);
24
+ const defaultProps = {
25
+ cubemap: null,
26
+ loadOptions: null,
27
+ orientation: 'default'
28
+ };
29
+ /**
30
+ * Renders a camera-centered cubemap background for `MapView`, `GlobeView`,
31
+ * `FirstPersonView`, and other 3D-capable deck.gl views.
32
+ */
33
+ export class SkyboxLayer extends Layer {
34
+ static defaultProps = defaultProps;
35
+ static layerName = 'SkyboxLayer';
36
+ state = undefined;
37
+ /** Initializes the cube model and starts loading the cubemap texture. */
38
+ initializeState() {
39
+ const attributeManager = this.getAttributeManager();
40
+ attributeManager?.remove(['instancePickingColors']);
41
+ const shaderInputs = new ShaderInputs(createShaderInputModules(this.context.defaultShaderModules), {
42
+ disableWarnings: true
43
+ });
44
+ const model = this._getModel(shaderInputs);
45
+ this.setState({
46
+ cubemapTexture: null,
47
+ loadCount: 0,
48
+ model,
49
+ shaderInputs
50
+ });
51
+ this._loadCubemap().catch(() => { });
52
+ }
53
+ /** Reloads the cubemap when its source manifest or load options change. */
54
+ updateState({ props, oldProps }) {
55
+ if (props.cubemap !== oldProps.cubemap || props.loadOptions !== oldProps.loadOptions) {
56
+ this._loadCubemap().catch(() => { });
57
+ }
58
+ }
59
+ /** Releases GPU resources owned by the layer. */
60
+ finalizeState() {
61
+ this.state.cubemapTexture?.destroy();
62
+ this.state.model?.destroy();
63
+ }
64
+ /** Draws the skybox cube for the current viewport. */
65
+ draw() {
66
+ const { model, cubemapTexture, shaderInputs } = this.state;
67
+ if (!model || !cubemapTexture || !shaderInputs) {
68
+ return;
69
+ }
70
+ const viewport = this.context.viewport;
71
+ shaderInputs.setProps({
72
+ app: {
73
+ modelMatrix: getSkyboxModelMatrix(this.props.orientation),
74
+ viewMatrix: getSkyboxViewMatrix(viewport),
75
+ projectionMatrix: viewport.projectionMatrix
76
+ }
77
+ });
78
+ model.draw(this.context.renderPass);
79
+ }
80
+ /** Creates the luma.gl model used to render the skybox cube. */
81
+ _getModel(shaderInputs) {
82
+ return new Model(this.context.device, {
83
+ ...this.getShaders(),
84
+ id: this.props.id,
85
+ bufferLayout: this.getAttributeManager()?.getBufferLayouts() || [],
86
+ geometry: new CubeGeometry({ indices: true }),
87
+ shaderInputs,
88
+ isInstanced: false,
89
+ parameters: SKYBOX_PARAMETERS
90
+ });
91
+ }
92
+ /** Returns the WGSL/GLSL shader pair used by the layer. */
93
+ getShaders() {
94
+ return {
95
+ source: SKYBOX_WGSL,
96
+ vs: SKYBOX_VS,
97
+ fs: SKYBOX_FS
98
+ };
99
+ }
100
+ /** Starts an asynchronous cubemap load for the current props. */
101
+ async _loadCubemap() {
102
+ const { cubemap, loadOptions } = this.props;
103
+ const nextLoadCount = this.state.loadCount + 1;
104
+ this.setState({ loadCount: nextLoadCount });
105
+ if (!cubemap) {
106
+ this._setCubemapTexture(null);
107
+ return;
108
+ }
109
+ try {
110
+ const loadedTexture = await loadCubemapSource(cubemap, loadOptions);
111
+ if (this.state.loadCount !== nextLoadCount || !this.state.model) {
112
+ return;
113
+ }
114
+ const cubemapData = convertLoadedCubemapToTextureData(loadedTexture);
115
+ this._setCubemapTexture(createCubemapTexture(this.context.device, cubemapData));
116
+ }
117
+ catch (error) {
118
+ if (this.state.loadCount === nextLoadCount) {
119
+ this.raiseError(error, 'SkyboxLayer failed to load cubemap');
120
+ }
121
+ }
122
+ }
123
+ /** Swaps the active GPU cubemap texture and updates model bindings. */
124
+ _setCubemapTexture(texture) {
125
+ const { cubemapTexture, model } = this.state;
126
+ if (cubemapTexture === texture) {
127
+ return;
128
+ }
129
+ cubemapTexture?.destroy();
130
+ this.setState({ cubemapTexture: texture });
131
+ if (texture && model) {
132
+ model.setBindings({ cubeTexture: texture });
133
+ }
134
+ this.setNeedsRedraw();
135
+ }
136
+ }
137
+ /** Loads a cubemap manifest or manifest URL through loaders.gl. */
138
+ async function loadCubemapSource(cubemap, loadOptions) {
139
+ const normalizedLoadOptions = createCubemapLoadOptions(cubemap, loadOptions);
140
+ if (typeof cubemap === 'string') {
141
+ return (await load(cubemap, TextureCubeLoader, normalizedLoadOptions));
142
+ }
143
+ return (await TextureCubeLoader.parseText(JSON.stringify(cubemap), normalizedLoadOptions));
144
+ }
145
+ /** Creates the runtime `DynamicTexture` instance used by the skybox model. */
146
+ function createCubemapTexture(device, data) {
147
+ return new DynamicTexture(device, {
148
+ dimension: 'cube',
149
+ data,
150
+ mipmaps: true,
151
+ sampler: {
152
+ addressModeU: 'clamp-to-edge',
153
+ addressModeV: 'clamp-to-edge',
154
+ addressModeW: 'clamp-to-edge',
155
+ magFilter: 'linear',
156
+ minFilter: 'linear',
157
+ mipmapFilter: 'linear'
158
+ }
159
+ });
160
+ }
161
+ /** Removes camera translation from the active view matrix for skybox rendering. */
162
+ function getSkyboxViewMatrix(viewport) {
163
+ const viewMatrix = new Matrix4(viewport.viewMatrixUncentered || viewport.viewMatrix);
164
+ viewMatrix[12] = 0;
165
+ viewMatrix[13] = 0;
166
+ viewMatrix[14] = 0;
167
+ return viewMatrix;
168
+ }
169
+ /** Returns the skybox cube transform for the requested cubemap orientation. */
170
+ function getSkyboxModelMatrix(orientation = 'default') {
171
+ if (orientation === 'y-up') {
172
+ return new Matrix4().rotateX(Math.PI / 2).scale([2, 2, 2]);
173
+ }
174
+ return new Matrix4(SKYBOX_SCALE);
175
+ }
176
+ /** Converts the current shader module list into a name-indexed dictionary. */
177
+ function createShaderInputModules(defaultShaderModules) {
178
+ return Object.fromEntries([app, ...defaultShaderModules].map((module) => [module.name, module]));
179
+ }
180
+ const SKYBOX_WGSL = /* wgsl */ `
181
+ struct appUniforms {
182
+ modelMatrix: mat4x4<f32>,
183
+ viewMatrix: mat4x4<f32>,
184
+ projectionMatrix: mat4x4<f32>,
185
+ };
186
+
187
+ @group(0) @binding(auto) var<uniform> app : appUniforms;
188
+ @group(0) @binding(auto) var cubeTexture : texture_cube<f32>;
189
+ @group(0) @binding(auto) var cubeTextureSampler : sampler;
190
+
191
+ struct VertexInputs {
192
+ @location(0) positions : vec3<f32>,
193
+ };
194
+
195
+ struct VertexOutputs {
196
+ @builtin(position) position : vec4<f32>,
197
+ @location(0) direction : vec3<f32>,
198
+ };
199
+
200
+ @vertex
201
+ fn vertexMain(inputs: VertexInputs) -> VertexOutputs {
202
+ var outputs : VertexOutputs;
203
+ let clipPosition =
204
+ app.projectionMatrix *
205
+ app.viewMatrix *
206
+ app.modelMatrix *
207
+ vec4<f32>(inputs.positions, 1.0);
208
+ outputs.position = vec4<f32>(clipPosition.x, clipPosition.y, clipPosition.w, clipPosition.w);
209
+ outputs.direction = inputs.positions;
210
+ return outputs;
211
+ }
212
+
213
+ @fragment
214
+ fn fragmentMain(inputs: VertexOutputs) -> @location(0) vec4<f32> {
215
+ return textureSample(cubeTexture, cubeTextureSampler, normalize(inputs.direction));
216
+ }
217
+ `;
218
+ const SKYBOX_VS = /* glsl */ `#version 300 es
219
+ in vec3 positions;
220
+
221
+ uniform appUniforms {
222
+ mat4 modelMatrix;
223
+ mat4 viewMatrix;
224
+ mat4 projectionMatrix;
225
+ } app;
226
+
227
+ out vec3 vDirection;
228
+
229
+ void main(void) {
230
+ vec4 clipPosition =
231
+ app.projectionMatrix * app.viewMatrix * app.modelMatrix * vec4(positions, 1.0);
232
+ gl_Position = clipPosition.xyww;
233
+ vDirection = positions;
234
+ }
235
+ `;
236
+ const SKYBOX_FS = /* glsl */ `#version 300 es
237
+ precision highp float;
238
+
239
+ uniform samplerCube cubeTexture;
240
+
241
+ in vec3 vDirection;
242
+ out vec4 fragColor;
243
+
244
+ void main(void) {
245
+ fragColor = texture(cubeTexture, normalize(vDirection));
246
+ }
247
+ `;
248
+ //# sourceMappingURL=skybox-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skybox-layer.js","sourceRoot":"","sources":["../../src/skybox-layer/skybox-layer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deck.gl-community/layers",
3
- "version": "9.2.5",
3
+ "version": "9.3.1-alpha.0",
4
4
  "description": "Add-on layers for deck.gl",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -33,19 +33,21 @@
33
33
  "test-watch": "vitest"
34
34
  },
35
35
  "dependencies": {
36
- "@deck.gl/core": "~9.2.8",
37
- "@deck.gl/layers": "~9.2.8",
38
- "@deck.gl/mesh-layers": "~9.2.8",
39
- "@luma.gl/constants": "~9.2.6",
40
- "@luma.gl/core": "~9.2.6",
41
- "@luma.gl/engine": "~9.2.6",
42
- "@luma.gl/shadertools": "~9.2.6",
36
+ "@deck.gl/core": "~9.3.0",
37
+ "@deck.gl/layers": "~9.3.0",
38
+ "@deck.gl/mesh-layers": "~9.3.0",
39
+ "@loaders.gl/core": "^4.4.1",
40
+ "@loaders.gl/textures": "^4.4.1",
41
+ "@luma.gl/constants": "~9.3.2",
42
+ "@luma.gl/core": "~9.3.2",
43
+ "@luma.gl/engine": "~9.3.2",
44
+ "@luma.gl/shadertools": "~9.3.2",
43
45
  "@math.gl/core": "^4.0.0"
44
46
  },
45
47
  "devDependencies": {
46
- "@deck.gl/test-utils": "~9.2.8",
47
- "@luma.gl/webgpu": "~9.2.6",
48
+ "@deck.gl/test-utils": "~9.3.0",
49
+ "@luma.gl/webgpu": "~9.3.2",
48
50
  "@probe.gl/test-utils": "^4.0.4"
49
51
  },
50
- "gitHead": "c6b0f45b1e7f9916c1b79a43c39b839a8096c163"
52
+ "gitHead": "dd572a3491cb15a6ff2f0008e93ae1dc38962b06"
51
53
  }
package/src/index.ts CHANGED
@@ -7,3 +7,6 @@ export {PathOutlineLayer} from './path-outline-layer/path-outline-layer';
7
7
 
8
8
  export type {PathMarkerLayerProps} from './path-marker-layer/path-marker-layer';
9
9
  export {PathMarkerLayer} from './path-marker-layer/path-marker-layer';
10
+
11
+ export type {SkyboxLayerProps} from './skybox-layer/skybox-layer';
12
+ export {SkyboxLayer} from './skybox-layer/skybox-layer';
@@ -59,8 +59,6 @@ in float outline_vzLevel;
59
59
  // in vec2 outline_vUV;
60
60
  in vec4 outline_vPosition;
61
61
 
62
- out vec4 fragColor;
63
-
64
62
  const float OUTLINE_Z_LEVEL_ERROR = 0.01;
65
63
 
66
64
  // Return a darker color in shadowmap
@@ -73,12 +71,12 @@ vec4 outline_filterDarkenColor(vec4 color) {
73
71
  if (outline_uEnabled) {
74
72
  float maxZLevel;
75
73
  if (outline_vPosition.q > 0.0) {
76
- maxZLevel = texture2DProj(outline_uShadowmap, outline_vPosition).r * 255.;
74
+ maxZLevel = textureProj(outline_uShadowmap, outline_vPosition).r * 255.;
77
75
  } else {
78
76
  discard;
79
77
  }
80
78
  if (maxZLevel < outline_vzLevel + OUTLINE_Z_LEVEL_ERROR) {
81
- vec4(color.rgb * 0.5, color.a);
79
+ return vec4(color.rgb * 0.5, color.a);
82
80
  } else {
83
81
  discard;
84
82
  }
@@ -5,9 +5,8 @@
5
5
  import type {PathLayerProps} from '@deck.gl/layers';
6
6
  import {PathLayer} from '@deck.gl/layers';
7
7
  import type {DefaultProps, LayerContext} from '@deck.gl/core';
8
- import {GL} from '@luma.gl/constants';
9
8
  import {Framebuffer} from '@luma.gl/core';
10
- import type {RenderPipelineParameters} from '@luma.gl/core';
9
+ import type {RenderPipelineParameters, Texture} from '@luma.gl/core';
11
10
  import {outline} from './outline';
12
11
 
13
12
  /**
@@ -89,30 +88,65 @@ export class PathOutlineLayer<DataT = any, ExtraPropsT = Record<string, unknown>
89
88
  initializeState(context: LayerContext) {
90
89
  super.initializeState();
91
90
 
91
+ const attributeManager = this.getAttributeManager();
92
+
93
+ if (!attributeManager) {
94
+ throw new Error('PathOutlineLayer requires an attribute manager during initialization.');
95
+ }
96
+
92
97
  // Create an outline "shadow" map
93
98
  // TODO - we should create a single outlineMap for all layers
94
99
  const outlineFramebuffer = context.device.createFramebuffer({
95
- colorAttachments: ['rgba8unorm']
96
- });
97
-
98
- this.setState({
99
- outlineFramebuffer
100
+ colorAttachments: [
101
+ context.device.createTexture({
102
+ format: 'rgba8unorm',
103
+ width: 1,
104
+ height: 1,
105
+ mipLevels: 1
106
+ })
107
+ ]
100
108
  });
101
109
 
102
- // Create an attribute manager
103
- // @ts-expect-error check whether this.getAttributeManager works here
104
- this.state.attributeManager.addInstanced({
110
+ attributeManager.addInstanced({
105
111
  instanceZLevel: {
106
112
  size: 1,
107
- type: GL.UNSIGNED_BYTE,
113
+ type: 'uint8',
108
114
  accessor: 'getZLevel'
109
115
  }
110
116
  });
117
+
118
+ this.setState({
119
+ outlineFramebuffer,
120
+ model: this._getModel()
121
+ });
122
+ }
123
+
124
+ finalizeState(context: LayerContext) {
125
+ this.state.outlineFramebuffer?.destroy();
126
+ super.finalizeState(context);
111
127
  }
112
128
 
113
129
  // Override draw to add render module
114
- draw({moduleParameters = {}, parameters, uniforms, context}) {
115
- // Need to calculate same uniforms as base layer
130
+ draw() {
131
+ const model = this.state.model;
132
+ const outlineFramebuffer = this.state.outlineFramebuffer;
133
+
134
+ if (!model || !outlineFramebuffer) {
135
+ return;
136
+ }
137
+
138
+ const viewport = this.context.viewport;
139
+ const viewportWidth = Math.max(1, Math.ceil(viewport.width));
140
+ const viewportHeight = Math.max(1, Math.ceil(viewport.height));
141
+
142
+ outlineFramebuffer.resize({width: viewportWidth, height: viewportHeight});
143
+
144
+ const shadowmapTexture = getFramebufferTexture(outlineFramebuffer);
145
+
146
+ if (!shadowmapTexture) {
147
+ return;
148
+ }
149
+
116
150
  const {
117
151
  jointRounded,
118
152
  capRounded,
@@ -124,7 +158,7 @@ export class PathOutlineLayer<DataT = any, ExtraPropsT = Record<string, unknown>
124
158
  widthMaxPixels
125
159
  } = this.props;
126
160
 
127
- uniforms = Object.assign({}, uniforms, {
161
+ const basePathProps = {
128
162
  jointType: Number(jointRounded),
129
163
  capType: Number(capRounded),
130
164
  billboard,
@@ -133,58 +167,57 @@ export class PathOutlineLayer<DataT = any, ExtraPropsT = Record<string, unknown>
133
167
  miterLimit,
134
168
  widthMinPixels,
135
169
  widthMaxPixels
136
- });
170
+ };
137
171
 
138
172
  // Render the outline shadowmap (based on segment z orders)
139
- const {outlineFramebuffer} = this.state;
140
-
141
- if (context?.viewport) {
142
- const viewportWidth = Math.max(1, Math.ceil(context.viewport.width));
143
- const viewportHeight = Math.max(1, Math.ceil(context.viewport.height));
144
-
145
- outlineFramebuffer.resize({width: viewportWidth, height: viewportHeight});
146
- } else {
147
- outlineFramebuffer.resize();
148
- }
149
-
150
- const shadowmapTexture = outlineFramebuffer.colorAttachments[0]?.texture;
151
-
152
- if (!shadowmapTexture) {
153
- return;
154
- }
155
- // TODO(v9): resize, see 'sf' example.
156
- // outlineFramebuffer.resize();
157
- // TODO(v9) clear FBO
158
- // outlineFramebuffer.clear({ color: true, depth: true, stencil: true });
159
-
160
- this.state.model.updateModuleSettings({
161
- outlineEnabled: true,
162
- outlineRenderShadowmap: true,
163
- outlineShadowmap: shadowmapTexture
173
+ this.setShaderModuleProps({
174
+ outline: {
175
+ outlineEnabled: true,
176
+ outlineRenderShadowmap: true,
177
+ outlineShadowmap: shadowmapTexture
178
+ }
164
179
  });
165
-
166
- this.state.model.draw({
167
- uniforms: Object.assign({}, uniforms, {
180
+ model.shaderInputs.setProps({
181
+ path: {
182
+ ...basePathProps,
168
183
  jointType: 0,
169
- widthScale: this.props.widthScale * 1.3
170
- }),
171
- parameters: OUTLINE_SHADOWMAP_PARAMETERS,
172
- framebuffer: outlineFramebuffer
184
+ widthScale: widthScale * 1.3
185
+ }
173
186
  });
187
+ model.setParameters(OUTLINE_SHADOWMAP_PARAMETERS);
188
+ const shadowRenderPass = this.context.device.beginRenderPass({
189
+ id: `${this.props.id}-outline-shadowmap`,
190
+ framebuffer: outlineFramebuffer,
191
+ parameters: {viewport: [0, 0, viewportWidth, viewportHeight]},
192
+ clearColor: [0, 0, 0, 0],
193
+ clearDepth: 1,
194
+ clearStencil: 0
195
+ });
196
+ model.draw(shadowRenderPass);
197
+ shadowRenderPass.end();
174
198
 
175
199
  // Now use the outline shadowmap to render the lines (with outlines)
176
- this.state.model.updateModuleSettings({
177
- outlineEnabled: true,
178
- outlineRenderShadowmap: false,
179
- outlineShadowmap: shadowmapTexture
200
+ this.setShaderModuleProps({
201
+ outline: {
202
+ outlineEnabled: true,
203
+ outlineRenderShadowmap: false,
204
+ outlineShadowmap: shadowmapTexture
205
+ }
180
206
  });
181
- this.state.model.draw({
182
- uniforms: Object.assign({}, uniforms, {
183
- jointType: Number(jointRounded),
184
- capType: Number(capRounded),
185
- widthScale: this.props.widthScale
186
- }),
187
- parameters: OUTLINE_RENDER_PARAMETERS
207
+ model.shaderInputs.setProps({
208
+ path: basePathProps
188
209
  });
210
+ model.setParameters(OUTLINE_RENDER_PARAMETERS);
211
+ model.draw(this.context.renderPass);
189
212
  }
190
213
  }
214
+
215
+ function getFramebufferTexture(framebuffer: Framebuffer): Texture | null {
216
+ const colorAttachment = framebuffer.colorAttachments[0];
217
+
218
+ if (!colorAttachment) {
219
+ return null;
220
+ }
221
+
222
+ return 'texture' in colorAttachment ? colorAttachment.texture : colorAttachment;
223
+ }