javascriptthree.js3draycasting

Raycasting HTML elements with ThreeJS


we are facing one problem with ThreeJS. We are trying to include HTML elements within ThreeJS and we are raycasting to get if we are pointing to any HTML element. But when we intersect it, returns an empty array. A simple example is the next one:

https://codepen.io/wazosa/pen/OJrqRRy?editors=1111

 mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;

  raycaster.setFromCamera(mouse, camera);

  var intersects = raycaster.intersectObject(scene, true);
  console.log(intersects)
  if (intersects.length > 0) {
    
        var object = intersects[0].object;


  }

You have a div and a cube, when you click over the cube it returns a console with it, but when you try to click on div element it returns an empty array. Any suggestions?

Thx in advance


Solution

  • Raycaster works against objects that have a raycast method, like Mesh. When you call raycaster.intersectObject( scene, true ), the Raycaster recurses through scene looking for objects with the raycast method. When it finds one, it executes that method to determine if there are any intersections.

    DIVs and other HTML elements are not part of the three.js scene. They are part of the webpage's DOM. Raycaster cannot intersect them because it doesn't even know they're there.

    Option 1

    You could write the text to a texture and create a Sprite to show the label. Sprite supports the raycast method.

    Option 2

    You could add an analog to the scene represent the HTML element. This should probably be a transparent Sprite or some other kind of billboard to ensure the orientation remains correct. The trick will be ensuring the positioning matches the 2D positioning of the HTML element.

    Option 3

    You could add a click handler (or similar event) to an element that contains labels. When you click, the event object should include a target property, which should be the HTML element you clicked on, regardless of the listener's host element. Other event properties include the 2D click position, although you will need to project that into 3D space if you're trying to get a 3D point.