-
-
Notifications
You must be signed in to change notification settings - Fork 36.2k
Open
Labels
Description
Description
When rendering interactive handles as instanced points using WebGPU + TSL (PointsNodeMaterial with positionNode = instancedBufferAttribute(...)), Raycaster does not return any intersections. Other scene objects (planes, lines, meshes) intersect correctly in the same pass. Adjusting raycaster.params.Points.threshold has no effect for these points.
Environment
- Renderer:
WebGPURenderer - Material:
PointsNodeMaterial(TSL) - three.js: v0.182.0
- Browser/OS: Chrome v142.0.7444.176/Win11
Snippets
- Handle creation (instanced positions with PointsNodeMaterial)
// Build one instanced buffer with all handle positions
const positions = new Float32Array(verticesCopy.length * 3);
verticesCopy.forEach((vertex, i) => {
positions[i * 3] = vertex.x;
positions[i * 3 + 1] = vertex.y;
positions[i * 3 + 2] = vertex.z;
});
const positionAttribute = new InstancedBufferAttribute(positions, 3);
// PointsNodeMaterial (TSL), constant on-screen size
const sizeUniform = uniform(this.HANDLE_SIZE_PX);
const material = new PointsNodeMaterial({
color,
positionNode: instancedBufferAttribute(positionAttribute),
// opacityNode: shapeCircle(), // also tested on/off
sizeNode: sizeUniform,
sizeAttenuation: false,
alphaToCoverage: true,
});
// Render all handles as one draw object
const handles = new Sprite(material);
handles.name = 'OBJECT_HANDLES';
handles.count = verticesCopy.length;
handles.renderOrder = 5;
targetObj.add(handles);- Raycaster configuration and usage
// Init
this.raycaster = new Raycaster();
this.raycaster.params.Points.threshold = 5; // also updated dynamically
// Pointer move
this.mouse = this.getNormalizedMousePosition(event);
this.raycaster.setFromCamera(this.mouse, view.camera);
// Query — handles are among the first targets
const objectsToIntersect = [
...this.getStackControllerObjs(view),
...(this.getActiveOverlayObj(view)?.getObjectsByProperty('name', 'OBJECT_HANDLES') || []),
// ... other objects (ROIs, landmarks, planes, volumes, bbox, etc.)
];
const hits = this.raycaster.intersectObjects(objectsToIntersect, false);
// Dynamic scaling (no effect on the missing hits)
private updateRaycasterPointThreshold(scaleFactor: number, pointSize: number): void {
this.raycaster.params.Points.threshold = pointSize * scaleFactor;
}Expected
intersectObjectsreturns intersections for each visible point/handle rendered viaPointsNodeMaterial. Changingraycaster.params.Points.thresholdaffects hit testing.
Actual
- No intersections are returned for the handles rendered with
PointsNodeMaterial(TSL) usingpositionNode: instancedBufferAttribute(...). Intersections for other objects work. Togglingtransparent,depthTest,alphaToCoverage, and culling does not change this.
Questions
- Is raycasting supported for
PointsNodeMaterial(TSL) with an instanced position node under WebGPU? - If supported, is a specific object type required (e.g., must be
Pointsinstead ofSprite) for raycasting to work withPointsNodeMaterial? - If not supported, what’s the recommended approach for per-point picking with TSL materials under WebGPU?
Screenshots
Version
0.182.0
Device
Desktop
Browser
Chrome
OS
Windows