three.js未捕获的RangeError:渲染循环中超出的最大调用堆栈大小

问题描述:

好吧..对于JS和three.js来说这么新,我很好奇为什么我在函数自我调用中获得堆栈超出, three.js自然地调用每个设计。然而,只有当我从主功能中删除呼叫时才会发生。three.js未捕获的RangeError:渲染循环中超出的最大调用堆栈大小

我已经基本上采用了 three.js-Documentation的立方体示例,我试图设置动画,以便动态添加和减去场景中的对象以及将其发送到特定的画布。从three.js所

 var scene = new THREE.Scene(); 
     var camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); 

     var renderer = new THREE.WebGLRenderer(); 
     renderer.setSize(window.innerWidth, window.innerHeight); 
     document.body.appendChild(renderer.domElement); 

     var geometry = new THREE.BoxGeometry(1, 1, 1); 
     var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); 
     var cube = new THREE.Mesh(geometry, material); 
     scene.add(cube); 

     camera.position.z = 5; 

     var render = function() { 
      requestAnimationFrame(render); 

      cube.rotation.x += 0.1; 
      cube.rotation.y += 0.1; 

      renderer.render(scene, camera); 
     }; 

     render(); 

上的动画调用render();聚焦

原始代码被称为reqestAnimationFrame()功能的自我。为了打破以备将来使用的程序结构,我将它设置了像这样(在后视线不是最好的选择):

function e3Dview(){ 
    // Set the e Canvas 
    this.canvas = document.getElementById("eplot3D") 

    scene = new THREE.Scene(); 
    camera = new THREE.PerspectiveCamera(75, this.canvas.width/this.canvas.height, 0.1, 1000); 

    renderer = new THREE.WebGLRenderer({ canvas: eplot3D }); 
    renderer.setSize(this.canvas.width, this.canvas.height); 

    var geo = new THREE.BoxGeometry(1, 1, 1); 
    var mat = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); 
    mat.wireframe = true 
    this.cube = new THREE.Mesh(geo, mat); 
    scene.add(this.cube); 

    camera.position.z = 5; 

    controls = new THREE.OrbitControls(camera, renderer.domElement); 

    // Execute render 
    this.renderloop(); 

}; 

e3Dview.prototype.renderloop = function(){ 
    requestAnimationFrame(this.renderloop()); 

    this.cube.rotation.x += 0.01; 
    this.cube.rotation.y += 0.01; 

    renderer.render(scene, camera); 

}; 

e3Dview.prototype.sceneClear = function(){ 
    scene.children.forEach(function(object){ 
     scene.remove(object); 
    }); 
}; 

一旦我移动渲染循环的inital父外呼,我得到一个“计算器”错误....

未捕获的RangeError:最大调用堆栈大小超过

所以我的问题是怎么回事,当在requestAnimationFrame没关系,但是当同样的事情发生外渲染调用本身父母叫s大头钉未被清除并且失败?

我错过了什么?

的问题是这一行:

requestAnimationFrame(this.renderloop()); 

这里您可以有效调用renderloop()立即,而不是传递函数为回调requestAnimationFrame,从而导致无限递归循环。

当然人们可能会尝试将其更改为以下,但这样做也不行,因为传递函数原型未绑定任何对象:

requestAnimationFrame(this.renderloop); // This won't work, either. 

这里的一个解决方案是结合所述函数应用于所述对象的范围:

requestAnimationFrame(this.renderloop.bind(this)); // This will work, but overhead at 60FPS might not be worth it 

我建议移动renderloop功能到e3Dview构造为私有方法,像这样:

function e3Dview(){ 
    var $this = this; // Hold the current object's scope, for accessing properties from within the callback method. 

    ... 

    function renderloop() { 
     requestAnimationFrame(renderloop); 

     $this.cube.rotation.x += 0.01; 
     $this.cube.rotation.y += 0.01; 

     renderer.render(scene, camera); 
    } 

    renderloop(); 
} 

这不是很漂亮,但通常是这样做的。如果你真的需要将renderloop作为公共函数公开,那么你可以 - 但我怀疑没有理由这么做。

+0

谢谢你队友,这关闭了我的JS知识中的一些空白。真的很有帮助。 – CromeX