Skip to content

Commit 0c4b7d1

Browse files
feat(core): Remove redundant instance picking colors (#10275)
1 parent 626010b commit 0c4b7d1

37 files changed

Lines changed: 312 additions & 144 deletions

docs/api-reference/core/deck.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ Parameters:
773773
* `y` (number) - y position in pixels
774774
* `radius` (number, optional) - radius of tolerance in pixels. Default `0`.
775775
* `layerIds` (string[], optional) - a list of layer ids to query from. If not specified, then all pickable and visible layers are queried.
776-
* `depth` - Specifies the max number of objects to return. Default `10`.
776+
* `depth` - Specifies the max number of objects to return. Default `10`. For layers without explicit picking color buffers, only the default depth of 10 unique objects per layer is guaranteed; higher custom depths may return duplicate results for these layers.
777777
* `unproject3D` (boolean, optional) - if `true`, `info.coordinate` will be a 3D point by unprojecting the `x, y` screen coordinates onto the picked geometry. Default `false`.
778778
779779
Returns:
@@ -783,6 +783,7 @@ Returns:
783783
Notes:
784784
785785
* Deep picking is implemented as a sequence of simpler picking operations and can have a performance impact. Should this become a concern, you can use the `depth` parameter to limit the number of matches that can be returned, and thus the maximum number of picking operations.
786+
* Layers that provide explicit picking color buffers support buffer mutation between picking passes and are not subject to the default-depth unique-object guarantee.
786787
787788
788789
#### `pickObjects` {#pickobjects}

docs/developer-guide/custom-layers/attribute-management.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ While most apps rely on their layers to automatically generate appropriate GPU b
4747

4848
While this allows for ultimate performance and control of updates, as well as potential sharing of buffers between layers, the application will need to generate attributes in exactly the format that the layer shaders expect, creating a strong coupling between the application and the layer.
4949

50-
**Note:** The application can provide some buffers and let others be managed by the layer. As an example management of the `instancePickingColors` buffer is normally left to the layer.
50+
**Note:** The application can provide some buffers and let others be managed by the layer. Explicit picking color buffers are only needed when the logical picking id differs from the rendered instance id.
5151

5252

5353
## More information

docs/developer-guide/custom-layers/picking.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,17 @@ When other gestures (click, drag, etc.) are detected, deck.gl does not repeat pi
4949
special support is provided for the built-in "picking color" based picking
5050
system, which most layers use.
5151

52-
To take full control of picking, a layer need to take the following steps:
52+
The following sections describe common ways to implement custom picking.
53+
54+
### Default Instanced Picking
55+
56+
Instanced layer shaders can derive picking colors from the built-in instance id when each rendered instance maps to one picked object. In GLSL, use `picking_setPickingColorFromInstanceID()` or assign `geometry.pickingColor = picking_getPickingColorFromInstanceID()`. In WGSL, add `@builtin(instance_index)` to the vertex inputs and use `picking_getPickingColorFromIndex(instanceIndex)`.
57+
58+
Add an explicit picking color attribute only when the logical picking id within the current layer is different from the rendered instance id. For example:
59+
60+
* Binary GeoJSON or MVT point sublayers may render local point instances while picking should return a global feature index.
61+
62+
* `PathLayer` tessellates one path into multiple rendered segment or joint instances, so its generated geometry needs explicit picking colors that map back to the source path index instead of each rendered segment's instance id.
5363

5464
### Creating A Picking Color Attribute
5565

docs/developer-guide/custom-layers/primitive-layers.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,4 @@ By always using the following shader functions for handling projections and scal
149149
150150
If your layer is instanced (`data` prop is an array and each element is rendered as one primitive), then you may take advantage of the default implementation of the [layer picking methods](../../api-reference/core/layer.md#layer-picking-methods).
151151
152-
By default, each layer creates an `instancePickingColors` attribute and automatically calculates it using the length of the `data` array.
153-
154-
For custom picking, read about [Implementing Custom Picking](./picking.md#implementing-custom-picking).
152+
By default, instanced layer shaders can derive picking colors from the built-in instance id. Add an explicit picking color attribute only when the logical picking id within the current layer is different from the rendered instance id. See [Implementing Custom Picking](./picking.md#implementing-custom-picking) for custom picking details and examples.

docs/developer-guide/custom-layers/subclassed-layers.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,6 @@ attribute vec3 instanceNormals;
206206
attribute vec4 instanceColors;
207207
attribute vec3 instancePositions;
208208
attribute vec3 instancePositions64Low;
209-
attribute vec3 instancePickingColors;
210209
211210
/* New attribute */
212211
attribute flat instanceRadiusPixels;
@@ -228,7 +227,7 @@ void main(void) {
228227
229228
vColor = vec4(lightColor, instanceColors.a * opacity) / 255.0;
230229
231-
picking_setPickingColor(instancePickingColors);
230+
picking_setPickingColorFromInstanceID();
232231
}
233232
`;
234233
```

docs/upgrade-guide.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Upgrade Guide
22

3+
## Upgrading to v9.4
4+
5+
#### `pickMultipleObjects()` pick depth limits
6+
7+
For layers that use built-in shader instance ids instead of explicit picking color buffers, `pickMultipleObjects()` now only guarantees the default `depth` of 10 unique objects per layer. Applications that call `pickMultipleObjects()` with a custom `depth` above the default may receive duplicate results for these layers. Layers with explicit picking color buffers keep their previous buffer-mutation behavior.
8+
9+
### `instancePickingColors` attribute is no longer automatically generated
10+
11+
Most built-in and custom instanced layers now derive picking colors from built-in shader instance ids, meaning the default `instancePickingColors` attribute is no longer automatically generated by deck.gl.
12+
13+
In rare cases, custom WebGL layer shaders may need an update if they explicitly read the `instancePickingColors` attribute.
14+
15+
- In such cases, use the new picking shader helper functions to derive the color from the instance id, for example `picking_setPickingColorFromInstanceID()` in GLSL or `picking_getPickingColorFromIndex(instanceIndex)` in WGSL.
16+
- However, if the logical picking id is different from the rendered instance id, layers can still continue to register and populate an explicit picking color attribute as before.
17+
318
## Upgrading to v9.3
419

520
Upgraded dependencies to [luma.gl v9.3](https://luma.gl/docs/upgrade-guide) and [loaders.gl v4.4](https://loaders.gl/docs/upgrade-guide). Your app may be affected if it contains custom layers.

docs/whats-new.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ This page contains highlights of each deck.gl release. Also check our [vis.gl bl
88

99
- Views now support a `parameters` prop for per-view GPU draw state overrides. `GlobeView` uses this to enable back-face culling by default, and applications can override it with `new GlobeView({parameters: {cullMode: 'none'}})`.
1010

11+
### Performance
12+
13+
- Picking in most instanced layers no longer allocates an `instancePickingColors` attribute buffer, instead using shader builtins `instance_index` / `gl_InstanceID`, reducing memory usage and initialization times.
14+
1115
## deck.gl v9.3
1216

1317
Release date: April 13, 2026

modules/aggregation-layers/src/common/aggregation-layer.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@ export default abstract class AggregationLayer<
3939
/** Called when some attributes change, a chance to mark Aggregator as dirty */
4040
abstract onAttributeChange(id: string): void;
4141

42-
initializeState(): void {
43-
this.getAttributeManager()!.remove(['instancePickingColors']);
44-
}
42+
initializeState(): void {}
4543

4644
// Extend Layer.updateState to update the Aggregator instance
4745
// returns true if aggregator is changed

modules/aggregation-layers/src/grid-layer/grid-cell-layer-vertex.glsl.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ in vec3 normals;
1212
in vec2 instancePositions;
1313
in float instanceElevationValues;
1414
in float instanceColorValues;
15-
in vec3 instancePickingColors;
1615
1716
uniform sampler2D colorRange;
1817
@@ -30,7 +29,7 @@ vec4 interp(float value, vec2 domain, sampler2D range) {
3029
}
3130
3231
void main(void) {
33-
geometry.pickingColor = instancePickingColors;
32+
geometry.pickingColor = picking_getPickingColorFromInstanceID();
3433
3534
if (isnan(instanceColorValues) ||
3635
instanceColorValues < grid.colorDomain.z ||

modules/aggregation-layers/src/hexagon-layer/hexagon-cell-layer-vertex.glsl.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ in vec3 normals;
1414
in vec2 instancePositions;
1515
in float instanceElevationValues;
1616
in float instanceColorValues;
17-
in vec3 instancePickingColors;
1817
1918
uniform sampler2D colorRange;
2019
@@ -34,7 +33,7 @@ vec4 interp(float value, vec2 domain, sampler2D range) {
3433
}
3534
3635
void main(void) {
37-
geometry.pickingColor = instancePickingColors;
36+
geometry.pickingColor = picking_getPickingColorFromInstanceID();
3837
3938
if (isnan(instanceColorValues) ||
4039
instanceColorValues < hexagon.colorDomain.z ||

0 commit comments

Comments
 (0)