1

I have sprites with text on screen, placed in spherical pattern and I want to allow user to click on individual words and highlight them.

Now the problem is that when I do raycasting and do raycaster.intersectObjects() it returns sprites that are somewhere completely different where the click happened (usually it highlights words that are to the left of the words clicked). For debugging purposes I actually drew the rays from the raycaster object, and they are pretty much going trough the words I clicked.

enter image description here

In this picture I clicked the words "emma", "universe" and "inspector legrasse", but the words that got highlighted are in the red, I also rotated the camera so we can see the lines.

here is the relevant code:

Sprite creation:

var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.height = 256;
canvas.width = 1024;
...
context.fillStyle = "rgba(0, 0, 0, 1.0)";
context.fillText(message, borderThickness, fontsize + borderThickness);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
var spriteMaterial = new THREE.SpriteMaterial({map: texture});
var sprite = new THREE.Sprite(spriteMaterial);
sprite.scale.set(400, 100, 1.0);

Individual sprites are then added to "sprites" array, and then added to the scene.

Click detection:

function clickOnSprite(event) {
    mouse.x = ( event.clientX / renderer.domElement.clientWidth ) * 2 - 1;
    mouse.y = -( event.clientY / renderer.domElement.clientHeight ) * 2 + 1;
    raycaster.setFromCamera(mouse, camera);

    drawRaycastLine(raycaster);

    var intersects = raycaster.intersectObjects(sprites);
    if (intersects.length > 0) {
        intersects[0].object.material.color.set(0xff0000);
        console.log(intersects[0]);
    }
}

I am using perspective camera with orbit controls.

prisoner849
  • 16,894
  • 4
  • 34
  • 68
  • Could you provide a live code example (code snippet here or jsfiddle or codepen)? – prisoner849 May 02 '18 at 13:50
  • 2
    Related: https://github.com/mrdoob/three.js/issues/13751 – Mugen87 May 02 '18 at 13:56
  • @prisoner849 that would be quite difficult ... the project contains many javascript files and libraries that aren't on CDNs – Igor Vereš May 02 '18 at 14:08
  • @Mugen87 Oh ... I was afraid of something like that. :/ I think I should ditch the sprites and try to come up with some sort of a hack ... I tried making 3D text but that's very resource intensive and can only handle like 10 words, whereas the sprites can easily do couple thousand. – Igor Vereš May 02 '18 at 14:10
  • Try to use plane meshes instead. Indeed, 3D text is the wrong choice for your use case. – Mugen87 May 02 '18 at 14:15
  • Maybe you could use square sprites of the same dimensions, with the text centered within it? That way the raycaster calculation won't run into issues. It'll change the design, however, and look something like this: https://i.imgur.com/y2LBLB9.jpg – M - May 02 '18 at 17:34
  • 1
    A long time ago when i tried to raycast against sprites, i couldn't make it work. My solution was to scatter planes and raycast those. Since it had to happen only on a click, i used the click to align the quads to the camera, before firing the ray. Rendering can be done with instancing, completely separate from the scenegraph and raycasting. – pailhead May 02 '18 at 18:11

1 Answers1

1

I came to the conclusion, that this cannot be currently done with sprites (at least not currently).

As suggested in the comments, I ended up using plane geometries instead of sprites.