【问题标题】:Three.js scene gets hanged and becomes slowThree.js 场景挂起变慢
【发布时间】:2017-07-03 00:12:23
【问题描述】:

threejs 场景由球体和平面几何组成,球体用图像和平面几何进行纹理化 用 2d 文本纹理化,平面几何图形附加点击事件,当我点击平面几何图形时 用鼠标我需要删除以前的球体和平面几何图形并加载具有新纹理的新球体 正在发生的图像和新平面几何,但以前的球体和平面几何仍保留在内存中,我需要 要删除这些对象,我尝试使用“处置”方法,但这对我没有帮助,可能是我犯了一些错误 实现dispose方法,因为这个场景被挂了,有人可以帮我解决一下吗 这个问题。我已经添加了我的部分代码,这可能会给出有关问题的想法。https://jsfiddle.net/v1ayw803/

var spheregeometry = new THREE.SphereGeometry(radius, 20, 20, 0, -6.283, 1, 1);
var texture = THREE.ImageUtils.loadTexture(response.ImagePath);
texture.minFilter = THREE.NearestFilter;
var spherematerial = new THREE.MeshBasicMaterial({map: texture});
var sphere = new THREE.Mesh(spheregeometry, spherematerial);
//texture.needsUpdate = true;

scene.add(sphere);
var objects = [];
var objects_sphere = [];
objects_sphere.push(sphere);

for(var i=0; i<spriteResponse.length; i++)
            {

                var cardinal = {ID: parseInt(spriteResponse[i].ID), lat: parseFloat(spriteResponse[i].lat), lon: parseFloat(spriteResponse[i].lng), name: spriteResponse[i].name};
                //var sprite =  new labelBox(cardinal, radius, root);
                //sprite.update();  was previously commented        
                //spritearray.push(sprite);

                var phi = Math.log( Math.tan( cardinal.lat*(Math.PI/180) / 2 + Math.PI / 4 ) / Math.tan( click_marker.getPosition().lat()* (Math.PI/180) / 2 + Math.PI / 4) );
                var delta_lon = Math.abs( click_marker.getPosition().lng() - cardinal.lon )*Math.PI/180;
                var bearing = Math.atan2( delta_lon ,  phi ) ;
                var Z_value = Math.cos(bearing)*(radius*0.75);
                var X_value = Math.sin(bearing)*(radius*0.75);

                var canvas = document.createElement('canvas');
                context = canvas.getContext('2d');
                metrics = null,
                textHeight = 32,
                textWidth = 0,
            //  actualFontSize = 2;
                context.font = "normal " + textHeight + "px Arial";
                metrics = context.measureText(cardinal.name);
                var textWidth = metrics.width;
                //var textHeight = metrics.height;
                canvas.width = textWidth;
                canvas.height = textHeight;
                context.font = "normal " + textHeight + "px Arial";
                context.textAlign = "center";
                context.textBaseline = "middle";
                context.beginPath();
                context.rect(0, 0, textWidth, textHeight);
                context.fillStyle = "white";
                context.fill();

                context.fillStyle = "black";
                context.fillText(cardinal.name, textWidth / 2, textHeight / 2);


                texture_plane = new THREE.Texture(canvas);
                var GPU_Value = renderer.getMaxAnisotropy();
                texture_plane.anisotropy = GPU_Value;
                texture_plane.needsUpdate = true;



                //var spriteAlignment = new THREE.Vector2(0,0) ;
                material = new THREE.MeshBasicMaterial( {color: 0xffffff,side: THREE.DoubleSide ,map : texture_plane} );
                material.needsUpdate = true;
                //material.transparent=true;
                geometry = new THREE.PlaneGeometry(0.3, 0.2);
                plane = new THREE.Mesh( geometry, material );
                plane.database_id = cardinal.ID;
                plane.LabelText   = cardinal.name;


                //plane.scale.set( 0.3, 0.3,1 );
                plane.scale.set( textWidth/165, textHeight/70, 1 );
                plane.position.set(X_value,0,Z_value);
                plane.coordinates = { X: X_value, Z: Z_value};
                plane.lat_lon = { LAT: cardinal.lat, LON: cardinal.lon};
                plane.textWidth = textWidth;
                plane.textHeight = textHeight;
                objects.push( plane );
                scene.add(plane);
                plane.userData = { keepMe: true };
                //objects.push( plane );
                //plane.id = cardinal.ID;
                //var direction = camera.getWorldDirection();
                camera.updateMatrixWorld();
                var vector = camera.position.clone();
                vector.applyMatrix3( camera.matrixWorld );
                plane.lookAt(vector);



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


            }
function onDocumentMouseDown( event ) 
            {

                //clearScene();
                event.preventDefault();

                var mouse = new THREE.Vector2();
                mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
                mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
                var raycaster = new THREE.Raycaster();
                raycaster.setFromCamera( mouse, camera );               
                var intersects = raycaster.intersectObjects( objects );                 

                var matched_marker = null;
                if(intersects.length != 0)
                {   
                    for ( var i = 0;  intersects.length > 0 && i < intersects.length; i++)
                    {
                        var x_id = intersects[0].object.database_id;                        
                            for( var j = 0; markers.length > 0 && j < markers.length; j++)
                        {
                            if(x_id == markers[j].ID)
                            {
                                matched_marker = markers[j];
                                break;
                            }                               
                        }
                        if(matched_marker != null)
                        {
                            break;
                        }       
                    }

                     // loadScene();
                    clean_data();
                    google.maps.event.trigger( matched_marker, 'click' );


                }

        }
   function clean_data()
        {
            for(var k=0;k<objects_sphere.length;k++)
            {
                scene.remove( objects_sphere[k] );
                objects_sphere[k].geometry.dispose();
                objects_sphere[k].material.map.dispose();
                objects_sphere[k].material.dispose();



            }

            for (var j=0; j<objects.length; j++)
            {
                scene.remove( objects[j] );
                objects[j].geometry.dispose();
                objects[j].material.map.dispose();
                objects[j].material.dispose();

            //  objects[j].material.needsUpdate = true;




            }

            /*spheregeometry.dispose();
            spherematerial.dispose();
            texture.dispose();
            scene.remove( sphere );*/
        } `

【问题讨论】:

  • 你的 js fiddle 不工作
  • 我没有看到 renderer.render() 调用,您确定在移除对象后重新渲染场景吗?
  • @Brandon.Blanchard 我添加了 animationLoop 函数并在 clean_data 函数中调用了该函数,但没有任何改变。
  • @lakers1234 也许我错过了,但我没看到你在哪里调用 clean_data();
  • @pprchsvr 我已经调用了 clean_data(); @函数onDocumentMouseDown(事件).

标签: javascript three.js


【解决方案1】:

看起来您从未在示例代码或 jsFiddle 中重新渲染场景。如果您从场景中移除对象并且对象仍然存在,则很可能您没有再次渲染场景。尝试添加渲染循环。

animationLoop () {
    myrenderer.render(myScene, myCamera)
    window.requestAnimationFrame(animationLoop)
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-20
    • 1970-01-01
    • 2015-08-02
    • 2013-01-28
    • 1970-01-01
    相关资源
    最近更新 更多