How to Set-up Raycasting in React-three-fiber
Asked Answered
B

3

6

I am trying to set up a scene in react-three-fiber that uses a raycaster to detect if an object intersects it.

My Scene: scene

I have been looking at examples like this example and this other example, of raycasters that use simple three objects but don't utilize separated component jsx ".gltf" meshes or their not in jsx. So I'm not sure how to add my group of meshes to a "raycaster.intersectObject();".

It seems that all you do is set up your camera, scene, and raytracer separately in different variables, but my camera and scene are apart of the Canvas Component.

Question: How do I add raycasting support to my scene? This would obscure the text that is on the opposite side of the sphere.

Thanks!

Berndt answered 28/11, 2020 at 23:1 Comment(3)
raycasting for pointer events is obviously inbuilt, i guess you want to use raycaster as is? in that case what stops you? it works in the exact same way as in plain threejs. you still have a scene, you can access each element in it via refs. jsx const ref = useRef() useEffect(() => { yourRaycaster.intersectObject(ref.current) ... }, []) return <group ref={ref}> ... Flirt
Thanks for responding, I tried this just now by putting the group ref in the intersectObjects() function and its console.logged nothing in the array. Is it possible to raycast group meshes? How do I know where the raycaster is coming from? Where do I call this useEffect? Where do I put the new THREE.Raycaster()? Does this get automatically called when the model is rotated, or when the camera is repositioned?Berndt
By the tutorial, it seems that you need to find the position of each object in the scene. In three.js you use .getWorldPosition(), but in react you use the refs position. Then you need to find the normalized position of that vector on the XY axis of the user's screen using projection. Then cast an individual ray out for each object's normalized screen position. If it intersects, then it's visible, if not, it's invisible. Now I just have to figure out how to turn that into jsx from minimal documentation.Berndt
G
1

This is the approach I used. Note that I used useState instead of useRef", since I had problems with the latter

const Template = function basicRayCaster(...args) {
  const [ray, setRay] = useState(null);
  const [box, setBox] = useState(null);
  useEffect(() => {
    if (!ray || !box) return;
    console.log(ray.ray.direction);
    const intersect = ray.intersectObject(box);
    console.log(intersect);
  }, [box, ray]);
  return (
    <>
      <Box ref={setBox}></Box>
      <raycaster
        ref={setRay}
        ray={[new Vector3(-3, 0, 0), new Vector3(1, 0, 0)]}
      ></raycaster>
    </>
  );
};
Gadwall answered 1/12, 2022 at 7:15 Comment(2)
Please add code and data as text (using code formatting), not images. Images: A) don't allow us to copy-&-paste the code/errors/data for testing; B) don't permit searching based on the code/error/data contents; and many more reasons. Images should only be used, in addition to text in code format, if having the image adds something significant that is not conveyed by just the text code/error/data.Ayana
I see you're creating new vectors inline. Won't these be recreated every time the component rerenders?Reduplicative
C
0

Try CycleRayCast from Drei lib. It is react-three-fiber-friendly

"This component allows you to cycle through all objects underneath the cursor with optional visual feedback. This can be useful for non-trivial selection, CAD data, housing, everything that has layers. It does this by changing the raycasters filter function and then refreshing the raycaster."

Cassimere answered 26/7, 2022 at 2:5 Comment(0)
J
0

You can retrieve the raycaster from useThree.

Example to modify the raycaster threshold for points onMount:

  const { raycaster } = useThree();
  useEffect(() => {
    if (raycaster.params.Points) {
      raycaster.params.Points.threshold = 0.1;
    }
  }, []);

Once done you are enable to modify its properties or to use it

Jackelynjackeroo answered 18/1, 2023 at 15:29 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.