Three.js 转换控件导致延迟

Three.js Transform Controls causes lag

我已经向球体添加了变换控件,因此它可以在我的场景中移动。我还添加了轨道控件来平移我的场景,效果很好。第一次加载场景时没有延迟,效果很好,但是一旦我移动球体,就会有明显的延迟。

我可以解决这个问题,但我真正想解决的是,即使我取消选择球体并且不再移动它,仅使用轨道控件时仍然存在延迟。

var renderer, scene, camera, controls;

init();

var geometry = new THREE.SphereGeometry( .025, 5, 5 );
var material = new THREE.MeshPhongMaterial( {color: 0xffffff} );
var sphere = new THREE.Mesh( geometry, material ); 
addControls(sphere,"translate");
scene.add(sphere);

render();

function addControls(object, type) {

   var transformControl = new THREE.TransformControls( camera,    renderer.domElement );

   transformControl.addEventListener( 'change', render );
   transformControl.addEventListener( 'dragging-changed', function ( event ) {

       controls.enabled = ! event.value;

   } );

   transformControl.attach( object );
   transformControl.setMode( type );
   transformControl.setSpace( "local" );
   scene.add( transformControl );

}

function init() {

   // Renderer
   renderer = new THREE.WebGLRenderer({ antialias: true });
   renderer.setSize(WIDTH, HEIGHT);
   renderer.setPixelRatio(window.devicePixelRatio);
   renderer.setClearColor(0xffffff);
   document.body.appendChild(renderer.domElement);

   // Camera
   camera = new THREE.PerspectiveCamera(100, WIDTH / HEIGHT, 0.1, 1000);
   camera.position.set(500, 0, 0);

   // Orbit Controls
   controls = new THREE.OrbitControls(camera, renderer.domElement);
   controls.maxDistance = 5;

   // Scene
   scene = new THREE.Scene();

}


function render() {

   renderer.render(scene, camera);
   requestAnimationFrame(render);

}

我尝试通过在 addControls() 中放置以下内容来从场景中移除变换控件:

window.addEventListener( 'keypress', function ( event ) {

   transformControl.detach( object );
   transformControl.dispose();
   scene.remove(transformControl);

} );

我将球体移动了一点之后,按下一个键,变换控件就会消失,但延迟仍然存在。 我预计在移动球体时可能会有一些滞后,但当它不移动时这种情况就会消失。

相反,即使我只使用轨道控制,仍然存在延迟。

欢迎来到 Whosebug。

原因是每次您的控件获得 change 事件时,您都在堆叠 requestAnimationFrame 的调用。您调用 render 函数,该函数又会请求在每次帧更新时再次调用它。你可以想象这爆炸的速度有多快。即使在删除变换控件后,这也会导致延迟。

要解决此问题,您应该将渲染函数与动画循环分离。

function animate() {

  requestAnimationFrame( animate );

  render();

}

function render() {

  renderer.render( scene, camera );

}

现在,对变换控件的更改只会渲染场景,不会扰乱动画循环。

JSFiddle Example