Variable: indexPicking
constindexPicking:object
Defined in: modules/engine/src/modules/picking/index-picking.ts:187
Provides support for color-based picking and highlighting.
In particular, supports picking a specific instance in an instanced draw call and highlighting an instance based on its picking color, and correspondingly, supports picking and highlighting groups of primitives with the same picking color in non-instanced draw-calls
Type Declaration
defaultUniforms
readonlydefaultUniforms:object
defaultUniforms.batchIndex
readonlybatchIndex:0=0
defaultUniforms.highlightColor
readonlyhighlightColor:NumberArray4=DEFAULT_HIGHLIGHT_COLOR
defaultUniforms.highlightedBatchIndex
readonlyhighlightedBatchIndex:-1=INVALID_INDEX
defaultUniforms.highlightedObjectIndex
readonlyhighlightedObjectIndex:-1=INVALID_INDEX
defaultUniforms.indexMode
readonlyindexMode:0=0
defaultUniforms.isActive
readonlyisActive:false=false
defaultUniforms.isHighlightActive
readonlyisHighlightActive:false=false
fs
fs: "precision highp float;\nprecision highp int;\n\nlayout(std140) uniform pickingUniforms {\n int isActive;\n int indexMode;\n int batchIndex;\n\n int isHighlightActive;\n int highlightedBatchIndex;\n int highlightedObjectIndex;\n vec4 highlightColor;\n} picking;\n\n\nconst int INDEX_PICKING_INVALID_INDEX = -1; // 2^32 - 1\n\nflat in int picking_objectIndex;\n\n/**\n * Check if this vertex is highlighted (part of the selected batch and object)\n */ \nbool picking_isFragmentHighlighted() {\n return \n bool(picking.isHighlightActive) &&\n picking.highlightedBatchIndex == picking.batchIndex &&\n picking.highlightedObjectIndex == picking_objectIndex\n ;\n}\n\n/**\n * Returns highlight color if this item is selected.\n */\nvec4 picking_filterHighlightColor(vec4 color) {\n // If we are still picking, we don't highlight\n if (bool(picking.isActive)) {\n return color;\n }\n\n // If we are not highlighted, return color as is\n if (!picking_isFragmentHighlighted()) {\n return color;\n }\n \n // Blend in highlight color based on its alpha value\n float highLightAlpha = picking.highlightColor.a;\n float blendedAlpha = highLightAlpha + color.a * (1.0 - highLightAlpha);\n float highLightRatio = highLightAlpha / blendedAlpha;\n\n vec3 blendedRGB = mix(color.rgb, picking.highlightColor.rgb, highLightRatio);\n return vec4(blendedRGB, blendedAlpha);\n}\n\n/*\n * Returns picking color if picking enabled else unmodified argument.\n */\nivec4 picking_getPickingColor() {\n // Assumes that colorAttachment0 is rg32int\n // TODO? - we could render indices into a second color attachment and not mess with fragColor\n return ivec4(picking_objectIndex, picking.batchIndex, 0, 0);\n}\n\nvec4 picking_filterPickingColor(vec4 color) {\n if (bool(picking.isActive)) {\n if (picking_objectIndex == INDEX_PICKING_INVALID_INDEX) {\n discard;\n }\n }\n return color;\n}\n\n/*\n * Returns picking color if picking is enabled if not\n * highlight color if this item is selected, otherwise unmodified argument.\n */\nvec4 picking_filterColor(vec4 color) {\n vec4 outColor = color;\n outColor = picking_filterHighlightColor(outColor);\n outColor = picking_filterPickingColor(outColor);\n return outColor;\n}\n"
getUniforms
getUniforms: (
props,prevUniforms?) =>PickingUniforms
Parameters
props?
PickingProps = {}
prevUniforms?
PickingUniforms
Returns
PickingUniforms
name
readonlyname:"picking"='picking'
props
readonlyprops:PickingProps
source
source: "struct pickingUniforms {\n isActive: i32,\n indexMode: i32,\n batchIndex: i32,\n\n isHighlightActive: i32,\n highlightedBatchIndex: i32,\n highlightedObjectIndex: i32,\n highlightColor: vec4<f32>,\n};\n\n@group(0) @binding(auto) var<uniform> picking: pickingUniforms;\n\n\nconst INDEX_PICKING_MODE_INSTANCE = 0;\nconst INDEX_PICKING_MODE_ATTRIBUTE = 1;\nconst INDEX_PICKING_MODE_VERTEX = 2;\nconst INDEX_PICKING_INVALID_INDEX = -1; // 2^32 - 1\n\n/**\n * WGSL shaders need to carry the returned object index through their own stage outputs.\n */\nfn picking_getInstanceObjectIndex(instanceIndex: u32) -> i32 {\n return i32(instanceIndex);\n}\n\nfn picking_getVertexObjectIndex(vertexIndex: u32) -> i32 {\n return i32(vertexIndex);\n}\n\nfn picking_getAttributeObjectIndex(objectIndex: i32) -> i32 {\n return objectIndex;\n}\n\nfn picking_setObjectIndex(objectIndex: i32) -> i32 {\n return picking_getAttributeObjectIndex(objectIndex);\n}\n\nfn picking_isObjectHighlighted(objectIndex: i32) -> bool {\n return\n picking.isHighlightActive != 0 &&\n picking.highlightedBatchIndex == picking.batchIndex &&\n picking.highlightedObjectIndex == objectIndex;\n}\n\nfn picking_filterHighlightColor(color: vec4<f32>, objectIndex: i32) -> vec4<f32> {\n if (picking.isActive != 0 || !picking_isObjectHighlighted(objectIndex)) {\n return color;\n }\n\n let highLightAlpha = picking.highlightColor.a;\n let blendedAlpha = highLightAlpha + color.a * (1.0 - highLightAlpha);\n if (blendedAlpha == 0.0) {\n return vec4<f32>(color.rgb, 0.0);\n }\n\n let highLightRatio = highLightAlpha / blendedAlpha;\n let blendedRGB = mix(color.rgb, picking.highlightColor.rgb, highLightRatio);\n return vec4<f32>(blendedRGB, blendedAlpha);\n}\n\nfn picking_filterPickingColor(color: vec4<f32>, objectIndex: i32) -> vec4<f32> {\n if (picking.isActive != 0 && objectIndex == INDEX_PICKING_INVALID_INDEX) {\n discard;\n }\n return color;\n}\n\nfn picking_getPickingColor(objectIndex: i32) -> vec2<i32> {\n return vec2<i32>(objectIndex, picking.batchIndex);\n}\n\n"
uniforms
readonlyuniforms:PickingUniforms
uniformTypes
uniformTypes:
Required<UniformTypes<PickingUniforms>>
vs
vs: "precision highp float;\nprecision highp int;\n\nlayout(std140) uniform pickingUniforms {\n int isActive;\n int indexMode;\n int batchIndex;\n\n int isHighlightActive;\n int highlightedBatchIndex;\n int highlightedObjectIndex;\n vec4 highlightColor;\n} picking;\n\n\nconst int INDEX_PICKING_MODE_INSTANCE = 0;\nconst int INDEX_PICKING_MODE_ATTRIBUTE = 1;\nconst int INDEX_PICKING_MODE_VERTEX = 2;\n\nconst int INDEX_PICKING_INVALID_INDEX = -1; // 2^32 - 1\n\nflat out int picking_objectIndex;\n\n/**\n * Vertex shaders should call this function to set the object index.\n * If using instance or vertex mode, the argument is ignored and 0 can be supplied.\n */\nvoid picking_setObjectIndex(int objectIndex) {\n switch (picking.indexMode) {\n case INDEX_PICKING_MODE_INSTANCE:\n picking_objectIndex = gl_InstanceID;\n break;\n case INDEX_PICKING_MODE_ATTRIBUTE:\n picking_objectIndex = objectIndex;\n break;\n case INDEX_PICKING_MODE_VERTEX:\n picking_objectIndex = gl_VertexID;\n break;\n }\n}\n"
Note
Color based picking has the significant advantage in that it can be added to any existing shader without requiring any additional picking logic.