Как добавить тег / метку, чтобы она отображалась поверх нескольких объектов, чтобы тег всегда был направлен на камеру, когда пользователь щелкает объект?

По сути, я хочу создать тег или метку, которая появляется поверх / на поверхности объекта, чтобы тег всегда был обращен к камере, когда пользователь щелкает объект, даже когда объект вращается.

Как мне это сделать?

Мне сказали использовать Ортогональную камеру (но я не уверен, как?) И CSS для метки (см. Предыдущий пост:Как я могу сделать так, чтобы текстовые метки всегда были направлены к камере? Возможно, используя спрайты?)

Метка в CSS и HTML ниже. Однако я хочу сделать это и для нескольких объектов, так что, думаю, я могу составить список всех тегов, которые я хочу для каждого куба в этом случае.

CSS:

label {
    vertical-align: middle;
    display: table-cell;
    background-color : #99FFCC;
border: 1px solid #008000;
width: 150px;
}

HTML:

<div id="Cube1">
    <label>Cube 1</label>
</div>

Предыдущий код:

<!DOCTYPE html>
<html lang="en">
<head>
        <title>three.js canvas - interactive - cubes</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
                body {
                        font-family: Monospace;
                        background-color: #f0f0f0;
                        margin: 0px;
                        overflow: hidden;
                }
        </style>
</head>
<body>

        <script src="js/three.min.js"></script>

        <script src="js/stats.min.js"></script>

        <script>

                var container, stats;
                var camera, scene, projector, renderer;
                var projector, mouse = { x: 0, y: 0 }, INTERSECTED;
                var particleMaterial;
                var currentLabel = null;

                var objects = [];

                init();
                animate();

                function init() {

                        container = document.createElement( 'div' );
                        document.body.appendChild( container );

                        var info = document.createElement( 'div' );
                        info.style.position = 'absolute';
                        info.style.top = '10px';
                        info.style.width = '100%';
                        info.style.textAlign = 'center';
                        info.innerHTML = '<a href="http://threejs.org" target="_blank">three.js</a> - clickable objects';
                        container.appendChild( info );

                        camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
                        camera.position.set( 0, 300, 500 );

                        scene = new THREE.Scene();

                        var geometry = new THREE.CubeGeometry( 100, 100, 100 );

                        for ( var i = 0; i < 10; i ++ ) {

                                var object = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 } ) );
                                object.position.x = Math.random() * 800 - 400;
                                object.position.y = Math.random() * 800 - 400;
                                object.position.z = Math.random() * 800 - 400;

                                object.scale.x = Math.random() * 2 + 1;
                                object.scale.y = Math.random() * 2 + 1;
                                object.scale.z = Math.random() * 2 + 1;

                                object.rotation.x = Math.random() * 2 * Math.PI;
                                object.rotation.y = Math.random() * 2 * Math.PI;
                                object.rotation.z = Math.random() * 2 * Math.PI;

                                object.label = "Object " + i;

                                scene.add( object );

                                objects.push( object );

                        }

                        var PI2 = Math.PI * 2;
                        particleMaterial = new THREE.ParticleCanvasMaterial( {

                                color: 0x000000,
                                program: function ( context ) {

                                        context.beginPath();
                                        context.arc( 0, 0, 1, 0, PI2, true );
                                        context.closePath();
                                        context.fill();

                                }

                        } );

                        projector = new THREE.Projector();

                        renderer = new THREE.CanvasRenderer();
                        renderer.setSize( window.innerWidth, window.innerHeight );

                        container.appendChild( renderer.domElement );

                        stats = new Stats();
                        stats.domElement.style.position = 'absolute';
                        stats.domElement.style.top = '0px';
                        container.appendChild( stats.domElement );

                        document.addEventListener( 'mousedown', onDocumentMouseDown, false );

                        //

                        window.addEventListener( 'resize', onWindowResize, false );

                }

                function onWindowResize() {

                        camera.aspect = window.innerWidth / window.innerHeight;
                        camera.updateProjectionMatrix();

                        renderer.setSize( window.innerWidth, window.innerHeight );

                }

                function onDocumentMouseDown( event ) {

                        event.preventDefault();

                        var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
                        projector.unprojectVector( vector, camera );

                        var raycaster = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );

                        var intersects = raycaster.intersectObjects( objects );

                        if ( intersects.length > 0 ) {

                        if ( intersects[ 0 ].object != INTERSECTED ) 
                                        {

                                         // restore previous intersection object (if it exists) to its original color
                                        if ( INTERSECTED ) {


                                        INTERSECTED.material.color.setHex( INTERSECTED.currentHex ); } 

                                        // store reference to closest object as current intersection object
                                        INTERSECTED = intersects[ 0 ].object;
                                        // store color of closest object (for later restoration)
                                        INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
                                        // set a new color for closest object
                                        INTERSECTED.material.color.setHex( 0xffff00 );

                                        var canvas1 = document.createElement('canvas');
                                        var context1 = canvas1.getContext('2d');
                                        context1.font = "Bold 40px Arial";
                                        context1.fillStyle = "rgba(255,0,0,0.95)";
                                        context1.fillText(INTERSECTED.label, 0, 50);

                                        // canvas contents will be used for a texture
                                        var texture1 = new THREE.Texture(canvas1) 
                                        texture1.needsUpdate = true;

                                        var material1 = new THREE.MeshBasicMaterial( {map: texture1, side:THREE.DoubleSide } );
                                        material1.transparent = true;

                                        var mesh1 = new THREE.Mesh(
                                        new THREE.PlaneGeometry(canvas1.width, canvas1.height),
                                        material1



                                );
                                        mesh1.position = intersects[0].point;
                                        if (currentLabel)
                                                scene.remove(currentLabel);
                                        scene.add( mesh1 );                             
                                        currentLabel = mesh1;
                        } 

                        else // there are no intersections
                                        {
                                // restore previous intersection object (if it exists) to its original color
                                if ( INTERSECTED ) {
                                        console.log("hello");
                                        INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
                                        }
                                        // remove previous intersection object reference
                                        //     by setting current intersection object to "nothing"
                                        INTERSECTED = null;
                                        mesh1 = null; 
                                        mesh1.position = intersects[0].point; 
                                        scene.add( mesh1 );

                                        }






                                //var particle = new THREE.Particle( particleMaterial );
                                //particle.position = intersects[ 0 ].point;
                                //particle.scale.x = particle.scale.y = 8;
                                //scene.add( particle );

                        }

                        /*
                        // Parse all the faces
                        for ( var i in intersects ) {

                                intersects[ i ].face.material[ 0 ].color.setHex( Math.random() * 0xffffff | 0x80000000 );

                        }
                        */


                }

                //

        ,        function animate() {

                        requestAnimationFrame( animate );

                        render();
                        stats.update();

                }

                var radius = 600;
                var theta = 0;

                function render() {

                        theta += 0.1;

                        camera.position.x = radius * Math.sin( THREE.Math.degToRad( theta ) );
                        camera.position.y = radius * Math.sin( THREE.Math.degToRad( theta ) );
                        camera.position.z = radius * Math.cos( THREE.Math.degToRad( theta ) );
                        camera.lookAt( scene.position );

                        renderer.render( scene, camera );

                }

        </script>

</body>

Пожалуйста, дайте мне знать, если я неясен.

Ответы на вопрос(1)

Ваш ответ на вопрос