A-Frame raycaster visibility behavior needs diagnosis
0 reputation · 27 Sept 2021, 22:42 UTC
0 reputation · 27 Sept 2021, 22:42 UTC
A-Frame’s raycaster component supports scoped intersection testing through objects, interval, near, and far. One behavior remains unclear for review: whether an entity marked visible=false is excluded from intersections and from raycaster-intersected events.
The documentation does not consistently define that visibility rule across A-Frame 1.x and 2.0 pre-release versions. Because the component relies on three.js raycasting, the bundled three.js version may also affect traversal of invisible objects. The target A-Frame release and its dependency version therefore need to be identified before the behavior is classified as expected.
For the version under test, should an invisible entity ever receive raycaster-intersected? Does the objects selector alter that outcome, and what release-specific evidence or controlled comparison of otherwise identical visible and hidden entities would settle the rule?
35775 reputation · 28 Sept 2021, 08:20 UTC
No. An entity with visible="false" is not automatically excluded from A-Frame raycaster intersections. If it is included in the raycaster candidate set and its geometry intersects the ray, it can receive raycaster-intersected and appear in intersectedEls. The objects selector controls which entities are candidates; it does not add a visibility test.
Likely explanation: A-Frame passes the objects selection to three.js Raycaster.intersectObjects, and three.js traversal does not skip object.visible === false by default. This is not yet confirmed for your release because A-Frame 1.x and 2.0 pre-release bundle different three.js revisions.
Confirmed boundary: objects is an inclusion list only. Omitting an entity excludes it regardless of visible; including an invisible entity does not exclude it solely because of visibility.
console.log(AFRAME.version, AFRAME.THREE?.REVISION). If AFRAME.THREE is undefined, log the REVISION of the three.js import in your bundle.visible="false". Keep both matched by the same objects selector, or leave objects unset.raycaster-intersected and intersectedEls for both entities.objects selector that omits the invisible entity; it should stop appearing while the visible one still intersects.| Observation | Meaning |
|---|---|
Both matched entities receive raycaster-intersected, including visible="false" | visible=false is not a raycasting exclusion for this release. |
| Only the visible entity receives the event | This release or bundle filters invisible objects; treat as version-specific. |
Invisible entity omitted from objects | No event; visible entity still intersects. objects is inclusion, not visibility. |
Missing diagnostic detail that changes the recommendation: report AFRAME.version with AFRAME.THREE.REVISION, or the imported three.js REVISION, for the release under test.
Use comments to ask for clarification. Post a solution as an answer.
35,775 reputation · 28 Sept 2021, 03:30 UTC
The core issue is that three.js Raycaster traverses the full scene graph and treats Object3D.visible as a render-only flag; it does not cull invisible objects from intersection tests unless application code explicitly filters them out. A-Frame’s raycaster component wraps this behavior and its objects selector merely narrows the candidate set—it does not inject a visibility check. Consequently, an entity with visible="false" can still appear in raycaster-intersected events in both A-Frame 1.x and current 2.0 pre-release builds, because the bundled three.js revision (r158+ in 1.4.x, r160+ in 2.0 alphas) retains the same default traversal logic.
To settle the rule for your build, log THREE.REVISION in the console, then run a minimal controlled test: two identical <a-box> entities, one with visible="false", both either inside the objects selector or left to scene-wide raycasting. Move the raycaster across them and record which entities fire raycaster-intersected. If the invisible box never appears, something in your version or a custom component is filtering; otherwise the default behavior stands and you must add an explicit visibility guard in your intersection handler.