gpt4 book ai didi

javascript - Three.js 未捕获 RangeError : Maximum call stack size exceeded in render loop

转载 作者:行者123 更新时间:2023-11-28 15:02:22 24 4
gpt4 key购买 nike

好吧..对 JS 和 Three.js 来说很陌生,我很好奇为什么我在函数自调用中遇到了堆栈溢出,而 Three.js 自然会根据设计调用。然而,只有当我从主函数中删除调用时才会发生这种情况。

我基本上采用了 three.js-Documentation 中的立方体示例我正在尝试设置动画,以便我可以动态地添加和减去场景中的对象,并将其发送到特定的 Canvas 。

来自 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);
});
};

一旦我将渲染循环移到初始父调用之外,我就会收到“stackoverflow”错误......

未捕获的范围错误:超出最大调用堆栈大小

所以我的问题是,当渲染在 requestAnimationFrame 中调用自身时,这是怎么回事,但是当同样的事情发生在父调用之外时,堆栈不会被清除并且失败?

我错过了什么?

最佳答案

问题出在这一行:

requestAnimationFrame( this.renderloop() );

在这里,您实际上是立即调用 renderloop(),而不是将该函数作为回调传递给 requestAnimationFrame,从而导致无限递归循环。

当然,人们可能会尝试将其更改为以下内容,但这也行不通,因为传递的函数原型(prototype)未绑定(bind)到任何对象:

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

这里的一个解决方案是将函数绑定(bind)到对象的范围:

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

我建议将 renderloop 函数作为私有(private)方法移至 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 公开为公共(public)函数,您可以——但我怀疑没有任何理由这样做。

关于javascript - Three.js 未捕获 RangeError : Maximum call stack size exceeded in render loop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40468398/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com