我有一些不好的问题,在动态多次重绘场景后帧率大幅下降,我希望有人可以提供帮助。在之前的三个版本中,我注意到内存泄漏,这在实际版本中似乎很好。我不知道为什么如果内存保持正常和cpu也会降低性能。
我的应用程序是由ajax调用触发的,它在不同的div容器中绘制canvasas。通过在新容器中初始化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>
答案 0 :(得分:0)
您的init_webgl
函数调用animate()
,这意味着动画循环不会被清除,每次按下按钮时都会重新初始化动画循环。点击20次后,您将运行20个动画循环。
您只需在程序开始时调用animate()
一次,然后将其从按钮点击代码中删除。