0

在动态地多次重绘场景后,我遇到了一些严重的帧率下降问题,希望有人能提供帮助。在之前的三个版本中,我也注意到内存泄漏,这在实际版本中似乎很好。我不知道如果内存保持正常并且 cpu 也保持正常,为什么性能会下降。

我的应用程序完全由 ajax 调用触发,在不同的 div 容器中绘制画布。通过在新容器中初始化 webgl,旧容器被清理干净。

基本功能类似于以下代码。如果你按下按钮让我们说 20 次,你会看到帧率下降:

http://jsfiddle.net/crizzis/YuJj6/

<input type="button" value="activate rendering in Div1" onclick="init_webgl(1);"></input>
<div id="webgl_container_1" onclick="init_webgl(1);" style="top:0px; height:300px; border:1px solid blue"></div>    
<input type="button" value="activate rendering in Div2" onclick="init_webgl(2);"></input>
<div id="webgl_container_2" onclick="init_webgl(2);"style="top:500px;height:300px; border:1px solid red"></div> 
    <script type="text/javascript"> 
        var camera, fov=70, controls, scene, projector, renderer, container;
        var time=0;
        //init_webgl(1);

        function init_webgl(styleId) {  

            console.log('writing webgl canvas to div with style Id: webgl_container_'+styleId);

            if (scene!=null){
                destroyWebGl();
            }   

            container = document.getElementById('webgl_container_'+styleId);    

            scene = new THREE.Scene();

            camera = new THREE.PerspectiveCamera( fov, container.clientWidth / container.clientHeight, 1, 10000 );
            camera.setViewOffset( container.clientWidth, container.clientHeight, 0, 0, container.clientWidth, container.clientHeight );
            camera.position.z = 350;                
            scene.add(camera);              

            projector = new THREE.Projector();

            renderer = new THREE.WebGLRenderer( { antialias: true } );
            renderer.setSize(container.clientWidth, container.clientHeight);

            light = new THREE.DirectionalLight( 0xffffff );
            light.position.set( 0.31,0.5, 1 );
            scene.add( light )              

            parent = new THREE.Object3D();
            scene.add( parent );                        

            container.appendChild( renderer.domElement );

            console.log('webgl initialized');
            init_renderObjects();
        }            

        function init_renderObjects(){                  
            for (var x = 0; x < 400; x++){
                var cube = new THREE.Mesh( 
                 new THREE.CubeGeometry( 50, 50, 50 ),
                 new THREE.MeshPhongMaterial( { ambient: 0xffffff, color: 0xffffff, opacity: 0.58,specular: 0xffffff, shininess: 40, shading: THREE.SmoothShading,  transparent: true,  wireframe: false } )
                );      
                cube.position.x = 100*x;
                parent.add( cube );
            }                
            animate();
        }

        function animate() {
            requestAnimationFrame(animate);
            timedelta=Date.now()-time;
            time = Date.now();          

            var children = parent.children;
            for(var i = children.length-1;i>=0;i--){
                var child = children[i];
                child.rotation.y = child.rotation.y+timedelta*0.005;
            };              
            render();
        }           

        function render() {             
            if (renderer!=null)renderer.render( scene, camera );                
        }

        function destroyWebGl(){              
             console.log( "destroyWebGl");
             console.log( "before programs"+ renderer.info.memory.programs );
             console.log( "before geometries"+ renderer.info.memory.geometries );
             console.log( "before textures"+ renderer.info.memory.textures );            

            var children = parent.children;
            for(var i = children.length-1;i>=0;i--){
                var child = children[i];
                child.geometry.dispose();
                child.material.dispose();
                parent.remove(child);
            };  

            scene.remove(parent);
            //renderer.deallocateObject( parent );

            camera = null;
            controls= null; 
            scene=null;
            projector=null;  
            parent=null;                    

            container.removeChild( renderer.domElement );       
            container=null;

            console.log( "after programs:" + renderer.info.memory.programs );
            console.log( "after geometries" + renderer.info.memory.geometries );
            console.log( "after textures" + renderer.info.memory.textures );              

            renderer=null;
            console.log('finished destroy');
        }            
        </script> 
4

1 回答 1

0

Your init_webgl function calls animate() which means the animation loop is not cleared and it is reinitialized each time the button is pressed. After 20 clicks you are running 20 animation loops.

You only need to call animate() once at the start of your program and remove it from button click code.

于 2013-04-26T10:31:06.200 回答