aframe: Raycaster does not ignore `material="visible: false;"` when `raycaster="objects: ... ;"` is defined
Description:
According to the A-Frame docs (https://aframe.io/docs/0.8.0/components/material.html#properties_visible), raycasters should ignore entities that have material="visible: false;"
. This doesn’t seem to be the case when raycaster="objects: ... ;"
is defined. In this case, all qualifying objects are raycasted regardless of visibility.
Should material.visible
not still affect raycasting on these entities?
- A-Frame Version:
0.7.*
-0.8.*
- Reproducible Code Snippet or URL: https://codepen.io/dansinni/pen/deYXZa
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 16 (13 by maintainers)
I hit this issue recently and found the following three.js change log item from r72: https://github.com/mrdoob/three.js/issues/6758
This behavior matches what @dsinni describes and seems like a conscious design decision on three.js’s part that’s been around for a couple years.
The “Raycasters will ignore invisible materials.” line in the documentation has been there since 0.3.0, which used r76.1. But I was able to reproduce the raycaster intersecting an object with
material="visible: false;"
in 0.3.0 (gaze to the right of the yellow box):Not anymore without hacking the component, it’s best practice and prescribed to control what is being raycasted. What I propose wasn’t showing off (I’m not a wizard), it is simple. Rather than depending on what is somewhat an arbitrary condition (visibility) and doing
object3D.visible = false
, do either like<a-entity data-no-raycast>
or<a-entity data-raycastable>
withobjects: [data-raycastable]
orobjects: :not([data-no-raycast]
.If you are depending solely on visibility, it sounds like the app has no system in place to toggle what is being raycasted, and your app is raycasting every single object, which is a killer for performance.
I often have hidden raycaster targets to pad the click range (e.g., small targets). Often, you still want to trigger with invisible objects. I even have a
raycaster-target
helper component that drops a hidden raycaster target by width/height.Regardless, you want to use query selectors, else everything will be raycastable. Some things I do is I create a
raycastable
component that can be mixed in. Ordata-raycastable
with a helper component that toggles them on / off based on like what menu you’re on. Or with the state component,bind-toggle__raycastable
. I always limit exactly to what should be raycastable because it’s expensive.Explicit > implicit in this case, especially as it involves performance and visibility of objects is not always a determining factor.
But yeah, docs should be updated with best practices. Been building complex menus and have mastered the art of the raycaster.