I am currently working on a project that involves a scene with an Object3D
representing a globe and multiple mesh elements that represent points on the globe. To enable user interaction, I am using OrbitControls
. In addition to this, I am attaching HTMLElements
to these points on the globe. However, since a globe is essentially a sphere, there might be instances where the points are not visible to the camera due to being placed on the backside of the object.
I am looking for a way to determine whether a point is visible to the camera or hidden by the object. If a point is not visible, I want to hide the corresponding HTMLElement
based on the visibility of the mesh. The position of the HTMLElement
is updated during render, so I believe this check should also take place during rendering:
private render() {
this.renderer.render(this.scene, this.camera);
this.points.forEach(({ label, mesh }) => {
const screen = this.toScreenPosition(mesh);
label.style.transform = `translate3d(${screen.x - 15}px, ${screen.y}px, 0)`;
});
this.requestId = window.requestAnimationFrame(this.render.bind(this));
}
The following code snippet works within the render function:
this.points.forEach(({ label, mesh }) => {
const screen = this.toScreenPosition(mesh);
label.style.transform = `translate3d(${screen.x - 15}px, ${screen.y}px, 0)`;
const direction = new Vector3();
direction.copy(mesh.position).sub(this.camera.position).normalize();
this.raycaster.set(this.camera.position, direction);
const intersections = this.raycaster.intersectObject(this.scene, true);
const intersected = intersections.length > 0 ? intersections[0].object.uuid === mesh.uuid : false;
if (intersected && label.style.opacity === "0") {
label.style.opacity = "1";
} else if (!intersected && label.style.opacity === "1") {
label.style.opacity = "0";
}
});